From 31e94f77a975e47d63bd23f2189df24600ea908d Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Fri, 3 Apr 2020 15:57:52 -0500
Subject: [PATCH 1/9] Started adding LpGBT, not compiling

---
 DQMUtils/CBCHistogramPulseShape.cc         |  49 ++--
 DQMUtils/DQMHistogramCalibrationExample.cc |  76 +++---
 HWDescription/FrontEndDescription.cc       |  30 +--
 HWInterface/CbcInterface.cc                |   5 -
 HWInterface/CicInterface.cc                |   1 -
 HWInterface/D19cFWInterface.cc             |  17 +-
 HWInterface/GbtInterface.cc                |  25 +-
 HWInterface/RD53FWInterface.cc             |   5 +-
 RootUtils/RootContainerFactory.h           | 271 ++++++++++++---------
 System/FileParser.cc                       | 162 ++----------
 System/FileParser.h                        |  16 +-
 Utils/Container.h                          |  14 +-
 Utils/ContainerFactory.cc                  |  13 +-
 Utils/ContainerFactory.h                   | 111 +++++----
 Utils/ContainerStream.h                    |  81 +++---
 Utils/D19cCbc3Event.cc                     |  23 +-
 Utils/D19cCbc3EventZS.cc                   |  15 +-
 Utils/D19cCic2Event.cc                     |  29 +--
 Utils/D19cCicEvent.cc                      |  25 +-
 Utils/D19cSSAEvent.cc                      |  15 +-
 Utils/DataContainer.h                      |  23 +-
 Utils/Visitor.h                            |   6 +
 settings/D19CDescription.xml               |  59 ++---
 23 files changed, 536 insertions(+), 535 deletions(-)

diff --git a/DQMUtils/CBCHistogramPulseShape.cc b/DQMUtils/CBCHistogramPulseShape.cc
index 19c271b62..32b980bbd 100644
--- a/DQMUtils/CBCHistogramPulseShape.cc
+++ b/DQMUtils/CBCHistogramPulseShape.cc
@@ -73,32 +73,35 @@ void CBCHistogramPulseShape::fillCBCPulseShapePlots(uint16_t delay, DetectorData
     for(auto board : theThresholdAndNoiseContainer) //for on boards - begin 
     {
         size_t boardIndex = board->getIndex();
-        for(auto module: *board) //for on module - begin 
+        for(auto opticalGroup: *board) //for on opticalGroup - begin 
         {
-            size_t moduleIndex = module->getIndex();
-
-            for(auto chip: *module) //for on chip - begin 
+            size_t opticalGroupIndex = opticalGroup->getIndex();
+            for(auto hybrid: *opticalGroup) //for on hybrid - begin 
             {
-                size_t chipIndex = chip->getIndex();
-                // Retreive the corresponging chip histogram:
-                if(chip->getSummaryContainer<ThresholdAndNoise,ThresholdAndNoise>() == nullptr ) continue;
-                TH1F *chipPulseShapeHistogram = fDetectorChipPulseShapeHistograms.at(boardIndex)->at(moduleIndex)->at(chipIndex)->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                int currentBin = chipPulseShapeHistogram->FindBin(binCenterValue);
-                chipPulseShapeHistogram->SetBinContent(currentBin, chip->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold     );
-                chipPulseShapeHistogram->SetBinError  (currentBin, chip->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThresholdError);
-                // Check if the chip data are there (it is needed in the case of the SoC when data may be sent chip by chip and not in one shot)
-                // Get channel data and fill the histogram
-                uint8_t channelNumber = 0;
-                for(auto channel : *chip->getChannelContainer<ThresholdAndNoise>()) //for on channel - begin 
+                size_t hybridIndex = hybrid->getIndex();
+                for(auto chip: *hybrid) //for on chip - begin 
                 {
-                    TH1F *channelPulseShapeHistogram = fDetectorChannelPulseShapeHistograms.at(boardIndex)->at(moduleIndex)->at(chipIndex)->getChannel<HistContainer<TH1F>>(channelNumber).fTheHistogram;
-                    int currentBin = channelPulseShapeHistogram->FindBin(binCenterValue);
-                    channelPulseShapeHistogram->SetBinContent(currentBin, channel.fThreshold);
-                    channelPulseShapeHistogram->SetBinError  (currentBin, channel.fNoise    );
-                    ++channelNumber;
-                } //for on channel - end 
-            } //for on chip - end 
-        } //for on module - end 
+                    size_t chipIndex = chip->getIndex();
+                    // Retreive the corresponging chip histogram:
+                    if(chip->getSummaryContainer<ThresholdAndNoise,ThresholdAndNoise>() == nullptr ) continue;
+                    TH1F *chipPulseShapeHistogram = fDetectorChipPulseShapeHistograms.at(boardIndex)->at(opticalGroupIndex)->at(moduleIndex)->at(chipIndex)->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    int currentBin = chipPulseShapeHistogram->FindBin(binCenterValue);
+                    chipPulseShapeHistogram->SetBinContent(currentBin, chip->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold     );
+                    chipPulseShapeHistogram->SetBinError  (currentBin, chip->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThresholdError);
+                    // Check if the chip data are there (it is needed in the case of the SoC when data may be sent chip by chip and not in one shot)
+                    // Get channel data and fill the histogram
+                    uint8_t channelNumber = 0;
+                    for(auto channel : *chip->getChannelContainer<ThresholdAndNoise>()) //for on channel - begin 
+                    {
+                        TH1F *channelPulseShapeHistogram = fDetectorChannelPulseShapeHistograms.at(boardIndex)->at(opticalGroupIndex)->at(moduleIndex)->at(chipIndex)->getChannel<HistContainer<TH1F>>(channelNumber).fTheHistogram;
+                        int currentBin = channelPulseShapeHistogram->FindBin(binCenterValue);
+                        channelPulseShapeHistogram->SetBinContent(currentBin, channel.fThreshold);
+                        channelPulseShapeHistogram->SetBinError  (currentBin, channel.fNoise    );
+                        ++channelNumber;
+                    } //for on channel - end 
+                } //for on chip - end 
+            } //for on module - end 
+        } //for on opticalGroup - end
     } //for on boards - end 
 }
 
diff --git a/DQMUtils/DQMHistogramCalibrationExample.cc b/DQMUtils/DQMHistogramCalibrationExample.cc
index 8d9d64d48..7df97ec2a 100644
--- a/DQMUtils/DQMHistogramCalibrationExample.cc
+++ b/DQMUtils/DQMHistogramCalibrationExample.cc
@@ -51,25 +51,29 @@ void DQMHistogramCalibrationExample::fillCalibrationExamplePlots(DetectorDataCon
     for(auto board : theHitContainer) //for on boards - begin 
     {
         size_t boardIndex = board->getIndex();
-        for(auto module: *board) //for on module - begin 
+        for(auto opticalGroup: *board) //for on opticalGroup - begin 
         {
-            size_t moduleIndex = module->getIndex();
-            for(auto chip: *module) //for on chip - begin 
+            size_t opticalGroupIndex = opticalGroup->getIndex();
+            for(auto hybrid: *opticalGroup) //for on hybrid - begin 
             {
-                size_t chipIndex = chip->getIndex();
-                // Retreive the corresponging chip histogram:
-                TH1F *chipHitHistogram = fDetectorHitHistograms.at(boardIndex)->at(moduleIndex)->at(chipIndex)
-                    ->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                uint channelBin=1;
-                // Check if the chip data are there (it is needed in the case of the SoC when data may be sent chip by chip and not in one shot)
-                if(chip->getChannelContainer<uint32_t>() == nullptr ) continue;
-                // Get channel data and fill the histogram
-                for(auto channel : *chip->getChannelContainer<uint32_t>()) //for on channel - begin 
+                size_t hybridIndex = hybrid->getIndex();
+                for(auto chip: *hybrid) //for on chip - begin 
                 {
-                    chipHitHistogram->SetBinContent(channelBin++,channel);
-                } //for on channel - end 
-            } //for on chip - end 
-        } //for on module - end 
+                    size_t chipIndex = chip->getIndex();
+                    // Retreive the corresponging chip histogram:
+                    TH1F *chipHitHistogram = fDetectorHitHistograms.at(boardIndex)->at(opticalGroupIndex)->at(hybridIndex)->at(chipIndex)
+                        ->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    uint channelBin=1;
+                    // Check if the chip data are there (it is needed in the case of the SoC when data may be sent chip by chip and not in one shot)
+                    if(chip->getChannelContainer<uint32_t>() == nullptr ) continue;
+                    // Get channel data and fill the histogram
+                    for(auto channel : *chip->getChannelContainer<uint32_t>()) //for on channel - begin 
+                    {
+                        chipHitHistogram->SetBinContent(channelBin++,channel);
+                    } //for on channel - end 
+                } //for on chip - end 
+            } //for on hybrid - end 
+        } //for on opticalGroup - end 
     } //for on boards - end 
 }
 
@@ -81,28 +85,32 @@ void DQMHistogramCalibrationExample::process()
     for(auto board : fDetectorHitHistograms) //for on boards - begin 
     {
         size_t boardIndex = board->getIndex();
-        for(auto module: *board) //for on module - begin 
+        for(auto opticalGroup: *board) //for on opticalGroup - begin 
         {
-            size_t moduleIndex = module->getIndex();
+            size_t opticalGroupIndex = opticalGroup->getIndex();
+            for(auto hybrid: *opticalGroup) //for on hybrid - begin 
+            {
+                size_t hybridIndex = hybrid->getIndex();
 
-            //Create a canvas do draw the plots
-            TCanvas *cValidation = new TCanvas(("Hits_module_" + std::to_string(module->getId())).data(),("Hits module " + std::to_string(module->getId())).data(),   0, 0, 650, 650 );
-            cValidation->Divide(module->size());
+                //Create a canvas do draw the plots
+                TCanvas *cValidation = new TCanvas(("Hits_hybrid_" + std::to_string(hybrid->getId())).data(),("Hits hybrid " + std::to_string(hybrid->getId())).data(),   0, 0, 650, 650 );
+                cValidation->Divide(hybrid->size());
 
-            for(auto chip: *module)  //for on chip - begin 
-            {
-                size_t chipIndex = chip->getIndex();
-                cValidation->cd(chipIndex+1);
-                // Retreive the corresponging chip histogram:
-                TH1F *chipHitHistogram = fDetectorHitHistograms.at(boardIndex)->at(moduleIndex)->at(chipIndex)
-                    ->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                for(auto chip: *hybrid)  //for on chip - begin 
+                {
+                    size_t chipIndex = chip->getIndex();
+                    cValidation->cd(chipIndex+1);
+                    // Retreive the corresponging chip histogram:
+                    TH1F *chipHitHistogram = fDetectorHitHistograms.at(boardIndex)->at(opticalGroupIndex)->at(hybridIndex)->at(chipIndex)
+                        ->getSummary<HistContainer<TH1F>>().fTheHistogram;
 
-                //Format the histogram (here you are outside from the SoC so you can use all the ROOT functions you need)
-                chipHitHistogram->SetStats(false);
-                chipHitHistogram->SetLineColor(kRed);
-                chipHitHistogram->DrawCopy();
-            } //for on chip - end 
-        } //for on module - end 
+                    //Format the histogram (here you are outside from the SoC so you can use all the ROOT functions you need)
+                    chipHitHistogram->SetStats(false);
+                    chipHitHistogram->SetLineColor(kRed);
+                    chipHitHistogram->DrawCopy();
+                } //for on chip - end 
+            } //for on hybrid - end 
+        } //for on opticalGroup - end 
     } //for on boards - end 
 }
 
diff --git a/HWDescription/FrontEndDescription.cc b/HWDescription/FrontEndDescription.cc
index fbb778b28..529de0f2d 100644
--- a/HWDescription/FrontEndDescription.cc
+++ b/HWDescription/FrontEndDescription.cc
@@ -12,27 +12,27 @@
 namespace Ph2_HwDescription
 {
   FrontEndDescription::FrontEndDescription (uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, bool pStatus, FrontEndType pType)
-    : fBeId   (pBeId)
-    , fFMCId  (pFMCId)
-    , fFeId   (pFeId)
-    , fStatus (pStatus)
-    , fType   (pType)
+    : fBeId        (pBeId)
+    , fFMCId       (pFMCId)
+    , fFeId        (pFeId)
+    , fStatus      (pStatus)
+    , fType        (pType)
   {}
 
   FrontEndDescription::FrontEndDescription()
-    : fBeId   (0)
-    , fFMCId  (0)
-    , fFeId   (0)
-    , fStatus (true)
-    , fType   (FrontEndType::UNDEFINED)
+    : fBeId        (0)
+    , fFMCId       (0)
+    , fFeId        (0)
+    , fStatus      (true)
+    , fType        (FrontEndType::UNDEFINED)
   {}
 
   FrontEndDescription::FrontEndDescription (const FrontEndDescription& pFeDesc)
-    : fBeId   (pFeDesc.fBeId)
-    , fFMCId  (pFeDesc.fFMCId)
-    , fFeId   (pFeDesc.fFeId)
-    , fStatus (pFeDesc.fStatus)
-    , fType   (pFeDesc.fType)
+    : fBeId          (pFeDesc.fBeId        )
+    , fFMCId         (pFeDesc.fFMCId       )
+    , fFeId          (pFeDesc.fFeId        )
+    , fStatus        (pFeDesc.fStatus      )
+    , fType          (pFeDesc.fType        )
   {}
 
   FrontEndDescription::~FrontEndDescription() {}
diff --git a/HWInterface/CbcInterface.cc b/HWInterface/CbcInterface.cc
index d28997f0f..4b134ee9f 100644
--- a/HWInterface/CbcInterface.cc
+++ b/HWInterface/CbcInterface.cc
@@ -157,7 +157,6 @@ namespace Ph2_HwInterface
     std::vector<uint8_t> CbcInterface::createHitListFromStubs(uint8_t pSeed, bool pSeedLayer )
     {
         std::vector<uint8_t> cChannelList(0);
-        uint32_t cFirstStrip = 2*std::floor(pSeed/2.0) + 1;
         uint32_t cSeedStrip = std::floor(pSeed/2.0); // counting from 1 
         LOG (DEBUG) << BOLDMAGENTA << "Seed of " << +pSeed << " means first hit is in strip " << +cSeedStrip << RESET;
         size_t cNumberOfChannels = 1 + (pSeed%2 != 0);    
@@ -186,7 +185,6 @@ namespace Ph2_HwInterface
 
         bool cLayerSwap = ( this->ReadChipReg(pChip , "LayerSwap") == 1 );
         LOG (DEBUG) << BOLDBLUE << "Injecting... stub in position " << +pStubAddress << " [half strips] with a bend of " << pStubBend << " [half strips]." <<  RESET;   
-        double cSeedStrip = (pStubAddress*0.5);
         std::vector<uint8_t> cSeedHits = createHitListFromStubs(pStubAddress,!cLayerSwap);
         // //try it here first 
         uint8_t cCorrelated = pStubAddress + pStubBend; // start counting strips from 0
@@ -366,7 +364,6 @@ namespace Ph2_HwInterface
                      std::vector<std::pair<std::string, uint16_t> > cRegVec;
                     // TriggerLatency1 holds bits 0-7 and FeCtrl&TrgLate2 holds 8
                     uint16_t cLat1 = dacValue & 0x00FF;
-                    uint16_t cReg = pCbc->getReg("FeCtrl&TrgLat2"); 
                     uint16_t cLat2 = (pCbc->getReg ("FeCtrl&TrgLat2") & 0xFE) | ( (dacValue & 0x0100) >> 8);
                     cRegVec.emplace_back ("TriggerLatency1", cLat1);
                     cRegVec.emplace_back ("FeCtrl&TrgLat2", cLat2);
@@ -571,8 +568,6 @@ namespace Ph2_HwInterface
             {
                 char dacName1[20];
                 sprintf (dacName1, dacTemplate.c_str(), iChannel+1);
-                ChipRegItem cRegItem = pCbc->getRegItem ( dacName1 );
-                cRegItem.fValue = localRegValues.getChannel<uint16_t>(iChannel);
                 // fBoardFW->EncodeReg ( cRegItem, pCbc->getFeId(), pCbc->getChipId(), cVec, pVerifLoop, true );
                 // #ifdef COUNT_FLAG
                 //     fRegisterCount++;
diff --git a/HWInterface/CicInterface.cc b/HWInterface/CicInterface.cc
index 3cc9e5401..cd3e8f307 100644
--- a/HWInterface/CicInterface.cc
+++ b/HWInterface/CicInterface.cc
@@ -682,7 +682,6 @@ namespace Ph2_HwInterface {
         }
         
         size_t cInputLineCounter = 0 ;
-        size_t cLineCounter=0;
         //std::vector<std::bitset<6>> cFeStates(8,0);
         cPortCounter=0;
         for( size_t cFeCounter=0; cFeCounter < 8; cFeCounter++)
diff --git a/HWInterface/D19cFWInterface.cc b/HWInterface/D19cFWInterface.cc
index e3e8b405d..22fe3e35d 100755
--- a/HWInterface/D19cFWInterface.cc
+++ b/HWInterface/D19cFWInterface.cc
@@ -368,7 +368,7 @@ namespace Ph2_HwInterface
             this->WriteStackReg( cVecReg ); 
             uint32_t cReadBack = this->ReadReg("sysreg.spi.rx_data");
             cReadBack = this->ReadReg("sysreg.spi.rx_data");
-            //LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
+            LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
         }
         cVecReg.clear();
         std::this_thread::sleep_for (std::chrono::milliseconds (500) );
@@ -454,7 +454,7 @@ namespace Ph2_HwInterface
         this->WriteReg("sysreg.spi.tx_data",cBufferValue);
         uint32_t cReadBack = this->ReadReg("sysreg.spi.rx_data");
         cReadBack = this->ReadReg("sysreg.spi.rx_data");
-        //LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
+        LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
       }
       // store in EEprom
       std::this_thread::sleep_for (std::chrono::milliseconds (1000) );
@@ -508,7 +508,7 @@ namespace Ph2_HwInterface
         this->WriteReg("sysreg.spi.command", cSPIcommand);
         uint32_t cReadBack = this->ReadReg("sysreg.spi.rx_data");
         cReadBack = this->ReadReg("sysreg.spi.rx_data");
-        //LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
+        LOG (DEBUG) << BOLDBLUE << "Dummy read from SPI returns : " << cReadBack << RESET;
     }
     void D19cFWInterface::powerAllFMCs(bool pEnable)
     {
@@ -1528,11 +1528,9 @@ bool D19cFWInterface::L1PhaseTuning(const BeBoard* pBoard , bool pScope)
     // back-end tuning on l1 lines
     for (auto& cFe : pBoard->fModuleVector)
     {
-        uint8_t cBitslip=0;
         selectLink (cFe->getLinkId());
         uint8_t cHybrid= cFe->getFeId() ;
         uint8_t cChip = 0;
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
         int cChipId = static_cast<OuterTrackerModule*>(cFe)->fCic->getChipId();
         // need to know the address 
         //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybrid) ;
@@ -1559,7 +1557,6 @@ bool D19cFWInterface::L1PhaseTuning(const BeBoard* pBoard , bool pScope)
             this->Start();
             std::this_thread::sleep_for (std::chrono::milliseconds (100) );
             this->Stop();
-            uint8_t cLineStatus = pTuner.GetLineStatus(this, cHybrid, cChip, cLineId);
         }
     }
 
@@ -1632,7 +1629,6 @@ bool D19cFWInterface::L1WordAlignment(const BeBoard* pBoard , bool pScope)
         selectLink (cFe->getLinkId());
         uint8_t cHybrid= cFe->getFeId() ;
         uint8_t cChip = 0;
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
         int cChipId = static_cast<OuterTrackerModule*>(cFe)->fCic->getChipId();
         // need to know the address 
         //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybrid) ;
@@ -1656,7 +1652,6 @@ bool D19cFWInterface::L1WordAlignment(const BeBoard* pBoard , bool pScope)
                 this->Start();
                 std::this_thread::sleep_for (std::chrono::milliseconds (500) );
                 this->Stop();
-                uint8_t cLineStatus = pTuner.GetLineStatus(this, cHybrid, cChip, cLineId);
                 cSuccess = pTuner.fDone;
             }
             // if the above doesn't work.. try and find the correct bitslip manually in software 
@@ -1789,7 +1784,6 @@ bool D19cFWInterface::StubTuning(const BeBoard* pBoard, bool pScope)
                 std::this_thread::sleep_for (std::chrono::milliseconds (10) );
                 pTuner.SendControl(this, cHybrid, 0 , cLineId , "WordAlignment"); 
                 std::this_thread::sleep_for (std::chrono::milliseconds (50) );
-                uint8_t cLineStatus = pTuner.GetLineStatus(this, cHybrid, 0, cLineId);
                 //LOG (DEBUG) << BOLDBLUE << "Line status " << +cLineStatus << RESET;
                 uint8_t cAttempts=0;
                 if( pTuner.fBitslip == 0 )
@@ -1807,7 +1801,6 @@ bool D19cFWInterface::StubTuning(const BeBoard* pBoard, bool pScope)
                         cGBTx.gbtxSetPhase(this, fGBTphase) ; 
                         pTuner.SendControl(this, cHybrid, 0 , cLineId , "WordAlignment"); 
                         std::this_thread::sleep_for (std::chrono::milliseconds (50) );
-                        cLineStatus = pTuner.GetLineStatus(this, cHybrid, 0, cLineId);
                         cAttempts++;
                     }while( pTuner.fBitslip == 0) ;
                 }
@@ -2113,7 +2106,6 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
                     {
                         cSuccess = cTuner.TuneLine(this,  cReadoutChip->getFeId() , cReadoutChip->getChipId() , cLineId , cPattern , 8 , true);
                         std::this_thread::sleep_for (std::chrono::milliseconds (200) );
-                        uint8_t cLineStatus = cTuner.GetLineStatus(this,  cReadoutChip->getFeId() , cReadoutChip->getChipId() , cLineId );
                         //LOG (INFO) << BOLDBLUE << "Automated phase tuning attempt" << cAttempts << " : " << ((cSuccess) ? "Worked" : "Failed") << RESET;
                         cAttempts++;
                     }while(!cSuccess && cAttempts <10);
@@ -2182,7 +2174,6 @@ bool D19cFWInterface::PhaseTuning (BeBoard* pBoard, uint8_t pFeId, uint8_t pChip
 
 uint32_t D19cFWInterface::ReadData ( BeBoard* pBoard, bool pBreakTrigger, std::vector<uint32_t>& pData, bool pWait)
 {
-    uint32_t cEventSize = computeEventSize (pBoard);
     uint32_t cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt");
     uint32_t data_handshake = ReadReg ("fc7_daq_cnfg.readout_block.global.data_handshake_enable");
     uint32_t cPackageSize = ReadReg ("fc7_daq_cnfg.readout_block.packet_nbr") + 1;
@@ -2359,7 +2350,6 @@ void D19cFWInterface::ReadNEvents (BeBoard* pBoard, uint32_t pNEvents, std::vect
     // sta
     bool pFailed = false;
     uint32_t cReadoutReq = ReadReg ("fc7_daq_stat.readout_block.general.readout_req");
-    uint32_t cNtriggers = ReadReg ("fc7_daq_stat.fast_command_block.trigger_in_counter");
     uint32_t cNWords = ReadReg ("fc7_daq_stat.readout_block.general.words_cnt");
 
     uint32_t cTimeoutCounter = 0 ;
@@ -2651,7 +2641,6 @@ void D19cFWInterface::BCEncodeReg ( const ChipRegItem& pRegItem,
     {
         GbtInterface cGBTx;
         //assume that they are all the same just to test - multibyte write for CBC
-        uint8_t cFirstChip = (pVecSend[0] & (0x1F << 18) ) >> 18;
         uint8_t cWriteReq = !((pVecSend[0] & (0x1 <<16)) >> 16); 
         if( cWriteReq == 1 )  
         {
diff --git a/HWInterface/GbtInterface.cc b/HWInterface/GbtInterface.cc
index 385d9a3cf..d96deebd7 100644
--- a/HWInterface/GbtInterface.cc
+++ b/HWInterface/GbtInterface.cc
@@ -555,7 +555,6 @@ namespace Ph2_HwInterface
             icWrite( pInterface, cRegister , cRegValue );
         }
         // then for EC port 
-        uint16_t cRegister = 232;
     }
     void GbtInterface::gbtxFrameAlignerDLL(BeBoardFWInterface* pInterface, std::vector<uint8_t> pGroups, uint8_t pDLLcurrent, uint8_t pLockMode )
     {
@@ -819,13 +818,11 @@ namespace Ph2_HwInterface
     {
         // number of bytes to write at a time 
         uint8_t cNBytes = 2; 
-        uint8_t cNSimWrites = 1;
         // work in progress
         std::map<uint8_t, std::vector<uint32_t>> cI2C; 
         cI2C.clear();
 
         auto cIterator = pVecSend.begin();
-        size_t cRegisters=0;
         SCAI2C cSCAcommand;
         while( cIterator < pVecSend.end() ) 
         {
@@ -905,17 +902,17 @@ namespace Ph2_HwInterface
                     {
                         auto& cChipId = cChipIterator->first;
                         auto& cRegisters = cChipIterator->second;
-                        uint32_t cErrorCode=0;
-                        uint8_t cSlave = 0; 
+                        // uint32_t cErrorCode=0;
+                        // uint8_t cSlave = 0; 
                         if( cChipId < 8 ) // CBC 
                         {
-                            cSlave = 0x40 | (cChipId + 1 );
+                            // cSlave = 0x40 | (cChipId + 1 );
                             cNBytes=2;
-                            cErrorCode = this->cbcSetPage(pInterface,(cMaster-fSCAMaster), cChipId, cPage+1);
+                            // cErrorCode = this->cbcSetPage(pInterface,(cMaster-fSCAMaster), cChipId, cPage+1);
                         }
                         else
                         {
-                            cSlave = 0x60;
+                            // cSlave = 0x60;
                             cNBytes = 3 ;
                         }
 
@@ -926,14 +923,12 @@ namespace Ph2_HwInterface
                         cIterator = cRegisters.begin();
                         while( cIterator < cRegisters.end() ) 
                         {
-                            uint32_t cWord = *cIterator;
+                            // uint32_t cWord = *cIterator;
                             //upload data bytes to send in the DATA register
-                            uint8_t cAddress = ( cWord & (0xFF << 8) ) >> 8;
-                            uint8_t cValue = ( cWord & (0xFF << 0) ) >> 0;
-                            uint16_t cDataField = (cAddress << 8) | cValue ; 
-                            uint32_t pData = (cChipId < 8 ) ? ((cAddress << 8*3) | (cValue << 8*2)) : ( (cAddress << 16) | ( cValue << 8) );
-                            cErrorCode = ecWrite( pInterface, cMaster , 0x40 , pData  );
-                            cErrorCode = ecWrite(pInterface, cMaster , 0xDA , (cSlave << 3*8) );
+                            // uint8_t cAddress = ( cWord & (0xFF << 8) ) >> 8;
+                            // uint8_t cValue = ( cWord & (0xFF << 0) ) >> 0;
+                            // cErrorCode = ecWrite( pInterface, cMaster , 0x40 , pData  );
+                            // cErrorCode = ecWrite(pInterface, cMaster , 0xDA , (cSlave << 3*8) );
                             cIterator++;
                         }
                         cChipIterator++;
diff --git a/HWInterface/RD53FWInterface.cc b/HWInterface/RD53FWInterface.cc
index b725ab5e3..d7c52019a 100644
--- a/HWInterface/RD53FWInterface.cc
+++ b/HWInterface/RD53FWInterface.cc
@@ -792,10 +792,11 @@ namespace Ph2_HwInterface
 
   void RD53FWInterface::Event::fillDataContainer (BoardDataContainer* boardContainer, const ChannelGroupBase* cTestChannelGroup)
   {
-    bool   vectorRequired = boardContainer->at(0)->at(0)->isSummaryContainerType<Summary<GenericDataVector,OccupancyAndPh>>();
+    bool   vectorRequired = boardContainer->at(0)->at(0)->at(0)->isSummaryContainerType<Summary<GenericDataVector,OccupancyAndPh>>();
     size_t chipIndx;
 
-    for (const auto& cModule : *boardContainer)
+    for (const auto& opticalReadout : *boardContainer)
+    for (const auto& cModule : *opticalReadout)
       for (const auto& cChip : *cModule)
         if (RD53FWInterface::Event::isHittedChip(cModule->getId(), cChip->getId(), chipIndx) == true)
           {
diff --git a/RootUtils/RootContainerFactory.h b/RootUtils/RootContainerFactory.h
index 7e19a683a..d87a64efc 100644
--- a/RootUtils/RootContainerFactory.h
+++ b/RootUtils/RootContainerFactory.h
@@ -67,22 +67,24 @@ namespace RootContainerFactory
 
 	using namespace details;
 
-	template<typename T, typename SC, typename SM, typename SB, typename SD>
-	void bookHistogramsFromStructure(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& channel, const SC& chipSummary, const SM& moduleSummary, const SB& boardSummary, const SD& detectorSummary)
+	template<typename T, typename SC, typename SM, typename SO, typename SB, typename SD>
+	void bookHistogramsFromStructure(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& channel, const SC& chipSummary, const SM& hybridSummary, const SO& opticalGroupSummary, const SB& boardSummary, const SD& detectorSummary)
 	{
 		std::string detectorFolder = "Detector";
 		createAndOpenRootFileFolder(theOutputFile,detectorFolder);
-		std::string channelHistogramGenericName         = getPlotName(&channel);
-		std::string chipSummaryHistogramGenericName     = getPlotName(&chipSummary);
-		std::string moduleSummaryHistogramGenericName   = getPlotName(&moduleSummary);
-		std::string boardSummaryHistogramGenericName    = getPlotName(&boardSummary);
-		std::string detectorSummaryHistogramGenericName = getPlotName(&detectorSummary);
+		std::string channelHistogramGenericName              = getPlotName(&channel);
+		std::string chipSummaryHistogramGenericName          = getPlotName(&chipSummary);
+		std::string hybridSummaryHistogramGenericName        = getPlotName(&hybridSummary);
+		std::string opticalGroupSummaryHistogramGenericName  = getPlotName(&opticalGroupSummary);
+		std::string boardSummaryHistogramGenericName         = getPlotName(&boardSummary);
+		std::string detectorSummaryHistogramGenericName      = getPlotName(&detectorSummary);
 		
-		std::string channelHistogramGenericTitle         = getPlotTitle(&channel);
-		std::string chipSummaryHistogramGenericTitle     = getPlotTitle(&chipSummary);
-		std::string moduleSummaryHistogramGenericTitle   = getPlotTitle(&moduleSummary);
-		std::string boardSummaryHistogramGenericTitle    = getPlotTitle(&boardSummary);
-		std::string detectorSummaryHistogramGenericTitle = getPlotTitle(&detectorSummary);
+		std::string channelHistogramGenericTitle             = getPlotTitle(&channel);
+		std::string chipSummaryHistogramGenericTitle         = getPlotTitle(&chipSummary);
+		std::string hybridSummaryHistogramGenericTitle       = getPlotTitle(&hybridSummary);
+		std::string opticalGroupSummaryHistogramGenericTitle = getPlotTitle(&opticalGroupSummary);
+		std::string boardSummaryHistogramGenericTitle        = getPlotTitle(&boardSummary);
+		std::string detectorSummaryHistogramGenericTitle     = getPlotTitle(&detectorSummary);
 		
 		copy.initialize<SD,SB>();
 
@@ -96,7 +98,6 @@ namespace RootContainerFactory
 		copy.getSummary<SD,SB>() = std::move(theDetectorSummary);
 
 		//Boards
-		// for(const std::vector<BoardContainer*>::iterator board = original.begin(); board != original.end(); board++)
 		for(const BoardContainer *board : original)
 		{
 			std::string boardFolder = "/Board_" + std::to_string(board->getId());
@@ -115,106 +116,139 @@ namespace RootContainerFactory
                                 boardSummaryHistogramGenericTitle.data(),
                                 board->getId()),
                            &boardSummary);
-			copyBoard->getSummary<SB,SM>() = std::move(theBoardSummary);
+			copyBoard->getSummary<SB,SO>() = std::move(theBoardSummary);
 
-			//Modules
-			for(const ModuleContainer* module : *board)
+
+			//OpticalGroups
+			for(const OpticalGroupContainer *opticalGroup : *board)
 			{
-				std::string moduleFolder = "/Module_" + std::to_string(module->getId());
-				std::string fullModuleFolder = detectorFolder + boardFolder + moduleFolder;
-				createAndOpenRootFileFolder(theOutputFile, fullModuleFolder);
-
-				ModuleDataContainer* copyModule = copyBoard->addModuleDataContainer(module->getId());
-				copyModule->initialize<SM,SC>();
-
-				SM theModuleSummary;
-				initializePlot(&theModuleSummary,
-                               Form("D_B(%d)_%s_Module(%d)",
-                                    board->getId(),
-                                    moduleSummaryHistogramGenericName.data(),
-                                    module->getId()),
-                               Form("D_B(%d)_%s_Module(%d)",
-                                    board->getId(),
-                                    moduleSummaryHistogramGenericTitle.data(),
-                                    module->getId()),
-                               &moduleSummary);
-				copyModule->getSummary<SM,SC>() = std::move(theModuleSummary);
-
-				//Chips
-				for(const ChipContainer* chip : *module)
+				std::string opticalGroupFolder = "/OpticalGroup_" + std::to_string(opticalGroup->getId());
+				std::string fullOpticalGroupFolder = detectorFolder + boardFolder +opticalGroupFolder;
+				createAndOpenRootFileFolder(theOutputFile, fullOpticalGroupFolder);
+			
+				OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
+				copyOpticalGroup->initialize<SO,SM>();
+
+				SO theOpticalGroupSummary;
+				initializePlot(&theOpticalGroupSummary,
+							Form("D_%s_OpticalGroup_(%d)",
+									opticalGroupSummaryHistogramGenericName.data(),
+									opticalGroup->getId()),
+							Form("D_%s_OpticalGroup(%d)",
+									opticalGroupSummaryHistogramGenericTitle.data(),
+									opticalGroup->getId()),
+							&opticalGroupSummary);
+				copyOpticalGroup->getSummary<SO,SM>() = std::move(theOpticalGroupSummary);
+
+
+
+				//Modules
+				for(const ModuleContainer* hybrid : *opticalGroup)
 				{
-					std::string chipFolder = "/Chip_" + std::to_string(chip->getId());
-					std::string fullChipFolder = detectorFolder + boardFolder + moduleFolder + chipFolder;
-					createAndOpenRootFileFolder(theOutputFile, fullChipFolder);
-
-					ChipDataContainer* copyChip = copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
-					copyChip->initialize<SC,T>();
-					
-					SC theChipSummary;
-					initializePlot(&theChipSummary,
-                                   Form("D_B(%d)_M(%d)_%s_Chip(%d)",
-                                        board->getId(),
-                                        module->getId(),
-                                        chipSummaryHistogramGenericName.c_str(),
-                                        chip->getId()),
-                                   Form("D_B(%d)_M(%d)_%s_Chip(%d)",
-                                        board->getId(),
-                                        module->getId(),
-                                        chipSummaryHistogramGenericTitle.c_str(),
-                                        chip->getId()),
-                                   &chipSummary);
-					copyChip->getSummary<SC,T>() = std::move(theChipSummary) ;
-	
-					//Channels
-					std::string channelFolder = "/Channel";
-					std::string fullChannelFolder = detectorFolder + boardFolder + moduleFolder + chipFolder + channelFolder;
-					createAndOpenRootFileFolder(theOutputFile, fullChannelFolder);
-
-					for(uint32_t row=0; row < chip->getNumberOfRows(); ++row)
+					std::string hybridFolder = "/Module_" + std::to_string(hybrid->getId());
+					std::string fullModuleFolder = detectorFolder + boardFolder + opticalGroupFolder + hybridFolder;
+					createAndOpenRootFileFolder(theOutputFile, fullModuleFolder);
+
+					ModuleDataContainer* copyModule = copyOpticalGroup->addModuleDataContainer(hybrid->getId());
+					copyModule->initialize<SM,SC>();
+
+					SM theModuleSummary;
+					initializePlot(&theModuleSummary,
+								Form("D_B(%d)_O(%d)_%s_Module(%d)",
+										board->getId(),
+										opticalGroup->getId(),
+										hybridSummaryHistogramGenericName.data(),
+										hybrid->getId()),
+								Form("D_B(%d)_O(%d)_%s_Module(%d)",
+										board->getId(),
+										opticalGroup->getId(),
+										hybridSummaryHistogramGenericTitle.data(),
+										hybrid->getId()),
+								&hybridSummary);
+					copyModule->getSummary<SM,SC>() = std::move(theModuleSummary);
+
+					//Chips
+					for(const ChipContainer* chip : *hybrid)
 					{
-						for(uint32_t col=0; col < chip->getNumberOfCols(); ++col)
+						std::string chipFolder = "/Chip_" + std::to_string(chip->getId());
+						std::string fullChipFolder = detectorFolder + boardFolder + opticalGroupFolder + hybridFolder + chipFolder;
+						createAndOpenRootFileFolder(theOutputFile, fullChipFolder);
+
+						ChipDataContainer* copyChip = copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
+						copyChip->initialize<SC,T>();
+						
+						SC theChipSummary;
+						initializePlot(&theChipSummary,
+									Form("D_B(%d)_O(%d)_M(%d)_%s_Chip(%d)",
+											board->getId(),
+											opticalGroup->getId(),
+											hybrid->getId(),
+											chipSummaryHistogramGenericName.c_str(),
+											chip->getId()),
+									Form("D_B(%d)_O(%d)_M(%d)_%s_Chip(%d)",
+											board->getId(),
+											opticalGroup->getId(),
+											hybrid->getId(),
+											chipSummaryHistogramGenericTitle.c_str(),
+											chip->getId()),
+									&chipSummary);
+						copyChip->getSummary<SC,T>() = std::move(theChipSummary) ;
+		
+						//Channels
+						std::string channelFolder = "/Channel";
+						std::string fullChannelFolder = detectorFolder + boardFolder + opticalGroupFolder + hybridFolder + chipFolder + channelFolder;
+						createAndOpenRootFileFolder(theOutputFile, fullChannelFolder);
+
+						for(uint32_t row=0; row < chip->getNumberOfRows(); ++row)
 						{
-							if(channelHistogramGenericName != "NULL")
+							for(uint32_t col=0; col < chip->getNumberOfCols(); ++col)
 							{
-								T theChannel;
-								std::string histogramName;
-								std::string histogramTitle;
-                                if(chip->getNumberOfCols() == 1)
-                                  {
-                                    histogramName  = Form("D_B(%d)_M(%d)_C(%d)_%s_Channel(%d)",
-                                                          board->getId(),
-                                                          module->getId(),
-                                                          chip->getId(),
-                                                          channelHistogramGenericName.data(),
-                                                          row);
-                                    histogramTitle = Form("D_B(%d)_M(%d)_C(%d)_%s_Channel(%d)",
-                                                          board->getId(),
-                                                          module->getId(),
-                                                          chip->getId(),
-                                                          channelHistogramGenericTitle.data(),
-                                                          row);
-                                  }
-                                else
-                                  {
-                                    histogramName = Form("D_B(%d)_M(%d)_C(%d)_%s_Row(%d)_Col(%d)",
-                                                         board->getId(),
-                                                         module->getId(),
-                                                         chip->getId(),
-                                                         channelHistogramGenericName.data(),
-                                                         row,
-                                                         col);
-                                    histogramTitle = Form("D_B(%d)_M(%d)_C(%d)_%s_Row(%d)_Col(%d)",
-                                                          board->getId(),
-                                                          module->getId(),
-                                                          chip->getId(),
-                                                          channelHistogramGenericTitle.data(),
-                                                          row,
-                                                          col);
-                                  }
-								initializePlot(&theChannel,histogramName, histogramTitle, &channel);
-								copyChip->getChannel<T>(row,col) = std::move(theChannel);
-							}
-						}	
+								if(channelHistogramGenericName != "NULL")
+								{
+									T theChannel;
+									std::string histogramName;
+									std::string histogramTitle;
+									if(chip->getNumberOfCols() == 1)
+									{
+										histogramName  = Form("D_B(%d)_O(%d)_M(%d)_C(%d)_%s_Channel(%d)",
+															board->getId(),
+															opticalGroup->getId(),
+															hybrid->getId(),
+															chip->getId(),
+															channelHistogramGenericName.data(),
+															row);
+										histogramTitle = Form("D_B(%d)_O(%d)_M(%d)_C(%d)_%s_Channel(%d)",
+															board->getId(),
+															opticalGroup->getId(),
+															hybrid->getId(),
+															chip->getId(),
+															channelHistogramGenericTitle.data(),
+															row);
+									}
+									else
+									{
+										histogramName = Form("D_B(%d)_O(%d)_M(%d)_C(%d)_%s_Row(%d)_Col(%d)",
+															board->getId(),
+															opticalGroup->getId(),
+															hybrid->getId(),
+															chip->getId(),
+															channelHistogramGenericName.data(),
+															row,
+															col);
+										histogramTitle = Form("D_B(%d)_O(%d)_M(%d)_C(%d)_%s_Row(%d)_Col(%d)",
+															board->getId(),
+															opticalGroup->getId(),
+															hybrid->getId(),
+															chip->getId(),
+															channelHistogramGenericTitle.data(),
+															row,
+															col);
+									}
+									initializePlot(&theChannel,histogramName, histogramTitle, &channel);
+									copyChip->getChannel<T>(row,col) = std::move(theChannel);
+								}
+							}	
+						}
 					}
 				}
 			}
@@ -226,13 +260,13 @@ namespace RootContainerFactory
 	template<typename T>
 	void bookHistogramsFromStructure(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& channel)
 	{
-		bookHistogramsFromStructure<T,T,T,T,T>(theOutputFile, original, copy, channel, channel, channel, channel, channel);
+		bookHistogramsFromStructure<T,T,T,T,T,T>(theOutputFile, original, copy, channel, channel, channel, channel, channel, channel);
 	}
 
 	template<typename T, typename S>
 	void bookHistogramsFromStructure(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& channel, const S& summay)
 	{
-		bookHistogramsFromStructure<T,S,S,S,S>(theOutputFile, original, copy, channel, summay, summay, summay, summay);
+		bookHistogramsFromStructure<T,S,S,S,S,S>(theOutputFile, original, copy, channel, summay, summay, summay, summay, summay);
 	}
 
 
@@ -240,35 +274,42 @@ namespace RootContainerFactory
 	void bookChannelHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& channel)
 	{
 		EmptyContainer theEmpty;
-		bookHistogramsFromStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, channel, theEmpty, theEmpty, theEmpty, theEmpty);
+		bookHistogramsFromStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, channel, theEmpty, theEmpty, theEmpty, theEmpty, theEmpty);
 	}
 
 	template<typename T>
 	void bookChipHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& chipSummary)
 	{
 		EmptyContainer theEmpty;
-		bookHistogramsFromStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, theEmpty, chipSummary, theEmpty, theEmpty, theEmpty);
+		bookHistogramsFromStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, theEmpty, chipSummary, theEmpty, theEmpty, theEmpty, theEmpty);
+	}
+
+	template<typename T>
+	void bookModuleHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& hybridSummary)
+	{
+		EmptyContainer theEmpty;
+		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, theEmpty, theEmpty, hybridSummary, theEmpty, theEmpty, theEmpty);
 	}
 
 	template<typename T>
-	void bookModuleHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& moduleSummary)
+	void bookOpticalGroupHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& opticalGroupSummary)
 	{
 		EmptyContainer theEmpty;
-		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, theEmpty, theEmpty, moduleSummary, theEmpty, theEmpty);
+		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(theOutputFile, original, copy, theEmpty, theEmpty, theEmpty, opticalGroupSummary, theEmpty, theEmpty);
 	}
 
 	template<typename T>
 	void bookBoardHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& boardSummary)
 	{
 		EmptyContainer theEmpty;
-		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(theOutputFile, original, copy, theEmpty, theEmpty, theEmpty, boardSummary, theEmpty);
+		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(theOutputFile, original, copy, theEmpty, theEmpty, theEmpty, theEmpty, boardSummary, theEmpty);
 	}
 
 	template<typename T>
 	void bookDetectorHistograms(TFile *theOutputFile, const DetectorContainer& original, DetectorDataContainer& copy, const T& detectorSummary)
 	{
 		EmptyContainer theEmpty;
-		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(theOutputFile, original, copy, theEmpty, theEmpty, theEmpty, theEmpty, detectorSummary);
+		bookHistogramsFromStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(theOutputFile, original, copy, theEmpty, theEmpty, theEmpty, theEmpty, theEmpty, detectorSummary);
 	}
 
 }
diff --git a/System/FileParser.cc b/System/FileParser.cc
index 590cad320..ecf20e51a 100644
--- a/System/FileParser.cc
+++ b/System/FileParser.cc
@@ -244,13 +244,13 @@ namespace Ph2_System {
 
         os << BLUE <<  "|\t|" << RESET << std::endl;
 
-    // Iterate the module node
-    for ( pugi::xml_node pModuleNode = pBeBordNode.child ( "Module" ); pModuleNode; pModuleNode = pModuleNode.next_sibling() )
+    // Iterate the OpticalGroup node
+    for ( pugi::xml_node pOpticalGroupNode = pBeBordNode.child ( "OpticalGroup" ); pOpticalGroupNode; pOpticalGroupNode = pOpticalGroupNode.next_sibling() )
       {
-        if ( static_cast<std::string> ( pModuleNode.name() ) == "Module" )
+        if ( static_cast<std::string> ( pOpticalGroupNode.name() ) == "OpticalGroup" )
           {
                 // for now try and guess based on xml nodes what the FE is 
-            this->parseModuleContainer (pModuleNode, cBeBoard, os );
+            this->parseOpticalGroupContainer (pOpticalGroupNode, cBeBoard, os );
           }
       }
 
@@ -263,147 +263,24 @@ namespace Ph2_System {
     return;
 
   }
-  /*void FileParser::parseBeBoard (pugi::xml_node pBeBordNode, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os )
-  {
-    uint32_t cBeId = pBeBordNode.attribute ( "Id" ).as_int();
-    BeBoard* cBeBoard = pDetectorContainer->addBoardContainer(cBeId, new BeBoard ( cBeId ));//FIX Change it to Reference!!!!
-    pBoardVector.emplace_back ( cBeBoard );
-
-    pugi::xml_attribute cBoardTypeAttribute = pBeBordNode.attribute ("boardType");
-
-    if (cBoardTypeAttribute == nullptr)
-      {
-        LOG (ERROR) << BOLDRED << "Error: Board Type not specified - aborting!" << RESET;
-        exit (1);
-      }
-    std::string cBoardType = cBoardTypeAttribute.value();
-
-        bool cWithOptical=false;
-        for (pugi::xml_node cChild: pBeBordNode.children("GBT_Links"))
-        {
-            std::string cName = cChild.name();
-            os << BOLDBLUE <<  "|"  << "----" <<  cName << "\n" << RESET; 
-            for (pugi::xml_node cGBT : cChild.children("GBT"))
-            {
-                for (pugi::xml_attribute cAttribute: cGBT.attributes())
-                {
-                    if( std::string ( cAttribute.name() ) == "enable")
-                        cWithOptical = cWithOptical | ( convertAnyInt ( cAttribute.value() ) ==1);
-                }
-            }
-        }
-        cBeBoard->setOptical( cWithOptical );
-        bool cConfigureCDCE=false;
-        for (pugi::xml_node cChild: pBeBordNode.children("CDCE"))
-        {
-            for (pugi::xml_attribute cAttribute: cChild.attributes())
-            {
-                if( std::string ( cAttribute.name() ) == "configure")
-                    cConfigureCDCE = cConfigureCDCE | ( convertAnyInt ( cAttribute.value() ) ==1);
-            }
-        }
-        cBeBoard->setCDCEconfiguration( cConfigureCDCE );
-
-        if( cWithOptical )
-            os << BOLDBLUE <<  "|"  << "----" << "Optical link is      " << BOLDGREEN << " is being used.\n" << RESET;
-        else
-            os << BOLDBLUE <<  "|"  << "----" << "Optical link is      " << BOLDRED << " is not being used.\n" << RESET;
-
-        if (cBoardType == "D19C")     cBeBoard->setBoardType (BoardType::D19C);
-    else if (cBoardType == "RD53") cBeBoard->setBoardType (BoardType::RD53);
-    else
-      {
-        LOG (ERROR) << "Error: Unknown Board Type: " << cBoardType << " - aborting!";
-        std::string errorstring = "Unknown Board Type " + cBoardType;
-        throw Exception (errorstring.c_str() );
-        exit (1);
-      }
-
-    pugi::xml_attribute cEventTypeAttribute = pBeBordNode.attribute ("eventType");
-    std::string cEventTypeString;
-
-    if (cEventTypeAttribute == nullptr)
-      {
-        //the HWDescription object does not have and EventType node, so assume EventType::VR
-            cBeBoard->setEventType (EventType::VR);
-            cEventTypeString = "VR";
-        }
-        else
-        {
-            cEventTypeString = cEventTypeAttribute.value();
-            if (cEventTypeString == "ZS") cBeBoard->setEventType (EventType::ZS);
-            else if (cEventTypeString == "SSA") cBeBoard->setEventType (EventType::SSA);
-            else if (cEventTypeString == "MPA") cBeBoard->setEventType (EventType::MPA);
-            else cBeBoard->setEventType (EventType::VR);
-        }
-
-        os << BOLDCYAN << "|" << "----" << pBeBordNode.name() << "  " << pBeBordNode.first_attribute().name() << ": " << BOLDYELLOW << pBeBordNode.attribute ( "Id" ).value() << BOLDCYAN << ", BoardType: " << BOLDYELLOW << cBoardType << BOLDCYAN << ", EventType: " << BOLDYELLOW << cEventTypeString << RESET << std:: endl;
-
-    pugi::xml_node cBeBoardConnectionNode = pBeBordNode.child ("connection");
-
-    std::string cId = cBeBoardConnectionNode.attribute ( "id" ).value();
-    std::string cUri = cBeBoardConnectionNode.attribute ( "uri" ).value();
-    std::string cAddressTable = expandEnvironmentVariables (cBeBoardConnectionNode.attribute ( "address_table" ).value() );
-
-    if (cBeBoard->getBoardType() == BoardType::D19C)
-      {
-        pBeBoardFWMap[cBeBoard->getBeBoardId()] =  new D19cFWInterface ( cId.c_str(), cUri.c_str(), cAddressTable.c_str() );
-            for (pugi::xml_node cChild: pBeBordNode.children("GBT_Links"))
-            {
-                for (pugi::xml_node cGBT : cChild.children("GBT"))
-                {
-                    for (pugi::xml_attribute cAttribute: cGBT.attributes())
-                    {
-                        if( std::string ( cAttribute.name() ) == "phaseTap") // T.B.D store this somewhere...but where 
-                        {
-                            static_cast<D19cFWInterface*>(pBeBoardFWMap[cBeBoard->getBeBoardId()])->setGBTxPhase( convertAnyInt (cAttribute.value()) );
-                            os << BOLDBLUE << "|" << "       " <<  "|"  << "----" << " phase is :      " << BOLDYELLOW << cAttribute.value() << std::endl << RESET;
-                        }
-                    }
-                }
-            }
-        }
-    else if (cBeBoard->getBoardType() == BoardType::RD53)
-      {
-            pBeBoardFWMap[cBeBoard->getBeBoardId()]   =  new RD53FWInterface (cId.c_str(), cUri.c_str(), cAddressTable.c_str());
-      }
 
-        os << BOLDBLUE << "|" << "       " <<  "|"  << "----" << "Board Id:      " << BOLDYELLOW << cId << std::endl << BOLDBLUE <<  "|" << "       " <<  "|"  << "----" << "URI:           " << BOLDYELLOW << cUri << std::endl << BOLDBLUE <<  "|" << "       " <<  "|"  << "----" << "Address Table: " << BOLDYELLOW << cAddressTable << std::endl << BOLDBLUE << "|" << "       " <<  "|" << RESET << std::endl;
-
-    // Iterate over the BeBoardRegister Nodes
-    for ( pugi::xml_node cBeBoardRegNode = pBeBordNode.child ( "Register" ); cBeBoardRegNode; cBeBoardRegNode = cBeBoardRegNode.next_sibling() )
-      {
-        if (std::string (cBeBoardRegNode.name() ) == "Register")
-          {
-            std::string cNameString;
-            uint32_t cValue;
-            this->parseRegister (cBeBoardRegNode, cNameString, cValue, cBeBoard, os);
-                os << BOLDBLUE << "|" << "       " <<  "|"  << "----" << "Board Id:      " << BOLDYELLOW << cId << std::endl << BOLDBLUE <<  "|    " << cNameString << " : " << +cValue << RESET; 
-                    //<< "       " <<  "|"  << "----" << "URI:           " << BOLDYELLOW << cUri << std::endl << BOLDBLUE <<  "|" << "       " <<  "|"  << "----" << "Address Table: " << BOLDYELLOW << cAddressTable << std::endl << BOLDBLUE << "|" << "       " <<  "|" << RESET << std::endl;
-          }
-      }
+  void FileParser::parseOpticalGroupContainer  (pugi::xml_node pOpticalGroupNode, BeBoard* pBoard, std::ostream& os )
+  {
 
-        os << BLUE <<  "|\t|" << RESET << std::endl;
+    uint32_t cOpticalGroupId = pOpticalGroupNode.attribute ( "Id"    ).as_int();
+    uint32_t cFMCId          = pOpticalGroupNode.attribute ( "FMCId" ).as_int();
+    uint32_t cBoardId        = pBoard->getBeBoardId();
+    OpticalGroup* theOpticalGroup = pBoard->addOpticalGroupContainer(cBoardId, new OpticalGroup (cBoardId, cFMCId, cOpticalGroupId));
 
-    // Iterate the module node
-    for ( pugi::xml_node pModuleNode = pBeBordNode.child ( "Module" ); pModuleNode; pModuleNode = pModuleNode.next_sibling() )
+    for ( pugi::xml_node pModuleNode = pOpticalGroupNode.child ( "Module" ); pModuleNode; pModuleNode = pModuleNode.next_sibling() )
       {
         if ( static_cast<std::string> ( pModuleNode.name() ) == "Module" )
           {
                 // for now try and guess based on xml nodes what the FE is 
-            this->parseModuleContainer (pModuleNode, cBeBoard, os );
+            this->parseModuleContainer (pModuleNode, theOpticalGroup, os, pBoard);
           }
       }
-
-    //here parse the Slink Node
-    pugi::xml_node cSLinkNode = pBeBordNode.child ("SLink");
-    this->parseSLink (cSLinkNode, cBeBoard, os);
-
-    // pBoardVector.emplace_back( cBeBoard );
-
-    return;
-
-  }*/
+  }
 
 
   void FileParser::parseRegister (pugi::xml_node pRegisterNode, std::string& pAttributeString, uint32_t& pValue, BeBoard* pBoard, std::ostream& os)
@@ -569,10 +446,10 @@ namespace Ph2_System {
 
     void FileParser::parseSSASettings (pugi::xml_node pModuleNode, ReadoutChip* pSSA)
     {
-        FrontEndType cType = pSSA->getFrontEndType();
+        // FrontEndType cType = pSSA->getFrontEndType();
     }
 
-  void FileParser::parseModuleContainer (pugi::xml_node pModuleNode, BeBoard* pBoard, std::ostream& os )
+  void FileParser::parseModuleContainer (pugi::xml_node pModuleNode, OpticalGroup* pOpticalGroup, std::ostream& os, BeBoard* pBoard)
   {
 
     bool cStatus = pModuleNode.attribute ( "Status" ).as_bool();
@@ -589,18 +466,17 @@ namespace Ph2_System {
         Module* cModule;
         if (pBoard->getBoardType() == BoardType::RD53)
           {
-                cModule = pBoard->addModuleContainer( pModuleNode.attribute ( "FeId" ).as_int(), new Module ( pBoard->getBeBoardId(), pModuleNode.attribute ( "FMCId" ).as_int(), pModuleNode.attribute ( "FeId" ).as_int(),  pModuleNode.attribute ( "FeId" ).as_int() ));
+                cModule = pOpticalGroup->addModuleContainer( pModuleNode.attribute ( "FeId" ).as_int(), new Module ( pOpticalGroup->getBeBoardId(), pOpticalGroup->getFMCId(), pModuleNode.attribute ( "FeId" ).as_int(),  pModuleNode.attribute ( "FeId" ).as_int() ));
           }
         else
           {
-            cModule = pBoard->addModuleContainer( pModuleNode.attribute ( "FeId" ).as_int(), new OuterTrackerModule ( pBoard->getBeBoardId(), pModuleNode.attribute ( "FMCId" ).as_int(), pModuleNode.attribute ( "FeId" ).as_int(),  pModuleNode.attribute ( "FeId" ).as_int() ));
+            cModule = pOpticalGroup->addModuleContainer( pModuleNode.attribute ( "FeId" ).as_int(), new OuterTrackerModule ( pOpticalGroup->getBeBoardId(), pOpticalGroup->getFMCId(), pModuleNode.attribute ( "FeId" ).as_int(),  pModuleNode.attribute ( "FeId" ).as_int() ));
             cModule->setLinkId( pModuleNode.attribute ( "LinkId" ).as_int() );
           }
-        pBoard->addModule ( cModule );
+        // pOpticalGroup->addModule ( cModule );
 
             // now try and do the configruation in a slightly more readable
         std::string cConfigFileDirectory;
-            bool cWithCIC=false;
         for (pugi::xml_node cChild: pModuleNode.children())
           {
             std::string cName = cChild.name();
@@ -642,7 +518,6 @@ namespace Ph2_System {
                       }
                         else if( cName == "CIC" || cName == "CIC2") 
                       {
-                            cWithCIC=true;
                             bool cCIC1 = (cName == "CIC");
                             FrontEndType cType = cCIC1 ? FrontEndType::CIC : FrontEndType::CIC2 ;
                             
@@ -679,7 +554,6 @@ namespace Ph2_System {
                                     std::vector<std::string> cAttributes{"clockFrequency", "enableBend","enableLastLine", "enableSparsification"};
                                     std::vector<std::string> cRegNames{ "", "BEND_SEL", "N_OUTPUT_TRIGGER_LINES_SEL", "CBC_SPARSIFICATION_SEL"};
                                     std::vector<uint16_t> cBitPositions{ 1, 2 , 3 , 4 };
-                                    uint8_t cValue = 0;
                                     for( auto it = cRegNames.begin(); it != cRegNames.end(); ++it)
                                     {
                                         auto cIndex = std::distance(cRegNames.begin(), it); 
diff --git a/System/FileParser.h b/System/FileParser.h
index bca07dab4..b6eb5f625 100644
--- a/System/FileParser.h
+++ b/System/FileParser.h
@@ -16,6 +16,7 @@
 #include "../HWInterface/D19cFWInterface.h"
 #include "../HWDescription/Definition.h"
 #include "../HWDescription/Chip.h"
+#include "../HWDescription/OpticalGroup.h"
 #include "../Utils/Utilities.h"
 #include "../Utils/Exception.h"
 #include "../Utils/ConditionDataSet.h"
@@ -79,13 +80,14 @@ namespace Ph2_System
      */
     void parseSettingsxml ( const std::string& pFilename, SettingsMap& pSettingsMap, std::ostream& os, bool pIsFile );
 
-    void parseBeBoard          (pugi::xml_node pBeBordNode,   BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os );
-    void parseRegister         (pugi::xml_node pRegisterNode, std::string& pAttributeString, uint32_t& pValue, Ph2_HwDescription::BeBoard* pBoard, std::ostream& os );
-    void parseSLink            (pugi::xml_node pSLinkNode,    Ph2_HwDescription::BeBoard* pBoard,               std::ostream& os );
-    void parseModuleContainer  (pugi::xml_node pModuleNode,   Ph2_HwDescription::BeBoard* pBoard,               std::ostream& os );
-    void parseCbcContainer     (pugi::xml_node pModuleNode,   Ph2_HwDescription::Module* cModule,               std::string cFilePrefix, std::ostream& os );
-    void parseCbcSettings      (pugi::xml_node pCbcNode,      Ph2_HwDescription::ReadoutChip* pCbc,             std::ostream& os);
-    void parseGlobalCbcSettings(pugi::xml_node pModuleNode,   Ph2_HwDescription::Module* pModule,               std::ostream& os);
+    void parseBeBoard                (pugi::xml_node pBeBordNode,   BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os );
+    void parseRegister               (pugi::xml_node pRegisterNode, std::string& pAttributeString, uint32_t& pValue, Ph2_HwDescription::BeBoard* pBoard, std::ostream& os );
+    void parseSLink                  (pugi::xml_node pSLinkNode       , Ph2_HwDescription::BeBoard*      pBoard       , std::ostream& os );
+    void parseOpticalGroupContainer  (pugi::xml_node pOpticalGroupNode, Ph2_HwDescription::BeBoard*      pBoard       , std::ostream& os );
+    void parseModuleContainer        (pugi::xml_node pModuleNode      , Ph2_HwDescription::OpticalGroup* pOpticalGroup, std::ostream& os,  Ph2_HwDescription::BeBoard* pBoard);
+    void parseCbcContainer           (pugi::xml_node pModuleNode      , Ph2_HwDescription::Module*       cModule      , std::string cFilePrefix, std::ostream& os );
+    void parseCbcSettings            (pugi::xml_node pCbcNode         , Ph2_HwDescription::ReadoutChip*  pCbc         , std::ostream& os);
+    void parseGlobalCbcSettings      (pugi::xml_node pModuleNode      , Ph2_HwDescription::Module*       pModule      , std::ostream& os);
 
     void parseSSA         (pugi::xml_node pModuleNode,   Ph2_HwDescription::Module* cModule, std::string cFilePrefix);
     void parseSSASettings (pugi::xml_node pModuleNode,   Ph2_HwDescription::ReadoutChip* cSSA);
diff --git a/Utils/Container.h b/Utils/Container.h
index 0a32f40c9..b07bb40c8 100644
--- a/Utils/Container.h
+++ b/Utils/Container.h
@@ -271,16 +271,26 @@ public:
 private:
 };
 
-class BoardContainer : public Container<ModuleContainer>
+class OpticalGroupContainer : public Container<ModuleContainer>
 {
 public:
-	BoardContainer(uint16_t id) : Container<ModuleContainer>(id){}
+	OpticalGroupContainer(uint16_t id) : Container<ModuleContainer>(id){}
 	template <class T>
 	T*               addModuleContainer(uint16_t id, T* module){return static_cast<T*>(Container<ModuleContainer>::addObject(id, module));}
 	ModuleContainer* addModuleContainer(uint16_t id)                 {return Container<ModuleContainer>::addObject(id, new ModuleContainer(id));}
 private:
 };
 
+class BoardContainer : public Container<OpticalGroupContainer>
+{
+public:
+	BoardContainer(uint16_t id) : Container<OpticalGroupContainer>(id){}
+	template <class T>
+	T*                     addOpticalGroupContainer(uint16_t id, T* opticalGroup){return static_cast<T*>(Container<OpticalGroupContainer>::addObject(id, opticalGroup));}
+	OpticalGroupContainer* addOpticalGroupContainer(uint16_t id)                 {return Container<OpticalGroupContainer>::addObject(id, new OpticalGroupContainer(id));}
+private:
+};
+
 class DetectorContainer : public Container<BoardContainer>
 {
 public:
diff --git a/Utils/ContainerFactory.cc b/Utils/ContainerFactory.cc
index 2858b00a5..58df9f995 100644
--- a/Utils/ContainerFactory.cc
+++ b/Utils/ContainerFactory.cc
@@ -19,12 +19,17 @@ void ContainerFactory::copyStructure(const DetectorContainer& original, Detector
 	for(const BoardContainer *board : original)
 	{
 		BoardDataContainer* copyBoard = copy.addBoardDataContainer(board->getId());
-		for(const ModuleContainer* module : *board)
+		for(const OpticalGroupContainer *opticalGroup : *board)
 		{
-			ModuleDataContainer* copyModule = copyBoard->addModuleDataContainer(module->getId());
-			for(const ChipContainer* chip : *module)
+			OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
+
+			for(const ModuleContainer* hybrid : *opticalGroup)
 			{
-				copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
+				ModuleDataContainer* copyModule = copyOpticalGroup->addModuleDataContainer(hybrid->getId());
+				for(const ChipContainer* chip : *hybrid)
+				{
+					copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
+				}
 			}
 		}
 	}
diff --git a/Utils/ContainerFactory.h b/Utils/ContainerFactory.h
index 65601cad0..cc1ae6cda 100644
--- a/Utils/ContainerFactory.h
+++ b/Utils/ContainerFactory.h
@@ -31,41 +31,50 @@ namespace ContainerFactory
 		for(const BoardDataContainer *board : detector)
 		{
 			std::cout << "Board" << std::endl;
-			for(const ModuleDataContainer* module : *board)
+			for(const OpticalGroupDataContainer *opticalGroup : *board)
 			{
-				std::cout << "Module" << std::endl;
-				for(const ChipDataContainer* chip : *module)
+				std::cout << "OpticalGroup" << std::endl;
+				for(const ModuleDataContainer* hybrid : *opticalGroup)
 				{
-					std::cout << "Chip" << std::endl;
-					for(typename ChannelDataContainer<T>::iterator channel=chip->begin<T>(); channel!=chip->end<T>(); channel++)
-					//for(ChannelBase& channel : chip)
+					std::cout << "Module" << std::endl;
+					for(const ChipDataContainer* chip : *hybrid)
 					{
-						//T& c = static_cast<T&>(*channel);
-						channel->print();
-						std::cout << *channel << std::endl;
-						//std::cout << "channel: " << *channel << std::endl;
+						std::cout << "Chip" << std::endl;
+						for(typename ChannelDataContainer<T>::iterator channel=chip->begin<T>(); channel!=chip->end<T>(); channel++)
+						//for(ChannelBase& channel : chip)
+						{
+							//T& c = static_cast<T&>(*channel);
+							channel->print();
+							std::cout << *channel << std::endl;
+							//std::cout << "channel: " << *channel << std::endl;
+						}
 					}
 				}
 			}
 		}
 	}
 
-	template<typename T, typename SC, typename SM, typename SB, typename SD>
+	template<typename T, typename SC, typename SM, typename SO, typename SB, typename SD>
 	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
 		copy.initialize<SD,SB>();
 		for(const BoardContainer *board : original)
 		{
 			BoardDataContainer* copyBoard = copy.addBoardDataContainer(board->getId());
-			copy.back()->initialize<SB,SM>();
-			for(const ModuleContainer* module : *board)
+			copy.back()->initialize<SB,SO>();
+			for(const OpticalGroupDataContainer *opticalGroup : *board)
 			{
-				ModuleDataContainer* copyModule = copyBoard->addModuleDataContainer(module->getId());
-				copyBoard->back()->initialize<SM,SC>();
-				for(const ChipContainer* chip : *module)
+				OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
+				copyBoard->back()->initialize<SO,SM>();
+				for(const ModuleContainer* hybrid : *opticalGroup)
 				{
-					copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
-					copyModule->back()->initialize<SC,T>();
+					ModuleDataContainer* copyModule = copyOpticalGroup->addModuleDataContainer(hybrid->getId());
+					copyOpticalGroup->back()->initialize<SM,SC>();
+					for(const ChipContainer* chip : *hybrid)
+					{
+						copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
+						copyModule->back()->initialize<SC,T>();
+					}
 				}
 			}
 		}
@@ -74,63 +83,74 @@ namespace ContainerFactory
 	template<typename T>
 	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<T,T,T,T,T>(original, copy);
+		copyAndInitStructure<T,T,T,T,T,T>(original, copy);
 	}
 
 
 	template<typename T, typename SC>
 	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<T,SC,SC,SC,SC>(original, copy);
+		copyAndInitStructure<T,SC,SC,SC,SC,SC>(original, copy);
 	}
 
 	template<typename T>
 	void copyAndInitChannel(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy);
+		copyAndInitStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy);
 	}
 
 	template<typename T>
 	void copyAndInitChip(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy);
+		copyAndInitStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy);
 	}
 
 	template<typename T>
 	void copyAndInitModule(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(original, copy);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy);
+	}
+
+	template<typename T>
+	void copyAndInitOpticalGroup(const DetectorContainer& original, DetectorDataContainer& copy)
+	{
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(original, copy);
 	}
 
 	template<typename T>
 	void copyAndInitBoard(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(original, copy);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(original, copy);
 	}
 
 	template<typename T>
 	void copyAndInitDetector(const DetectorContainer& original, DetectorDataContainer& copy)
 	{
-		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(original, copy);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(original, copy);
 	}
 
 
-	template<typename T, typename SC, typename SM, typename SB, typename SD>
-	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy, T& channel, SC& chipSummay, SM& moduleSummary, SB& boardSummary, SD& detectorSummary)
+	template<typename T, typename SC, typename SM, typename SO, typename SB, typename SD>
+	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy, T& channel, SC& chipSummay, SM& hybridSummary, SO& opticalGroupSummary, SB& boardSummary, SD& detectorSummary)
 	{
 		static_cast<DetectorDataContainer&>(copy).initialize<SD,SB>(detectorSummary);
 		for(const BoardContainer *board : original)
 		{
 			BoardDataContainer* copyBoard = copy.addBoardDataContainer(board->getId());
-			static_cast<BoardDataContainer*>(copy.back())->initialize<SB,SM>(boardSummary);
-			for(const ModuleContainer* module : *board)
+			static_cast<BoardDataContainer*>(copy.back())->initialize<SB,SO>(boardSummary);
+			for(const OpticalGroupDataContainer *opticalGroup : *board)
 			{
-				ModuleDataContainer* copyModule = copyBoard->addModuleDataContainer(module->getId());
-				static_cast<ModuleDataContainer*>(copyBoard->back())->initialize<SM,SC>(moduleSummary);
-				for(const ChipContainer* chip : *module)
+				OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
+				static_cast<BoardDataContainer*>(copyBoard->back())->initialize<SO,SM>(opticalGroupSummary);
+				for(const ModuleContainer* hybrid : *opticalGroup)
 				{
-					copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
-					static_cast<ChipDataContainer*>(copyModule->back())->initialize<SC,T>(chipSummay,channel);
+					ModuleDataContainer* copyModule = copyOpticalGroup->addModuleDataContainer(hybrid->getId());
+					static_cast<ModuleDataContainer*>(copyOpticalGroup->back())->initialize<SM,SC>(hybridSummary);
+					for(const ChipContainer* chip : *hybrid)
+					{
+						copyModule->addChipDataContainer(chip->getId(), chip->getNumberOfRows(), chip->getNumberOfCols());
+						static_cast<ChipDataContainer*>(copyModule->back())->initialize<SC,T>(chipSummay,channel);
+					}
 				}
 			}
 		}
@@ -139,49 +159,56 @@ namespace ContainerFactory
 	template<typename T>
 	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy, T& channel)
 	{
-		copyAndInitStructure<T,T,T,T,T>(original, copy, channel, channel, channel, channel, channel);
+		copyAndInitStructure<T,T,T,T,T,T>(original, copy, channel, channel, channel, channel, channel, channel);
 	}
 
 
 	template<typename T, typename S>
 	void copyAndInitStructure(const DetectorContainer& original, DetectorDataContainer& copy, T& channel, S& summay)
 	{
-		copyAndInitStructure<T,S,S,S,S>(original, copy, channel, summay, summay, summay, summay);
+		copyAndInitStructure<T,S,S,S,S,S>(original, copy, channel, summay, summay, summay, summay, summay);
 	}
 
 	template<typename T>
 	void copyAndInitChannel(const DetectorContainer& original, DetectorDataContainer& copy, T& channel)
 	{
 		EmptyContainer theEmpty;
-		copyAndInitStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy, channel, theEmpty, theEmpty, theEmpty, theEmpty);
+		copyAndInitStructure<T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy, channel, theEmpty, theEmpty, theEmpty, theEmpty, theEmpty);
 	}
 
 	template<typename T>
 	void copyAndInitChip(const DetectorContainer& original, DetectorDataContainer& copy, T& chipSummary)
 	{
 		EmptyContainer theEmpty;
-		copyAndInitStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy, theEmpty, chipSummary, theEmpty, theEmpty, theEmpty);
+		copyAndInitStructure<EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy, theEmpty, chipSummary, theEmpty, theEmpty, theEmpty, theEmpty);
+	}
+
+	template<typename T>
+	void copyAndInitModule(const DetectorContainer& original, DetectorDataContainer& copy, T& hybridSummary)
+	{
+		EmptyContainer theEmpty;
+		copyAndInitStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer,EmptyContainer>(original, copy, theEmpty, theEmpty, hybridSummary, theEmpty, theEmpty, theEmpty);
 	}
 
 	template<typename T>
-	void copyAndInitModule(const DetectorContainer& original, DetectorDataContainer& copy, T& moduleSummary)
+	void copyAndInitOpticalGroup(const DetectorContainer& original, DetectorDataContainer& copy, T& opticalGroupSummary)
 	{
 		EmptyContainer theEmpty;
-		copyAndInitStructure<EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(original, copy, theEmpty, theEmpty, moduleSummary, theEmpty, theEmpty);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer,EmptyContainer>(original, copy, theEmpty, theEmpty, theEmpty, theEmpty, opticalGroupSummary, theEmpty, theEmpty);
 	}
 
 	template<typename T>
 	void copyAndInitBoard(const DetectorContainer& original, DetectorDataContainer& copy, T& boardSummary)
 	{
 		EmptyContainer theEmpty;
-		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(original, copy, theEmpty, theEmpty, theEmpty, boardSummary, theEmpty);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T,EmptyContainer>(original, copy, theEmpty, theEmpty, theEmpty, theEmpty, boardSummary, theEmpty);
 	}
 
 	template<typename T>
 	void copyAndInitDetector(const DetectorContainer& original, DetectorDataContainer& copy, T& detectorSummary)
 	{
 		EmptyContainer theEmpty;
-		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(original, copy, theEmpty, theEmpty, theEmpty, theEmpty, detectorSummary);
+		copyAndInitStructure<EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,EmptyContainer,T>(original, copy, theEmpty, theEmpty, theEmpty, theEmpty, theEmpty, detectorSummary);
 	}
 
 
diff --git a/Utils/ContainerStream.h b/Utils/ContainerStream.h
index 77af2eba7..24e7ddc94 100644
--- a/Utils/ContainerStream.h
+++ b/Utils/ContainerStream.h
@@ -89,6 +89,7 @@ public:
 	}
 
 	uint16_t fBoardId;
+	uint16_t fOpticalGroupId;
 
 } __attribute__((packed));
 
@@ -169,30 +170,34 @@ public:
 } __attribute__((packed));
 
 template <typename C, typename... I>
-class ChannelContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamChannelContainer<C>>
+class ChannelContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, uint16_t, I...>, DataStreamChannelContainer<C>>
 {
 	enum HeaderId
 	{
+		OpticalGroupId,
 		ModuleId,
 		ChipId
 	};
 	static constexpr size_t getEnumSize() { return ChipId + 1; }
 
 public:
-	ChannelContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamChannelContainer<C>>(creatorName) { ; }
+	ChannelContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, uint16_t, I...>, DataStreamChannelContainer<C>>(creatorName) { ; }
 	~ChannelContainerStream() { ; }
 
 	void streamAndSendBoard(BoardDataContainer *board, TCPPublishServer *networkStreamer)
 	{
-		for (auto module : *board)
+		for (auto opticalGroup : *board)
 		{
-			for (auto chip : *module)
+			for (auto hybrid : *opticalGroup)
 			{
-				retrieveChipData(board->getIndex(), module->getIndex(), chip);
-				const std::vector<char> &stream = this->encodeStream();
-				this->incrementStreamPacketNumber();
-				/* std::cout << __PRETTY_FUNCTION__ << "SENDING STREAM!" << std::endl; */
-				networkStreamer->broadcast(stream);
+				for (auto chip : *hybrid)
+				{
+					retrieveChipData(board->getIndex(), opticalGroup->getIndex(), hybrid->getIndex(), chip);
+					const std::vector<char> &stream = this->encodeStream();
+					this->incrementStreamPacketNumber();
+					/* std::cout << __PRETTY_FUNCTION__ << "SENDING STREAM!" << std::endl; */
+					networkStreamer->broadcast(stream);
+				}
 			}
 		}
 	}
@@ -200,6 +205,7 @@ public:
 	void decodeChipData(DetectorDataContainer &detectorContainer)
 	{
 		detectorContainer.getObject(this->fHeaderStream.fBoardId)
+			->getObject(this->fHeaderStream.template getHeaderInfo<HeaderId::OpticalGroupId>())
 			->getObject(this->fHeaderStream.template getHeaderInfo<HeaderId::ModuleId>())
 			->getObject(this->fHeaderStream.template getHeaderInfo<HeaderId::ChipId>())
 			->setChannelContainer(this->fDataStream.fChannelContainer);
@@ -222,9 +228,10 @@ public:
 	}
 
 protected:
-	void retrieveChipData(uint16_t boardId, uint16_t moduleId, ChipDataContainer *chip)
+	void retrieveChipData(uint16_t boardId, uint16_t opticalGroupId, uint16_t moduleId, ChipDataContainer *chip)
 	{
 		this->fHeaderStream.fBoardId = boardId;
+		this->fHeaderStream.template setHeaderInfo<HeaderId::OpticalGroupId>(opticalGroupId);
 		this->fHeaderStream.template setHeaderInfo<HeaderId::ModuleId>(moduleId);
 		this->fHeaderStream.template setHeaderInfo<HeaderId::ChipId>(chip->getIndex());
 		this->fDataStream.fChannelContainer = chip->getChannelContainer<C>();
@@ -322,29 +329,33 @@ public:
 } __attribute__((packed));
 
 template <typename T, typename C, typename... I>
-class ChipContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamChipContainer<T, C>>
+class ChipContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, uint16_t, I...>, DataStreamChipContainer<T, C>>
 {
 	enum HeaderId
 	{
+		OpticalGroupId,
 		ModuleId,
 		ChipId
 	};
 	static constexpr size_t getEnumSize() { return ChipId + 1; }
 
 public:
-	ChipContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamChipContainer<T, C>>(creatorName) { ; }
+	ChipContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, uint16_t, I...>, DataStreamChipContainer<T, C>>(creatorName) { ; }
 	~ChipContainerStream() { ; }
 
 	void streamAndSendBoard(BoardDataContainer *board, TCPPublishServer *networkStreamer)
 	{
-		for (auto module : *board)
+		for (auto opticalGroup : *board)
 		{
-			for (auto chip : *module)
+			for (auto module : *opticalGroup)
 			{
-				retrieveChipData(board->getIndex(), module->getIndex(), chip);
-				const std::vector<char> &stream = this->encodeStream();
-				this->incrementStreamPacketNumber();
-				networkStreamer->broadcast(stream);
+				for (auto chip : *module)
+				{
+					retrieveChipData(board->getIndex(), opticalGroup->getIndex(), module->getIndex(), chip);
+					const std::vector<char> &stream = this->encodeStream();
+					this->incrementStreamPacketNumber();
+					networkStreamer->broadcast(stream);
+				}
 			}
 		}
 	}
@@ -352,11 +363,12 @@ public:
 	void decodeChipData(DetectorDataContainer &detectorContainer)
 	{
 		uint16_t boardId = this->fHeaderStream.fBoardId;
+		uint16_t opticalGroupId = this->fHeaderStream.template getHeaderInfo<HeaderId::OpticalGroupId>();
 		uint16_t moduleId = this->fHeaderStream.template getHeaderInfo<HeaderId::ModuleId>();
 		uint16_t chipId = this->fHeaderStream.template getHeaderInfo<HeaderId::ChipId>();
 
-		detectorContainer.at(boardId)->at(moduleId)->at(chipId)->setChannelContainer(this->fDataStream.fChannelContainer);
-		detectorContainer.at(boardId)->at(moduleId)->at(chipId)->setSummaryContainer(this->fDataStream.fChipSummaryContainer);
+		detectorContainer.at(boardId)->at(opticalGroupId)->at(moduleId)->at(chipId)->setChannelContainer(this->fDataStream.fChannelContainer);
+		detectorContainer.at(boardId)->at(opticalGroupId)->at(moduleId)->at(chipId)->setSummaryContainer(this->fDataStream.fChipSummaryContainer);
 		this->fDataStream.fChannelContainer = nullptr;
 		this->fDataStream.fChipSummaryContainer = nullptr;
 	}
@@ -377,9 +389,10 @@ public:
 	}
 
 protected:
-	void retrieveChipData(uint16_t boardId, uint16_t moduleId, ChipDataContainer *chip)
+	void retrieveChipData(uint16_t boardId, uint16_t opticalGroupId, uint16_t moduleId, ChipDataContainer *chip)
 	{
 		this->fHeaderStream.fBoardId = boardId;
+		this->fHeaderStream.template setHeaderInfo<HeaderId::OpticalGroupId>(opticalGroupId);
 		this->fHeaderStream.template setHeaderInfo<HeaderId::ModuleId>(moduleId);
 		this->fHeaderStream.template setHeaderInfo<HeaderId::ChipId>(chip->getIndex());
 		if (chip->getChannelContainer<T>() != nullptr)
@@ -569,38 +582,43 @@ public:
 };
 
 template <typename T, typename C, typename M, typename... I>
-class ModuleContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, I...>, DataStreamModuleContainer<T, C, M>>
+class ModuleContainerStream : public ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamModuleContainer<T, C, M>>
 {
 	enum HeaderId
 	{
+		OpticalGroupId,
 		ModuleId
 	};
 	static constexpr size_t getEnumSize() { return ModuleId + 1; }
 
 public:
-	ModuleContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, I...>, DataStreamModuleContainer<T, C, M>>(creatorName) { ; }
+	ModuleContainerStream(const std::string &creatorName) : ObjectStream<HeaderStreamContainer<uint16_t, uint16_t, I...>, DataStreamModuleContainer<T, C, M>>(creatorName) { ; }
 	~ModuleContainerStream() { ; }
 
 	void streamAndSendBoard(BoardDataContainer *board, TCPPublishServer *networkStreamer)
 	{
-		for (auto module : *board)
+		for (auto opticalGroup : *board)
 		{
-			retrieveModuleData(board->getIndex(), module);
-			const std::vector<char> &stream = this->encodeStream();
-			this->incrementStreamPacketNumber();
-			networkStreamer->broadcast(stream);
+			for (auto module : *opticalGroup)
+			{
+				retrieveModuleData(board->getIndex(), opticalGroup->getIndex(), module);
+				const std::vector<char> &stream = this->encodeStream();
+				this->incrementStreamPacketNumber();
+				networkStreamer->broadcast(stream);
+			}
 		}
 	}
 
 	void decodeModuleData(DetectorDataContainer &detectorContainer)
 	{
 		uint16_t boardId = this->fHeaderStream.fBoardId;
+		uint16_t opticalGroupId = this->fHeaderStream.template getHeaderInfo<HeaderId::OpticalGroupId>();
 		uint16_t moduleId = this->fHeaderStream.template getHeaderInfo<HeaderId::ModuleId>();
 
-		detectorContainer.at(boardId)->at(moduleId)->setSummaryContainer(this->fDataStream.fModuleSummaryContainer);
+		detectorContainer.at(boardId)->at(opticalGroupId)->at(moduleId)->setSummaryContainer(this->fDataStream.fModuleSummaryContainer);
 		this->fDataStream.fModuleSummaryContainer = nullptr;
 
-		for (auto chip : *detectorContainer.at(boardId)->at(moduleId))
+		for (auto chip : *detectorContainer.at(boardId)->at(opticalGroupId)->at(moduleId))
 		{
 			if (this->fDataStream.fContainerCarried.isChipContainerCarried())
 			{
@@ -631,9 +649,10 @@ public:
 	}
 
 protected:
-	void retrieveModuleData(uint16_t boardId, ModuleDataContainer *module)
+	void retrieveModuleData(uint16_t boardId, uint16_t opticalGroupId, ModuleDataContainer *module)
 	{
 		this->fHeaderStream.fBoardId = boardId;
+		this->fHeaderStream.template setHeaderInfo<HeaderId::OpticalGroupId>(opticalGroupId);
 		this->fHeaderStream.template setHeaderInfo<HeaderId::ModuleId>(module->getIndex());
 		this->fDataStream.fNumberOfChips = module->size();
 		if (module->getSummaryContainer<M, C>() != nullptr)
diff --git a/Utils/D19cCbc3Event.cc b/Utils/D19cCbc3Event.cc
index 4fd8eacc6..8fea1b6b4 100644
--- a/Utils/D19cCbc3Event.cc
+++ b/Utils/D19cCbc3Event.cc
@@ -31,19 +31,22 @@ namespace Ph2_HwInterface {
 
     void D19cCbc3Event::fillDataContainer(BoardDataContainer* boardContainer, const ChannelGroupBase *cTestChannelGroup)
     {
-        for(auto module: *boardContainer)
+        for(auto opticalGroup: *boardContainer)
     	{
-    		for(auto chip: *module)
-    		{
-                unsigned int i = 0;
-    			for(ChannelDataContainer<Occupancy>::iterator channel =  chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
-				{
-                    if(cTestChannelGroup->isChannelEnabled(i))
+            for(auto hybrid: *opticalGroup)
+            {
+                for(auto chip: *hybrid)
+                {
+                    unsigned int i = 0;
+                    for(ChannelDataContainer<Occupancy>::iterator channel =  chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
                     {
-    					channel->fOccupancy  += (float)privateDataBit ( module->getId(), chip->getId(), i);
+                        if(cTestChannelGroup->isChannelEnabled(i))
+                        {
+                            channel->fOccupancy  += (float)privateDataBit ( hybrid->getId(), chip->getId(), i);
+                        }
                     }
-				}
-    		}
+                }
+            }
     	}
     }
 
diff --git a/Utils/D19cCbc3EventZS.cc b/Utils/D19cCbc3EventZS.cc
index 8c7c10518..d2b9a8fc2 100644
--- a/Utils/D19cCbc3EventZS.cc
+++ b/Utils/D19cCbc3EventZS.cc
@@ -20,16 +20,19 @@ namespace Ph2_HwInterface
 {
   void D19cCbc3EventZS::fillDataContainer(BoardDataContainer* boardContainer, const ChannelGroupBase *cTestChannelGroup)
     {
-        for(auto module: *boardContainer)
+        for(auto opticalGroup : *boardContainer)
         {
-            for(auto chip: *module)
+            for(auto hybrid : *opticalGroup)
             {
-                unsigned int i = 0;
-                for(ChannelContainer<Occupancy>::iterator channel =  chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
+                for(auto chip : *hybrid)
                 {
-                    if(cTestChannelGroup->isChannelEnabled(i))
+                    unsigned int i = 0;
+                    for(ChannelContainer<Occupancy>::iterator channel =  chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
                     {
-                        channel->fOccupancy  += (float)DataBit ( module->getId(), chip->getId(), i);
+                        if(cTestChannelGroup->isChannelEnabled(i))
+                        {
+                            channel->fOccupancy  += (float)DataBit ( hybrid->getId(), chip->getId(), i);
+                        }
                     }
                 }
             }
diff --git a/Utils/D19cCic2Event.cc b/Utils/D19cCic2Event.cc
index 6761ad50d..c5b2b383d 100644
--- a/Utils/D19cCic2Event.cc
+++ b/Utils/D19cCic2Event.cc
@@ -33,28 +33,30 @@ namespace Ph2_HwInterface {
 
     void D19cCic2Event::fillDataContainer(BoardDataContainer* boardContainer, const ChannelGroupBase *cTestChannelGroup)
     {
-        for(auto module: *boardContainer)
+        for(auto opticalGroup : *boardContainer)
     	{
-            LOG (DEBUG) << BOLDBLUE << "Filling data container for module " << module->getId() << RESET;
-            for(auto chip: *module)
-    		{
-                std::vector<uint32_t> cHits = this->GetHits ( module->getId(), chip->getId() );
-                //LOG (DEBUG) << "\t.... " << +cHits.size() << " hits in chip." << RESET;
-                for( auto cHit : cHits ) 
+            for(auto hybrid : *opticalGroup)
+            {
+                LOG (DEBUG) << BOLDBLUE << "Filling data container for hybrid " << hybrid->getId() << RESET;
+                for(auto chip : *hybrid)
                 {
-                    if( cTestChannelGroup->isChannelEnabled(cHit)) 
+                    std::vector<uint32_t> cHits = this->GetHits ( hybrid->getId(), chip->getId() );
+                    //LOG (DEBUG) << "\t.... " << +cHits.size() << " hits in chip." << RESET;
+                    for( auto cHit : cHits ) 
                     {
-                        chip->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1.;
+                        if( cTestChannelGroup->isChannelEnabled(cHit)) 
+                        {
+                            chip->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1.;
+                        }
                     }
                 }
-    		}
+            }
     	}
     }
     void D19cCic2Event::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list )
     {
         fIsSparsified=pBoard->getSparsification();
         LOG (DEBUG) << BOLDBLUE << " Found " << +pBoard->fModuleVector.size() << " FE connected to this board.." << RESET;
-        auto cNHybrids = pBoard->fModuleVector.size(); 
         fEventHitList.clear();
         fEventStubList.clear();
         for( size_t cFeIndex=0; cFeIndex < N2SMODULES*2 ; cFeIndex++)
@@ -130,7 +132,6 @@ namespace Ph2_HwInterface {
             LOG (DEBUG) << BOLDBLUE << "\t.. FE Id from firmware " << +cFeId << " .. putting data in event list .. offset " << +cOffset << RESET;
             std::pair<uint16_t,uint16_t> cL1Information; 
             uint32_t cL1DataSize = (cL1Header & 0xFFF)*4;
-            uint32_t cFrameDelay = *(cIterator + 1) & 0xFFF; 
             cL1Information.first = ( *(cIterator + 2)  & 0x7FC000 ) >> 14;
             cL1Information.second = ( *(cIterator + 2)  & 0xFF800000 ) >> 23;
             LOG (DEBUG) << BOLDBLUE << "L1 counter for this event : " << +cL1Information.first << " . L1 data size is " << +(cL1DataSize) << " status " << std::bitset<9>(cL1Information.second) << RESET;
@@ -141,7 +142,6 @@ namespace Ph2_HwInterface {
                 // clusters/hit data first 
                 std::vector<std::bitset<CLUSTER_WORD_SIZE>> cL1Words(cNClusters, 0);
                 this->splitStream(list , cL1Words , cOffset+3 , cNClusters ); // split 32 bit words in std::vector of CLUSTER_WORD_SIZE bits
-                size_t cClusterId=0;
                 fEventHitList[cFeId].first = cL1Information;
                 fEventHitList[cFeId].second.clear();
                 for(auto cL1Word : cL1Words)
@@ -199,7 +199,6 @@ namespace Ph2_HwInterface {
             //LOG (DEBUG) << BOLDBLUE << "BxId for this event : " << +cStubInformation.first << " . Stub data size is " << +cStubDataSize << " status " << std::bitset<9>(cStubInformation.second) << " -- number of stubs in packet : " << +cNStubs << RESET;
             std::vector<std::bitset<STUB_WORD_SIZE>> cStubWords(cNStubs, 0);
             this->splitStream(list , cStubWords , cOffset + cL1DataSize + 2 , cNStubs ); // split 32 bit words in std::vector of STUB_WORD_SIZE bits
-            size_t cStubId=0;
             fEventStubList[cFeId].first = cStubInformation;
             fEventStubList[cFeId].second.clear();
             for(auto cStubWord : cStubWords)
@@ -555,7 +554,6 @@ namespace Ph2_HwInterface {
         const int FIRST_LINE_WIDTH = 22;
         const int LINE_WIDTH = 32;
         const int LAST_LINE_WIDTH = 8; 
-        uint8_t cFeId=0;
         //still need to work this out for sparsified data
         if(!fIsSparsified)
         {   
@@ -665,7 +663,6 @@ namespace Ph2_HwInterface {
     {
         uint32_t cEvtCount = this->GetEventCount();
         uint16_t cBunch = static_cast<uint16_t> (this->GetBunch() );
-        uint32_t cBeStatus = this->fBeStatus;
         SLinkEvent cEvent (EventType::VR, pBoard->getConditionDataSet()->getDebugMode(), FrontEndType::CBC3, cEvtCount, cBunch, SOURCE_ID );
         
         // // get link Ids 
diff --git a/Utils/D19cCicEvent.cc b/Utils/D19cCicEvent.cc
index 04453eff1..a859bc4fc 100644
--- a/Utils/D19cCicEvent.cc
+++ b/Utils/D19cCicEvent.cc
@@ -34,21 +34,24 @@ namespace Ph2_HwInterface {
 
     void D19cCicEvent::fillDataContainer(BoardDataContainer* boardContainer, const ChannelGroupBase *cTestChannelGroup)
     {
-        for(auto module: *boardContainer)
-    	{
-            LOG (DEBUG) << BOLDBLUE << "Filling data container for module " << module->getId() << RESET;
-            for(auto chip: *module)
-    		{
-                std::vector<uint32_t> cHits = this->GetHits ( module->getId(), chip->getId() );
-                LOG (DEBUG) << "\t.... " << +cHits.size() << " hits in chip." << RESET;
-                for( auto cHit : cHits ) 
+        for(auto opticalGroup : *boardContainer)
+        {
+            for(auto hybrid : *opticalGroup)
+            {
+                LOG (DEBUG) << BOLDBLUE << "Filling data container for hybrid " << hybrid->getId() << RESET;
+                for(auto chip: *hybrid)
                 {
-                    if( cTestChannelGroup->isChannelEnabled(cHit)) 
+                    std::vector<uint32_t> cHits = this->GetHits ( hybrid->getId(), chip->getId() );
+                    LOG (DEBUG) << "\t.... " << +cHits.size() << " hits in chip." << RESET;
+                    for( auto cHit : cHits ) 
                     {
-                        chip->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1.;
+                        if( cTestChannelGroup->isChannelEnabled(cHit)) 
+                        {
+                            chip->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1.;
+                        }
                     }
                 }
-    		}
+            }
     	}
     }
     // void D19cCicEvent::splitStream( std::vector<uint32_t> pData, const size_t pLength ) 
diff --git a/Utils/D19cSSAEvent.cc b/Utils/D19cSSAEvent.cc
index b1dcfd32c..02b1502e3 100644
--- a/Utils/D19cSSAEvent.cc
+++ b/Utils/D19cSSAEvent.cc
@@ -16,16 +16,19 @@ D19cSSAEvent::D19cSSAEvent(const BeBoard *pBoard, uint32_t pNSSA, uint32_t pNFe,
 }
 void D19cSSAEvent::fillDataContainer(BoardDataContainer *boardContainer, const ChannelGroupBase *cTestChannelGroup)
 {
-	for (auto module : *boardContainer)
+	for(auto opticalGroup : *boardContainer)
 	{
-		for (auto chip : *module)
+		for(auto hybrid : *opticalGroup)
 		{
-			unsigned int i = 0;
-			for (ChannelDataContainer<Occupancy>::iterator channel = chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
+			for (auto chip : *hybrid)
 			{
-				if (cTestChannelGroup->isChannelEnabled(i))
+				unsigned int i = 0;
+				for (ChannelDataContainer<Occupancy>::iterator channel = chip->begin<Occupancy>(); channel != chip->end<Occupancy>(); channel++, i++)
 				{
-					channel->fOccupancy += (float)privateDataBit(module->getId(), chip->getId(), i);
+					if (cTestChannelGroup->isChannelEnabled(i))
+					{
+						channel->fOccupancy += (float)privateDataBit(hybrid->getId(), chip->getId(), i);
+					}
 				}
 			}
 		}
diff --git a/Utils/DataContainer.h b/Utils/DataContainer.h
index 14ed88c9a..9d28d149d 100644
--- a/Utils/DataContainer.h
+++ b/Utils/DataContainer.h
@@ -489,12 +489,12 @@ public:
 private:
 };
 
-class BoardDataContainer : public DataContainer<ModuleDataContainer>
+class OpticalGroupDataContainer : public DataContainer<ModuleDataContainer>
 {
 public:
-	BoardDataContainer(uint16_t id) : DataContainer<ModuleDataContainer>(id){}
-	BoardDataContainer(const BoardDataContainer&) = delete;
-	BoardDataContainer(BoardDataContainer&& theCopyContainer)
+	OpticalGroupDataContainer(uint16_t id) : DataContainer<ModuleDataContainer>(id){}
+	OpticalGroupDataContainer(const OpticalGroupDataContainer&) = delete;
+	OpticalGroupDataContainer(OpticalGroupDataContainer&& theCopyContainer)
 	: DataContainer<ModuleDataContainer>(std::move(theCopyContainer))
 	{}
 
@@ -504,6 +504,21 @@ public:
 private:
 };
 
+class BoardDataContainer : public DataContainer<OpticalGroupDataContainer>
+{
+public:
+	BoardDataContainer(uint16_t id) : DataContainer<OpticalGroupDataContainer>(id){}
+	BoardDataContainer(const BoardDataContainer&) = delete;
+	BoardDataContainer(BoardDataContainer&& theCopyContainer)
+	: DataContainer<OpticalGroupDataContainer>(std::move(theCopyContainer))
+	{}
+
+	template <class T>
+	T*               addOpticalGroupDataContainer(uint16_t id, T* opticalGroup){return static_cast<T*>(DataContainer<OpticalGroupDataContainer>::addObject(id, opticalGroup));}
+	OpticalGroupDataContainer* addOpticalGroupDataContainer(uint16_t id)                 {return DataContainer<OpticalGroupDataContainer>::addObject(id, new OpticalGroupDataContainer(id));}
+private:
+};
+
 class DetectorDataContainer : public DataContainer<BoardDataContainer>
 {
 public:
diff --git a/Utils/Visitor.h b/Utils/Visitor.h
index 64d4e1230..5330ed479 100644
--- a/Utils/Visitor.h
+++ b/Utils/Visitor.h
@@ -27,6 +27,7 @@ namespace GUI
 namespace Ph2_HwDescription
 {
 	class BeBoard;
+	class OpticalGroup;
 	class Module;
 	class Chip;
     class ReadoutChip;
@@ -59,6 +60,11 @@ class HwDescriptionVisitor
 	 * \param pBeBoard
 	 */
 	virtual void visitBeBoard( Ph2_HwDescription::BeBoard& pBeBoard ) {}
+	/*!
+	 * \brief Visitor for OpticalGroup Class
+	 * \param pOpticalGroup
+	 */
+	virtual void visitOpticalGroup( Ph2_HwDescription::OpticalGroup& pOpticalGroup ) {}
 	/*!
 	 * \brief Visitor for Module Class
 	 * \param pModule
diff --git a/settings/D19CDescription.xml b/settings/D19CDescription.xml
index c1198b258..586a68115 100755
--- a/settings/D19CDescription.xml
+++ b/settings/D19CDescription.xml
@@ -4,36 +4,39 @@
     <connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.0.7:50001" address_table="file://settings/address_tables/uDTC_OT_address_table.xml" />
 
     <CDCE configure="0" clockRate="120"/>
-       
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <Global>
-            <Settings threshold="500" latency="29"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFA" channelgroup="0" delay="0" groundothers="0"/>
-            <ClusterStub clusterwidth="4" ptwidth="4" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00011" pipelogic="0" stublogic="0" or254="0" tpgclock="0" testclock="0" dll="11"/>
-            <ChannelMask disable=""/>
-        </Global>
+    
+    <OpticalGroup Id="0" FMCId="0" >
+        
+        <Module FeId="0" ModuleId="0" Status="1">
+            <Global>
+                <Settings threshold="500" latency="29"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFA" channelgroup="0" delay="0" groundothers="0"/>
+                <ClusterStub clusterwidth="4" ptwidth="4" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00011" pipelogic="0" stublogic="0" or254="0" tpgclock="0" testclock="0" dll="11"/>
+                <ChannelMask disable=""/>
+            </Global>
 
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <!-- <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" /> -->
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <!-- <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" /> -->
 
-        <!-- <CBC_Files path="./Results/FEH_2S_xxxx_Electron_15-03-20_13h44m46/" />
-        <CBC Id="0" configfile="BE0_FE0_Chip0.txt" />
-        <CBC Id="1" configfile="BE0_FE0_Chip1.txt" />
-        <CBC Id="2" configfile="BE0_FE0_Chip2.txt" />
-        <CBC Id="3" configfile="BE0_FE0_Chip3.txt" />
-        <CBC Id="4" configfile="BE0_FE0_Chip4.txt" />
-        <CBC Id="5" configfile="BE0_FE0_Chip5.txt" />
-        <CBC Id="6" configfile="BE0_FE0_Chip6.txt" />
-        <CBC Id="7" configfile="BE0_FE0_Chip7.txt" /> -->
-    </Module>
+            <!-- <CBC_Files path="./Results/FEH_2S_xxxx_Electron_15-03-20_13h44m46/" />
+            <CBC Id="0" configfile="BE0_FE0_Chip0.txt" />
+            <CBC Id="1" configfile="BE0_FE0_Chip1.txt" />
+            <CBC Id="2" configfile="BE0_FE0_Chip2.txt" />
+            <CBC Id="3" configfile="BE0_FE0_Chip3.txt" />
+            <CBC Id="4" configfile="BE0_FE0_Chip4.txt" />
+            <CBC Id="5" configfile="BE0_FE0_Chip5.txt" />
+            <CBC Id="6" configfile="BE0_FE0_Chip6.txt" />
+            <CBC Id="7" configfile="BE0_FE0_Chip7.txt" /> -->
+        </Module>
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
-- 
GitLab


From e5a875ac47fe23b4bb44efbdeacb1ca11db94c59 Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Fri, 3 Apr 2020 15:58:30 -0500
Subject: [PATCH 2/9] Added OpticalReadout class, not working

---
 HWDescription/OpticalGroup.cc | 36 ++++++++++++++++
 HWDescription/OpticalGroup.h  | 79 +++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 HWDescription/OpticalGroup.cc
 create mode 100644 HWDescription/OpticalGroup.h

diff --git a/HWDescription/OpticalGroup.cc b/HWDescription/OpticalGroup.cc
new file mode 100644
index 000000000..a15b34e7b
--- /dev/null
+++ b/HWDescription/OpticalGroup.cc
@@ -0,0 +1,36 @@
+/*!
+  Filename :                              OpticalGroup.cc
+  Content :                               OpticalGroup Description class
+  Programmer :                    Lorenzo BIDEGAIN
+  Version :               1.0
+  Date of Creation :              25/06/14
+  Support :                               mail to : lorenzo.bidegain@gmail.com
+*/
+
+#include "OpticalGroup.h"
+
+namespace Ph2_HwDescription
+{
+  // Default C'tor
+  OpticalGroup::OpticalGroup()
+    : FrontEndDescription( )
+    , OpticalGroupContainer    (0)
+    , fOpticalGroupId          (0)
+  {
+  }
+
+  OpticalGroup::OpticalGroup (const FrontEndDescription& pFeDesc, uint8_t pOpticalGroupId)
+    : FrontEndDescription(pFeDesc  )
+    , OpticalGroupContainer    (pOpticalGroupId)
+    , fOpticalGroupId          (pOpticalGroupId)
+  {
+  }
+
+  OpticalGroup::OpticalGroup (uint8_t pBeId, uint8_t pFMCId, uint8_t pOpticalGroupId)
+    : FrontEndDescription(pBeId, pFMCId, 0)
+    , OpticalGroupContainer   (pOpticalGroupId)
+    , fOpticalGroupId         (pOpticalGroupId)
+  {
+  }
+
+}
diff --git a/HWDescription/OpticalGroup.h b/HWDescription/OpticalGroup.h
new file mode 100644
index 000000000..1994b0aa1
--- /dev/null
+++ b/HWDescription/OpticalGroup.h
@@ -0,0 +1,79 @@
+/*!
+
+        \file                           OpticalGroup.h
+        \brief                          OpticalGroup Description class
+        \author                         Fabio Ravera
+        \version                        1.0
+        \date                           02/04/20
+        Support :                       mail to : fabio.ravera@cern.ch
+
+ */
+
+#ifndef OpticalGroup_h__
+#define OpticalGroup_h__
+
+#include "FrontEndDescription.h"
+// #include "RD53.h"
+#include "Module.h"
+#include "../Utils/Visitor.h"
+#include <vector>
+#include "../Utils/Container.h"
+
+// FE Hybrid HW Description Class
+
+
+/*!
+ * \namespace Ph2_HwDescription
+ * \brief Namespace regrouping all the hardware description
+ */
+namespace Ph2_HwDescription {
+
+    /*!
+     * \class OpticalGroup
+     * \brief handles a vector of Chip which are connected to the OpticalGroup
+     */
+    class OpticalGroup : public FrontEndDescription, public OpticalGroupContainer
+    {
+
+      public:
+
+        // C'tors take FrontEndDescription or hierachy of connection
+        OpticalGroup (const FrontEndDescription& pFeDesc, uint8_t pOpticalGroupId );
+        OpticalGroup (uint8_t pBeId, uint8_t pFMCId, uint8_t pOpticalGroupId );
+
+        // Default C'tor
+        OpticalGroup();
+
+        // D'tor
+        ~OpticalGroup()
+        {
+        };
+
+        /*!
+         * \brief acceptor method for HwDescriptionVisitor
+         * \param pVisitor
+         */
+        void accept ( HwDescriptionVisitor& pVisitor )
+        {
+            pVisitor.visitOpticalGroup ( *this );
+
+            for ( auto* cHybrid : *this )
+                static_cast<Module*>(cHybrid)->accept ( pVisitor );
+        }
+
+        uint8_t getOpticalGroupId() const
+        {
+            return fOpticalGroupId;
+        };
+
+        void setOpticalGroupId ( uint8_t pOpticalGroupId )
+        {
+            fOpticalGroupId = pOpticalGroupId;
+        };
+
+      protected:
+        uint8_t fOpticalGroupId;
+    };
+}
+
+#endif
-- 
GitLab


From c28e86907199a3a5d86dcc3aa349018d1497026a Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Fri, 3 Apr 2020 16:34:47 -0500
Subject: [PATCH 3/9] Merged with official Repo

---
 DQMUtils/DQMHistogramBase.h       |  69 +++----
 DQMUtils/DQMHistogramPedeNoise.cc | 309 ++++++++++++++++--------------
 2 files changed, 197 insertions(+), 181 deletions(-)

diff --git a/DQMUtils/DQMHistogramBase.h b/DQMUtils/DQMHistogramBase.h
index 0a90ef6fe..8259649ee 100644
--- a/DQMUtils/DQMHistogramBase.h
+++ b/DQMUtils/DQMHistogramBase.h
@@ -96,40 +96,41 @@ class DQMHistogramBase
                bool isNoise                  = false)
     {
       for (auto cBoard : HistDataContainer)
-        for (auto cModule : *cBoard)
-          for (auto cChip : *cModule)
-            {
-              TCanvas* canvas = cChip->getSummary<CanvasContainer<Hist>>().fCanvas;
-              Hist*    hist   = cChip->getSummary<CanvasContainer<Hist>>().fTheHistogram;
-
-              canvas->cd();
-              hist->Draw(opt);
-              canvas->Modified();
-              canvas->Update();
-
-              if (electronAxis == true)
-                {
-                  TPad* myPad = static_cast<TPad*>(canvas->GetPad(0));
-                  myPad->SetTopMargin(0.16);
-
-                  axes.emplace_back(new TGaxis(myPad->GetUxmin(), myPad->GetUymax(), myPad->GetUxmax(), myPad->GetUymax(),
-                                               RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(1),isNoise),
-                                               RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(hist->GetXaxis()->GetNbins()),isNoise), 510, "-"));
-                  axes.back()->SetTitle(electronAxisTitle);
-                  axes.back()->SetTitleOffset(1.2);
-                  axes.back()->SetTitleSize(0.035);
-                  axes.back()->SetTitleFont(40);
-                  axes.back()->SetLabelOffset(0.001);
-                  axes.back()->SetLabelSize(0.035);
-                  axes.back()->SetLabelFont(42);
-                  axes.back()->SetLabelColor(kRed);
-                  axes.back()->SetLineColor(kRed);
-                  axes.back()->Draw();
-
-                  canvas->Modified();
-                  canvas->Update();
-                }
-            }
+        for (auto cOpticalGroup : *cBoard)
+          for (auto cHybrid : *cOpticalGroup)
+            for (auto cChip : *cHybrid)
+              {
+                TCanvas* canvas = cChip->getSummary<CanvasContainer<Hist>>().fCanvas;
+                Hist*    hist   = cChip->getSummary<CanvasContainer<Hist>>().fTheHistogram;
+
+                canvas->cd();
+                hist->Draw(opt);
+                canvas->Modified();
+                canvas->Update();
+
+                if (electronAxis == true)
+                  {
+                    TPad* myPad = static_cast<TPad*>(canvas->GetPad(0));
+                    myPad->SetTopMargin(0.16);
+
+                    axes.emplace_back(new TGaxis(myPad->GetUxmin(), myPad->GetUymax(), myPad->GetUxmax(), myPad->GetUymax(),
+                                                RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(1),isNoise),
+                                                RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(hist->GetXaxis()->GetNbins()),isNoise), 510, "-"));
+                    axes.back()->SetTitle(electronAxisTitle);
+                    axes.back()->SetTitleOffset(1.2);
+                    axes.back()->SetTitleSize(0.035);
+                    axes.back()->SetTitleFont(40);
+                    axes.back()->SetLabelOffset(0.001);
+                    axes.back()->SetLabelSize(0.035);
+                    axes.back()->SetLabelFont(42);
+                    axes.back()->SetLabelColor(kRed);
+                    axes.back()->SetLineColor(kRed);
+                    axes.back()->Draw();
+
+                    canvas->Modified();
+                    canvas->Update();
+                  }
+              }
     }
 
   double findValueInSettings (const Ph2_System::SettingsMap& settingsMap, const std::string name, double defaultValue = 0.) const
diff --git a/DQMUtils/DQMHistogramPedeNoise.cc b/DQMUtils/DQMHistogramPedeNoise.cc
index be53f67a3..f3ce2559b 100644
--- a/DQMUtils/DQMHistogramPedeNoise.cc
+++ b/DQMUtils/DQMHistogramPedeNoise.cc
@@ -149,63 +149,66 @@ void DQMHistogramPedeNoise::process()
 
     for(auto board : fDetectorPedestalHistograms)
     {
-        
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            TCanvas *cValidation = new TCanvas(("Validation_module_" + std::to_string(module->getId())).data(),("Validation module " + std::to_string(module->getId())).data(),   0, 0, 650, fPlotSCurves ? 900 : 650 );
-            TCanvas *cPedeNoise  = new TCanvas(("PedeNoise_module_"  + std::to_string(module->getId())).data(),("PedeNoise module "  + std::to_string(module->getId())).data(), 670, 0, 650, 650 );
-
-            cValidation->Divide(module->size(),fPlotSCurves ? 3 : 2);
-            cPedeNoise->Divide(module->size(),2);
-
-            for(auto chip: *module)
+        
+            for(auto hybrid : *opticalGroup)
             {
-                cValidation->cd(chip->getIndex()+1 +module->size()*0);
-                TH1F *validationHistogram = fDetectorValidationHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                validationHistogram->SetStats(false);
-                validationHistogram->DrawCopy();
-                gPad->SetLogy();
-
-                cValidation->cd(chip->getIndex()+1 +module->size()*1);
-                TH1F *chipStripNoiseEvenHistogram = fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipStripNoiseOddHistogram  = fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                chipStripNoiseEvenHistogram->SetLineColor(kBlue);
-                chipStripNoiseEvenHistogram->SetMaximum (10);
-                chipStripNoiseEvenHistogram->SetMinimum (0);
-                chipStripNoiseOddHistogram->SetLineColor(kRed);
-                chipStripNoiseOddHistogram->SetMaximum (10);
-                chipStripNoiseOddHistogram->SetMinimum (0);
-                chipStripNoiseEvenHistogram->SetStats(false);
-                chipStripNoiseOddHistogram->SetStats(false);
-                chipStripNoiseEvenHistogram->DrawCopy();
-                chipStripNoiseOddHistogram->DrawCopy("same");
-
-                cPedeNoise->cd(chip->getIndex()+1 +module->size()*1);
-                fDetectorPedestalHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->DrawCopy();
-                
-                cPedeNoise->cd(chip->getIndex()+1 +module->size()*0);
-                fDetectorNoiseHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->DrawCopy();
+                TCanvas *cValidation = new TCanvas(("Validation_hybrid_" + std::to_string(hybrid->getId())).data(),("Validation hybrid " + std::to_string(hybrid->getId())).data(),   0, 0, 650, fPlotSCurves ? 900 : 650 );
+                TCanvas *cPedeNoise  = new TCanvas(("PedeNoise_hybrid_"  + std::to_string(hybrid->getId())).data(),("PedeNoise hybrid "  + std::to_string(hybrid->getId())).data(), 670, 0, 650, 650 );
+
+                cValidation->Divide(hybrid->size(),fPlotSCurves ? 3 : 2);
+                cPedeNoise->Divide(hybrid->size(),2);
 
-                if(fPlotSCurves)
+                for(auto chip: *hybrid)
                 {
-                    TH2F* cSCurveHist = fDetectorSCurveHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH2F>>().fTheHistogram;
-                    TH1D* cTmp = cSCurveHist->ProjectionY();
-                    cSCurveHist->GetYaxis()->SetRangeUser ( cTmp->GetBinCenter (cTmp->FindFirstBinAbove (0) ) - 10, cTmp->GetBinCenter (cTmp->FindLastBinAbove (0.99) ) + 10 );
-                    delete cTmp;
-                    cValidation->cd(chip->getIndex()+1 +module->size()*2);
-                    cSCurveHist->SetStats(false);
-                    cSCurveHist->DrawCopy("colz");
-                }
+                    cValidation->cd(chip->getIndex()+1 +hybrid->size()*0);
+                    TH1F *validationHistogram = fDetectorValidationHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    validationHistogram->SetStats(false);
+                    validationHistogram->DrawCopy();
+                    gPad->SetLogy();
+
+                    cValidation->cd(chip->getIndex()+1 +hybrid->size()*1);
+                    TH1F *chipStripNoiseEvenHistogram = fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipStripNoiseOddHistogram  = fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    chipStripNoiseEvenHistogram->SetLineColor(kBlue);
+                    chipStripNoiseEvenHistogram->SetMaximum (10);
+                    chipStripNoiseEvenHistogram->SetMinimum (0);
+                    chipStripNoiseOddHistogram->SetLineColor(kRed);
+                    chipStripNoiseOddHistogram->SetMaximum (10);
+                    chipStripNoiseOddHistogram->SetMinimum (0);
+                    chipStripNoiseEvenHistogram->SetStats(false);
+                    chipStripNoiseOddHistogram->SetStats(false);
+                    chipStripNoiseEvenHistogram->DrawCopy();
+                    chipStripNoiseOddHistogram->DrawCopy("same");
+
+                    cPedeNoise->cd(chip->getIndex()+1 +hybrid->size()*1);
+                    fDetectorPedestalHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->DrawCopy();
+                    
+                    cPedeNoise->cd(chip->getIndex()+1 +hybrid->size()*0);
+                    fDetectorNoiseHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->DrawCopy();
 
-                fDetectorStripNoiseHistograms    .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
-                fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
-                fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
+                    if(fPlotSCurves)
+                    {
+                        TH2F* cSCurveHist = fDetectorSCurveHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH2F>>().fTheHistogram;
+                        TH1D* cTmp = cSCurveHist->ProjectionY();
+                        cSCurveHist->GetYaxis()->SetRangeUser ( cTmp->GetBinCenter (cTmp->FindFirstBinAbove (0) ) - 10, cTmp->GetBinCenter (cTmp->FindLastBinAbove (0.99) ) + 10 );
+                        delete cTmp;
+                        cValidation->cd(chip->getIndex()+1 +hybrid->size()*2);
+                        cSCurveHist->SetStats(false);
+                        cSCurveHist->DrawCopy("colz");
+                    }
 
-            }
+                    fDetectorStripNoiseHistograms    .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
+                    fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
+                    fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,10.);
 
-            fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(module->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetXaxis()->SetRangeUser(-0.5, NCHANNELS*module->size() - 0.5);
-            fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(module->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,15.);
-        
+                }
+
+                fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetXaxis()->SetRangeUser(-0.5, NCHANNELS*hybrid->size() - 0.5);
+                fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram->GetYaxis()->SetRangeUser(0.,15.);
+            
+            }
         }
     }
 }
@@ -221,19 +224,22 @@ void DQMHistogramPedeNoise::fillValidationPlots(DetectorDataContainer &theOccupa
 {
     for(auto board : theOccupancy)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            // std::cout << __PRETTY_FUNCTION__ << " The Module Occupancy = " << module->getSummary<Occupancy,Occupancy>().fOccupancy << std::endl;
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
-                TH1F *chipValidationHistogram = fDetectorValidationHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                uint channelBin=1;
-
-                if(chip->getChannelContainer<Occupancy>() == nullptr ) continue;
-                for(auto channel : *chip->getChannelContainer<Occupancy>())
+                // std::cout << __PRETTY_FUNCTION__ << " The Module Occupancy = " << hybrid->getSummary<Occupancy,Occupancy>().fOccupancy << std::endl;
+                for(auto chip: *hybrid)
                 {
-                    chipValidationHistogram->SetBinContent(channelBin  ,channel.fOccupancy     );
-                    chipValidationHistogram->SetBinError  (channelBin++,channel.fOccupancyError);
+                    TH1F *chipValidationHistogram = fDetectorValidationHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    uint channelBin=1;
+
+                    if(chip->getChannelContainer<Occupancy>() == nullptr ) continue;
+                    for(auto channel : *chip->getChannelContainer<Occupancy>())
+                    {
+                        chipValidationHistogram->SetBinContent(channelBin  ,channel.fOccupancy     );
+                        chipValidationHistogram->SetBinError  (channelBin++,channel.fOccupancyError);
+                    }
                 }
             }
         }
@@ -245,47 +251,50 @@ void DQMHistogramPedeNoise::fillPedestalAndNoisePlots(DetectorDataContainer &the
 {
     for(auto board : thePedestalAndNoise)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            TH1F *moduleNoiseHistogram      = fDetectorModuleNoiseHistograms     .at(board->getIndex())->at(module->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-            TH1F *moduleStripNoiseHistogram = fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(module->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-            
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
-                TH1F *chipPedestalHistogram       = fDetectorPedestalHistograms      .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipNoiseHistogram          = fDetectorNoiseHistograms         .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipStripNoiseHistogram     = fDetectorStripNoiseHistograms    .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipStripPedestalHistogram  = fDetectorStripPedestalHistograms .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipStripNoiseEvenHistogram = fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                TH1F *chipStripNoiseOddHistogram  = fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-
-                if(chip->getChannelContainer<ThresholdAndNoise>() == nullptr ) continue;
-                uint8_t channelNumber = 0;
-                for(auto channel : *chip->getChannelContainer<ThresholdAndNoise>())
+                TH1F *hybridNoiseHistogram      = fDetectorModuleNoiseHistograms     .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                TH1F *hybridStripNoiseHistogram = fDetectorModuleStripNoiseHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                
+                for(auto chip: *hybrid)
                 {
-                    chipPedestalHistogram->Fill(channel.fThreshold);
-                    chipNoiseHistogram->Fill(channel.fNoise);
-                    moduleNoiseHistogram->Fill(channel.fNoise);
-
-                    if ( ( int (channelNumber) % 2 ) == 0 )
-                    {
-                        chipStripNoiseEvenHistogram->SetBinContent( int ( channelNumber / 2 ) + 1, channel.fNoise     );
-                        chipStripNoiseEvenHistogram->SetBinError  ( int ( channelNumber / 2 ) + 1, channel.fNoiseError);
-                    }
-                    else
+                    TH1F *chipPedestalHistogram       = fDetectorPedestalHistograms      .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipNoiseHistogram          = fDetectorNoiseHistograms         .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipStripNoiseHistogram     = fDetectorStripNoiseHistograms    .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipStripPedestalHistogram  = fDetectorStripPedestalHistograms .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipStripNoiseEvenHistogram = fDetectorStripNoiseEvenHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    TH1F *chipStripNoiseOddHistogram  = fDetectorStripNoiseOddHistograms .at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+
+                    if(chip->getChannelContainer<ThresholdAndNoise>() == nullptr ) continue;
+                    uint8_t channelNumber = 0;
+                    for(auto channel : *chip->getChannelContainer<ThresholdAndNoise>())
                     {
-                        chipStripNoiseOddHistogram->SetBinContent( int ( channelNumber / 2 ) + 1, channel.fNoise     );
-                        chipStripNoiseOddHistogram->SetBinError  ( int ( channelNumber / 2 ) + 1, channel.fNoiseError);
-                    }
+                        chipPedestalHistogram->Fill(channel.fThreshold);
+                        chipNoiseHistogram->Fill(channel.fNoise);
+                        hybridNoiseHistogram->Fill(channel.fNoise);
+
+                        if ( ( int (channelNumber) % 2 ) == 0 )
+                        {
+                            chipStripNoiseEvenHistogram->SetBinContent( int ( channelNumber / 2 ) + 1, channel.fNoise     );
+                            chipStripNoiseEvenHistogram->SetBinError  ( int ( channelNumber / 2 ) + 1, channel.fNoiseError);
+                        }
+                        else
+                        {
+                            chipStripNoiseOddHistogram->SetBinContent( int ( channelNumber / 2 ) + 1, channel.fNoise     );
+                            chipStripNoiseOddHistogram->SetBinError  ( int ( channelNumber / 2 ) + 1, channel.fNoiseError);
+                        }
 
-                    chipStripNoiseHistogram   ->SetBinContent(channelNumber + 1                               , channel.fNoise        );
-                    chipStripNoiseHistogram   ->SetBinError  (channelNumber + 1                               , channel.fNoiseError   );
-                    chipStripPedestalHistogram->SetBinContent(channelNumber + 1                               , channel.fThreshold     );
-                    chipStripPedestalHistogram->SetBinError  (channelNumber + 1                               , channel.fThresholdError);
-                    moduleStripNoiseHistogram ->SetBinContent(NCHANNELS * chip->getIndex() + channelNumber + 1, channel.fNoise         );
-                    moduleStripNoiseHistogram ->SetBinError  (NCHANNELS * chip->getIndex() + channelNumber + 1, channel.fNoiseError    );
+                        chipStripNoiseHistogram   ->SetBinContent(channelNumber + 1                               , channel.fNoise        );
+                        chipStripNoiseHistogram   ->SetBinError  (channelNumber + 1                               , channel.fNoiseError   );
+                        chipStripPedestalHistogram->SetBinContent(channelNumber + 1                               , channel.fThreshold     );
+                        chipStripPedestalHistogram->SetBinError  (channelNumber + 1                               , channel.fThresholdError);
+                        hybridStripNoiseHistogram ->SetBinContent(NCHANNELS * chip->getIndex() + channelNumber + 1, channel.fNoise         );
+                        hybridStripNoiseHistogram ->SetBinError  (NCHANNELS * chip->getIndex() + channelNumber + 1, channel.fNoiseError    );
 
-                    ++channelNumber;
+                        ++channelNumber;
+                    }
                 }
             }
         }
@@ -298,28 +307,31 @@ void DQMHistogramPedeNoise::fillSCurvePlots(uint16_t vcthr, DetectorDataContaine
     
     for ( auto board : fSCurveOccupancy )
     {
-        for ( auto module : *board )
+        for(auto opticalGroup : *board)
         {
-            for ( auto chip : *module )
+            for(auto hybrid: *opticalGroup)
             {
-                TH2F *chipSCurve = fDetectorSCurveHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH2F>>().fTheHistogram;
-    
-                if(chip->getChannelContainer<ThresholdAndNoise>() == nullptr ) continue;
-                uint8_t channelNumber = 0;
-                for(auto channel : *chip->getChannelContainer<Occupancy>())
+                for ( auto chip : *hybrid )
                 {
-                    float tmpOccupancy      = channel.fOccupancy     ;
-                    float tmpOccupancyError = channel.fOccupancyError;
-                    chipSCurve->SetBinContent(channelNumber+1, vcthr+1, tmpOccupancy     );
-                    chipSCurve->SetBinError  (channelNumber+1, vcthr+1, tmpOccupancyError);
-
-                    if(fFitSCurves)
+                    TH2F *chipSCurve = fDetectorSCurveHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH2F>>().fTheHistogram;
+        
+                    if(chip->getChannelContainer<ThresholdAndNoise>() == nullptr ) continue;
+                    uint8_t channelNumber = 0;
+                    for(auto channel : *chip->getChannelContainer<Occupancy>())
                     {
-                        TH1F *channelSCurve = fDetectorChannelSCurveHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<HistContainer<TH1F>>(channelNumber).fTheHistogram;
-                        channelSCurve->SetBinContent(vcthr+1, tmpOccupancy     );
-                        channelSCurve->SetBinError  (vcthr+1, tmpOccupancyError);
+                        float tmpOccupancy      = channel.fOccupancy     ;
+                        float tmpOccupancyError = channel.fOccupancyError;
+                        chipSCurve->SetBinContent(channelNumber+1, vcthr+1, tmpOccupancy     );
+                        chipSCurve->SetBinError  (channelNumber+1, vcthr+1, tmpOccupancyError);
+
+                        if(fFitSCurves)
+                        {
+                            TH1F *channelSCurve = fDetectorChannelSCurveHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<HistContainer<TH1F>>(channelNumber).fTheHistogram;
+                            channelSCurve->SetBinContent(vcthr+1, tmpOccupancy     );
+                            channelSCurve->SetBinError  (vcthr+1, tmpOccupancyError);
+                        }
+                        ++channelNumber;
                     }
-                    ++channelNumber;
                 }
             }
         }
@@ -332,53 +344,56 @@ void DQMHistogramPedeNoise::fitSCurves ()
 
     for(auto board : fDetectorChannelSCurveHistograms)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
+                for(auto chip: *hybrid)
+                {
 
-                ChipDataContainer *theChipThresholdAndNoise = fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex());
+                    ChipDataContainer *theChipThresholdAndNoise = fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex());
 
-                for (uint32_t cChannel = 0; cChannel < NCHANNELS; cChannel++)
-                {
-                    TH1F *channelSCurve = chip->getChannel<HistContainer<TH1F>>(cChannel).fTheHistogram;
-                    
-                    float cFirstNon0 ( 0 );
-                    float cFirst1 ( 0 );
-                    
-                    for ( Int_t cBin = 1; cBin < channelSCurve->GetNbinsX() - 1; cBin++ )
+                    for (uint32_t cChannel = 0; cChannel < NCHANNELS; cChannel++)
                     {
-                        double cContent = channelSCurve->GetBinContent ( cBin );
-
-                        if ( !cFirstNon0 )
-                        {
-                            if ( cContent ) cFirstNon0 = channelSCurve->GetBinCenter ( cBin );
-                        }
-                        else if ( cContent > 0.85 )
+                        TH1F *channelSCurve = chip->getChannel<HistContainer<TH1F>>(cChannel).fTheHistogram;
+                        
+                        float cFirstNon0 ( 0 );
+                        float cFirst1 ( 0 );
+                        
+                        for ( Int_t cBin = 1; cBin < channelSCurve->GetNbinsX() - 1; cBin++ )
                         {
-                            cFirst1 = channelSCurve->GetBinCenter ( cBin );
-                            break;
+                            double cContent = channelSCurve->GetBinContent ( cBin );
+
+                            if ( !cFirstNon0 )
+                            {
+                                if ( cContent ) cFirstNon0 = channelSCurve->GetBinCenter ( cBin );
+                            }
+                            else if ( cContent > 0.85 )
+                            {
+                                cFirst1 = channelSCurve->GetBinCenter ( cBin );
+                                break;
+                            }
                         }
-                    }
 
-                    TF1 *cFit = new TF1 ( "SCurveFit", MyErf, cFirstNon0 - 10, cFirst1 + 10, 2 );
-                    
-                    // Get rough midpoint & width
-                    double cMid = ( cFirst1 + cFirstNon0 ) * 0.5;
-                    double cWidth = ( cFirst1 - cFirstNon0 ) * 0.5;
+                        TF1 *cFit = new TF1 ( "SCurveFit", MyErf, cFirstNon0 - 10, cFirst1 + 10, 2 );
+                        
+                        // Get rough midpoint & width
+                        double cMid = ( cFirst1 + cFirstNon0 ) * 0.5;
+                        double cWidth = ( cFirst1 - cFirstNon0 ) * 0.5;
 
-                    cFit->SetParameter ( 0, cMid );
-                    cFit->SetParameter ( 1, cWidth );
+                        cFit->SetParameter ( 0, cMid );
+                        cFit->SetParameter ( 1, cWidth );
 
-                    // Fit
-                    channelSCurve->Fit ( cFit, "RQ+0" );
+                        // Fit
+                        channelSCurve->Fit ( cFit, "RQ+0" );
 
-                    theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fThreshold      = cFit->GetParameter(0);
-                    theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fNoise          = cFit->GetParameter(1);
-                    theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fThresholdError = cFit->GetParError (0);
-                    theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fNoiseError     = cFit->GetParError (1);
+                        theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fThreshold      = cFit->GetParameter(0);
+                        theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fNoise          = cFit->GetParameter(1);
+                        theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fThresholdError = cFit->GetParError (0);
+                        theChipThresholdAndNoise->getChannel<ThresholdAndNoise>(cChannel).fNoiseError     = cFit->GetParError (1);
 
-                }    
+                    }    
+                }
             }
         }
     }
-- 
GitLab


From 92c5780b5cef90e4971404d504428acd6c2cc530 Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 18:30:57 -0500
Subject: [PATCH 4/9] Continue adding opticalGroup layer

---
 DQMUtils/DQMHistogramPedestalEqualization.cc |   98 +-
 DQMUtils/DQMInterface.cc                     |    3 +-
 DQMUtils/RD53ClockDelayHistograms.cc         |   32 +-
 DQMUtils/RD53GainHistograms.cc               |   78 +-
 DQMUtils/RD53GainOptimizationHistograms.cc   |   17 +-
 DQMUtils/RD53InjectionDelayHistograms.cc     |   34 +-
 DQMUtils/RD53LatencyHistograms.cc            |   32 +-
 DQMUtils/RD53PhysicsHistograms.cc            |   77 +-
 DQMUtils/RD53PixelAliveHistograms.cc         |   77 +-
 DQMUtils/RD53SCurveHistograms.cc             |   78 +-
 DQMUtils/RD53ThrEqualizationHistograms.cc    |   32 +-
 DQMUtils/RD53ThresholdHistograms.cc          |   17 +-
 DQMUtils/SSAPhysicsHistograms.cc             |   68 +-
 HWDescription/BeBoard.cc                     |   95 +-
 HWDescription/BeBoard.h                      |   59 +-
 HWDescription/Module.cc                      |    3 -
 HWDescription/Module.h                       |   66 +-
 HWDescription/OuterTrackerModule.h           |   36 +-
 HWInterface/BeBoardInterface.cc              |    2 +-
 HWInterface/BeBoardInterface.h               |    2 +-
 HWInterface/CbcInterface.cc                  |   26 +-
 HWInterface/D19cFWInterface.cc               |  846 ++++----
 HWInterface/RD53FWInterface.cc               |   12 +-
 HWInterface/RD53Interface.cc                 |    2 +-
 System/FileParser.cc                         |   71 +-
 System/FileParser.h                          |    6 +-
 System/SystemController.cc                   |  195 +-
 System/SystemController.h                    |   27 +-
 Utils/ContainerFactory.h                     |    6 +-
 Utils/ContainerRecycleBin.h                  |   26 +-
 Utils/D19cCbc3Event.cc                       |   16 +-
 Utils/D19cCbc3EventZS.cc                     |   12 +-
 Utils/D19cCic2Event.cc                       |   14 +-
 Utils/D19cCicEvent.cc                        |   38 +-
 Utils/D19cMPAEvent.cc                        |    8 +-
 Utils/SSAEvent.cc                            |   38 +-
 setup.sh                                     |    4 +-
 tools/AntennaTester.cc                       |   53 +-
 tools/BackEndAlignment.cc                    |  266 +--
 tools/BiasSweep.cc                           |   54 +-
 tools/CBCPulseShape.cc                       |    3 +-
 tools/CMTester.cc                            |  474 ++---
 tools/CalibrationExample.cc                  |   21 +-
 tools/Channel.cc                             |    3 +-
 tools/Channel.h                              |    3 +-
 tools/CicFEAlignment.cc                      |  645 ++++---
 tools/DataChecker.cc                         | 1298 +++++++------
 tools/Eudaq2Producer.cc                      |  371 ++--
 tools/ExtraChecks.cc                         | 1809 +++++++++---------
 tools/ExtraChecks.h                          |    1 +
 tools/HybridTester.cc                        |  317 +--
 tools/HybridTester.h                         |    4 +-
 tools/LatencyScan.cc                         |  343 ++--
 tools/MultiplexingSetup.cc                   |   37 +-
 tools/OpenFinder.cc                          |   46 +-
 tools/PedeNoise.cc                           |  162 +-
 tools/PedestalEqualization.cc                |  111 +-
 tools/PulseShape.cc                          |  181 +-
 tools/PulseShape.h                           |    2 +-
 tools/RD53ClockDelay.cc                      |  160 +-
 tools/RD53Gain.cc                            |   78 +-
 tools/RD53GainOptimization.cc                |   78 +-
 tools/RD53InjectionDelay.cc                  |   64 +-
 tools/RD53Latency.cc                         |   34 +-
 tools/RD53Physics.cc                         |   50 +-
 tools/RD53PixelAlive.cc                      |   54 +-
 tools/RD53SCurve.cc                          |   82 +-
 tools/RD53ThrAdjustment.cc                   |  121 +-
 tools/RD53ThrEqualization.cc                 |  143 +-
 tools/RD53ThrMinimization.cc                 |   78 +-
 tools/RegisterTester.cc                      |   96 +-
 tools/SSAPhysics.cc                          |   15 +-
 tools/ShortFinder.cc                         |   56 +-
 tools/SignalScan.cc                          |  305 +--
 tools/SignalScanFit.cc                       |  307 +--
 tools/StubQuickCheck.cc                      |  225 ++-
 tools/StubSweep.cc                           |  298 +--
 tools/StubTool.cc                            |  644 ++++---
 tools/StubTool.h                             |    2 +-
 tools/TPCalibration.cc                       |  246 +--
 tools/Tool.cc                                |  377 ++--
 tools/Tool.h                                 |   18 +-
 82 files changed, 6295 insertions(+), 5693 deletions(-)

diff --git a/DQMUtils/DQMHistogramPedestalEqualization.cc b/DQMUtils/DQMHistogramPedestalEqualization.cc
index b5670b849..38fb01f69 100644
--- a/DQMUtils/DQMHistogramPedestalEqualization.cc
+++ b/DQMUtils/DQMHistogramPedestalEqualization.cc
@@ -89,29 +89,32 @@ void DQMHistogramPedestalEqualization::process()
 {
     for(auto board : fDetectorOffsetHistograms)
     { 
-        for(auto module: *board)
-        {   
-            TCanvas *offsetCanvas = new TCanvas(("Offset_" + std::to_string(module->getId())).data(),("Offset " + std::to_string(module->getId())).data(),10, 0, 500, 500 );
-            TCanvas *occupancyCanvas  = new TCanvas(("Occupancy_"  + std::to_string(module->getId())).data(),("Occupancy "  + std::to_string(module->getId())).data(), 10, 525, 500, 500 );
-
-            offsetCanvas   ->DivideSquare (module->size());
-            occupancyCanvas->DivideSquare (module->size());
-            
-            for(auto chip: *module)
-            {
-                offsetCanvas->cd(chip->getIndex()+1);
-                TH1I* offsetHistogram = chip->getSummary<HistContainer<TH1I>>().fTheHistogram;
-                offsetHistogram->GetXaxis()->SetTitle("Channel");
-                offsetHistogram->GetYaxis()->SetTitle("Offset");
-                offsetHistogram->DrawCopy();
-
-                occupancyCanvas->cd(chip->getIndex()+1);
-                TH1F* occupancyHistogram = fDetectorOccupancyHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                occupancyHistogram->GetXaxis()->SetTitle("Channel");
-                occupancyHistogram->GetYaxis()->SetTitle("Occupancy");
-                occupancyHistogram->DrawCopy();
+        for(auto opticalGroup : *board)
+        {
+            for(auto hybrid: *opticalGroup)
+            {   
+                TCanvas *offsetCanvas = new TCanvas(("Offset_" + std::to_string(hybrid->getId())).data(),("Offset " + std::to_string(hybrid->getId())).data(),10, 0, 500, 500 );
+                TCanvas *occupancyCanvas  = new TCanvas(("Occupancy_"  + std::to_string(hybrid->getId())).data(),("Occupancy "  + std::to_string(hybrid->getId())).data(), 10, 525, 500, 500 );
+
+                offsetCanvas   ->DivideSquare (hybrid->size());
+                occupancyCanvas->DivideSquare (hybrid->size());
+                
+                for(auto chip: *hybrid)
+                {
+                    offsetCanvas->cd(chip->getIndex()+1);
+                    TH1I* offsetHistogram = chip->getSummary<HistContainer<TH1I>>().fTheHistogram;
+                    offsetHistogram->GetXaxis()->SetTitle("Channel");
+                    offsetHistogram->GetYaxis()->SetTitle("Offset");
+                    offsetHistogram->DrawCopy();
+
+                    occupancyCanvas->cd(chip->getIndex()+1);
+                    TH1F* occupancyHistogram = fDetectorOccupancyHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    occupancyHistogram->GetXaxis()->SetTitle("Channel");
+                    occupancyHistogram->GetYaxis()->SetTitle("Occupancy");
+                    occupancyHistogram->DrawCopy();
+                }
+                
             }
-            
         }
     }
 
@@ -129,13 +132,16 @@ void DQMHistogramPedestalEqualization::fillVplusPlots(DetectorDataContainer &the
 {
     for(auto board : theVthr)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            if(module == nullptr) continue;
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
-                TH1I *chipVplusHistogram = fDetectorVplusHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1I>>().fTheHistogram;
-                chipVplusHistogram->SetBinContent(1, chip->getSummary<uint16_t>());
+                if(hybrid == nullptr) continue;
+                for(auto chip: *hybrid)
+                {
+                    TH1I *chipVplusHistogram = fDetectorVplusHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1I>>().fTheHistogram;
+                    chipVplusHistogram->SetBinContent(1, chip->getSummary<uint16_t>());
+                }
             }
         }
     }
@@ -147,20 +153,23 @@ void DQMHistogramPedestalEqualization::fillOccupancyPlots(DetectorDataContainer
 {
     for(auto board : theOccupancy)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
-                if(chip->getChannelContainer<Occupancy>() == nullptr ) continue;
-                TH1F *chipOccupancyHistogram = fDetectorOccupancyHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-                uint channelBin=1;
-                for(auto channel : *chip->getChannelContainer<Occupancy>())
+                for(auto chip: *hybrid)
                 {
-                    chipOccupancyHistogram->SetBinContent(channelBin  ,channel.fOccupancy     );
-                    chipOccupancyHistogram->SetBinError  (channelBin++,channel.fOccupancyError);
+                    if(chip->getChannelContainer<Occupancy>() == nullptr ) continue;
+                    TH1F *chipOccupancyHistogram = fDetectorOccupancyHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+                    uint channelBin=1;
+                    for(auto channel : *chip->getChannelContainer<Occupancy>())
+                    {
+                        chipOccupancyHistogram->SetBinContent(channelBin  ,channel.fOccupancy     );
+                        chipOccupancyHistogram->SetBinError  (channelBin++,channel.fOccupancyError);
+                    }
                 }
-            }
 
+            }
         }
     }
 }
@@ -171,16 +180,19 @@ void DQMHistogramPedestalEqualization::fillOffsetPlots(DetectorDataContainer &th
 {
     for(auto board : theOffsets)
     {
-        for(auto module: *board)
+        for(auto opticalGroup : *board)
         {
-            for(auto chip: *module)
+            for(auto hybrid: *opticalGroup)
             {
-                if(chip->getChannelContainer<uint8_t>() == nullptr ) continue;
-                TH1I *chipOffsetHistogram = fDetectorOffsetHistograms.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1I>>().fTheHistogram;
-                uint channelBin=1;
-                for(auto channel : *chip->getChannelContainer<uint8_t>())
+                for(auto chip: *hybrid)
                 {
-                    chipOffsetHistogram->SetBinContent(channelBin++,channel );
+                    if(chip->getChannelContainer<uint8_t>() == nullptr ) continue;
+                    TH1I *chipOffsetHistogram = fDetectorOffsetHistograms.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<HistContainer<TH1I>>().fTheHistogram;
+                    uint channelBin=1;
+                    for(auto channel : *chip->getChannelContainer<uint8_t>())
+                    {
+                        chipOffsetHistogram->SetBinContent(channelBin++,channel );
+                    }
                 }
             }
         }
diff --git a/DQMUtils/DQMInterface.cc b/DQMUtils/DQMInterface.cc
index 064271578..9118055a3 100644
--- a/DQMUtils/DQMInterface.cc
+++ b/DQMUtils/DQMInterface.cc
@@ -86,12 +86,11 @@ void DQMInterface::configure(std::string const &calibrationName, std::string con
 
 	Ph2_System::FileParser fParser;
 	std::map<uint16_t, Ph2_HwInterface::BeBoardFWInterface *> fBeBoardFWMap;
-	std::vector<Ph2_HwDescription::BeBoard *> fBoardVector;
 	std::stringstream out;
 	DetectorContainer fDetectorStructure;
 	Ph2_System::SettingsMap pSettingsMap;
 
-	fParser.parseHW(configurationFilePath, fBeBoardFWMap, fBoardVector, &fDetectorStructure, out, true);
+	fParser.parseHW(configurationFilePath, fBeBoardFWMap, &fDetectorStructure, out, true);
 	fParser.parseSettings(configurationFilePath, pSettingsMap, out, true);
 
 	if (calibrationName == "pedenoise")
diff --git a/DQMUtils/RD53ClockDelayHistograms.cc b/DQMUtils/RD53ClockDelayHistograms.cc
index c15b27ee0..f8a9cd580 100644
--- a/DQMUtils/RD53ClockDelayHistograms.cc
+++ b/DQMUtils/RD53ClockDelayHistograms.cc
@@ -60,30 +60,32 @@ void ClockDelayHistograms::fillOccupancy (const DetectorDataContainer& Occupancy
   const size_t ClkDelaySize = RD53Shared::setBits(RD53Shared::MAXBITCHIPREG) + 1;
 
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<ClkDelaySize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<ClkDelaySize>>() == nullptr) continue;
 
-          auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (size_t i = startValue; i <= stopValue; i++)
-            Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<ClkDelaySize>>().data[i-startValue]);
-        }
+            for (size_t i = startValue; i <= stopValue; i++)
+              Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<ClkDelaySize>>().data[i-startValue]);
+          }
 }
 
 void ClockDelayHistograms::fillClockDelay (const DetectorDataContainer& ClockDelayContainer)
 {
   for (const auto cBoard : ClockDelayContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
 
-          auto* ClockDelayHist = ClockDelay.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* ClockDelayHist = ClockDelay.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          ClockDelayHist->Fill(cChip->getSummary<uint16_t>());
-        }
+            ClockDelayHist->Fill(cChip->getSummary<uint16_t>());
+          }
 }
 
 void ClockDelayHistograms::process ()
diff --git a/DQMUtils/RD53GainHistograms.cc b/DQMUtils/RD53GainHistograms.cc
index 71fdb5c0b..b0ba367fe 100644
--- a/DQMUtils/RD53GainHistograms.cc
+++ b/DQMUtils/RD53GainHistograms.cc
@@ -75,49 +75,51 @@ bool GainHistograms::fill (std::vector<char>& dataBuffer)
 void GainHistograms::fillOccupancy (const DetectorDataContainer& OccupancyContainer, int DELTA_VCAL)
 {
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
-
-          auto* hOcc2D             = Occupancy2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              {
-                if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
-                  hOcc2D->Fill(DELTA_VCAL, cChip->getChannel<OccupancyAndPh>(row,col).fPh);
-                if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
-              }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
+
+            auto* hOcc2D             = Occupancy2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                {
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
+                    hOcc2D->Fill(DELTA_VCAL, cChip->getChannel<OccupancyAndPh>(row,col).fPh);
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
+                }
+          }
 }
 
 void GainHistograms::fillGainAndIntercept (const DetectorDataContainer& GainAndInterceptContainer)
 {
   for (const auto cBoard : GainAndInterceptContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<GainAndIntercept>() == nullptr) continue;
-
-          auto* Gain1DHist      = Gain1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* Intercept1DHist = Intercept1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* Gain2DHist      = Gain2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* Intercept2DHist = Intercept2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorFit2DHist  = ErrorFit2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              if (cChip->getChannel<GainAndIntercept>(row,col).fGain == RD53Shared::FITERROR) ErrorFit2DHist->Fill(col+1, row+1);
-              else if (cChip->getChannel<GainAndIntercept>(row,col).fGain != 0)
-                {
-                  Gain1DHist->Fill(cChip->getChannel<GainAndIntercept>(row,col).fGain);
-                  Intercept1DHist->Fill(cChip->getChannel<GainAndIntercept>(row,col).fIntercept);
-                  Gain2DHist->SetBinContent(col+1, row+1, cChip->getChannel<GainAndIntercept>(row,col).fGain);
-                  Intercept2DHist->SetBinContent(col+1, row+1, cChip->getChannel<GainAndIntercept>(row,col).fIntercept);
-                }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<GainAndIntercept>() == nullptr) continue;
+
+            auto* Gain1DHist      = Gain1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Intercept1DHist = Intercept1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Gain2DHist      = Gain2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* Intercept2DHist = Intercept2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorFit2DHist  = ErrorFit2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                if (cChip->getChannel<GainAndIntercept>(row,col).fGain == RD53Shared::FITERROR) ErrorFit2DHist->Fill(col+1, row+1);
+                else if (cChip->getChannel<GainAndIntercept>(row,col).fGain != 0)
+                  {
+                    Gain1DHist->Fill(cChip->getChannel<GainAndIntercept>(row,col).fGain);
+                    Intercept1DHist->Fill(cChip->getChannel<GainAndIntercept>(row,col).fIntercept);
+                    Gain2DHist->SetBinContent(col+1, row+1, cChip->getChannel<GainAndIntercept>(row,col).fGain);
+                    Intercept2DHist->SetBinContent(col+1, row+1, cChip->getChannel<GainAndIntercept>(row,col).fIntercept);
+                  }
+          }
 }
 
 void GainHistograms::process ()
diff --git a/DQMUtils/RD53GainOptimizationHistograms.cc b/DQMUtils/RD53GainOptimizationHistograms.cc
index f00e31a59..9566eab6c 100644
--- a/DQMUtils/RD53GainOptimizationHistograms.cc
+++ b/DQMUtils/RD53GainOptimizationHistograms.cc
@@ -17,7 +17,7 @@ void GainOptimizationHistograms::book (TFile* theOutputFile, const DetectorConta
   ContainerFactory::copyStructure(theDetectorStructure, DetectorData);
 
 
-  uint16_t rangeKrumCurr = RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0))->getNumberOfBits("KRUM_CURR_LIN")) + 1;
+  uint16_t rangeKrumCurr = RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0)->at(0))->getNumberOfBits("KRUM_CURR_LIN")) + 1;
 
   auto hKrumCurr = CanvasContainer<TH1F>("KrumCurr", "KrumCurr", rangeKrumCurr, 0, rangeKrumCurr);
   bookImplementer(theOutputFile, theDetectorStructure, KrumCurr, hKrumCurr, "Krummenacher Current", "Entries");
@@ -41,15 +41,16 @@ bool GainOptimizationHistograms::fill (std::vector<char>& dataBuffer)
 void GainOptimizationHistograms::fill (const DetectorDataContainer& DataContainer)
 {
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
 
-          auto* hKrumCurr = KrumCurr.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* hKrumCurr = KrumCurr.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          hKrumCurr->Fill(cChip->getSummary<uint16_t>());
-        }
+            hKrumCurr->Fill(cChip->getSummary<uint16_t>());
+          }
 }
 
 void GainOptimizationHistograms::process ()
diff --git a/DQMUtils/RD53InjectionDelayHistograms.cc b/DQMUtils/RD53InjectionDelayHistograms.cc
index 3d25954a9..fdc7838a9 100644
--- a/DQMUtils/RD53InjectionDelayHistograms.cc
+++ b/DQMUtils/RD53InjectionDelayHistograms.cc
@@ -21,7 +21,7 @@ void InjectionDelayHistograms::book (TFile* theOutputFile, const DetectorContain
   // # Retrieve parameters #
   // #######################
   startValue = 0;
-  stopValue  = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"))+1) - 1;
+  stopValue  = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"))+1) - 1;
 
 
   auto hInjectionDelay = CanvasContainer<TH1F>("InjectionDelay", "Injection Delay", stopValue - startValue + 1, startValue, stopValue + 1);
@@ -61,30 +61,32 @@ void InjectionDelayHistograms::fillOccupancy (const DetectorDataContainer& Occup
   const size_t InjDelaySize = RD53Shared::setBits(RD53Shared::MAXBITCHIPREG) + 1;
 
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<InjDelaySize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<InjDelaySize>>() == nullptr) continue;
 
-          auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (size_t i = startValue; i <= stopValue; i++)
-            Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<InjDelaySize>>().data[i-startValue]);
-        }
+            for (size_t i = startValue; i <= stopValue; i++)
+              Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<InjDelaySize>>().data[i-startValue]);
+          }
 }
 
 void InjectionDelayHistograms::fillInjectionDelay (const DetectorDataContainer& InjectionDelayContainer)
 {
   for (const auto cBoard : InjectionDelayContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
 
-          auto* InjectionDelayHist = InjectionDelay.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* InjectionDelayHist = InjectionDelay.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          InjectionDelayHist->Fill(cChip->getSummary<uint16_t>());
-        }
+            InjectionDelayHist->Fill(cChip->getSummary<uint16_t>());
+          }
 }
 
 void InjectionDelayHistograms::process ()
diff --git a/DQMUtils/RD53LatencyHistograms.cc b/DQMUtils/RD53LatencyHistograms.cc
index 7ebb71e04..71d7baf2a 100644
--- a/DQMUtils/RD53LatencyHistograms.cc
+++ b/DQMUtils/RD53LatencyHistograms.cc
@@ -62,30 +62,32 @@ void LatencyHistograms::fillOccupancy (const DetectorDataContainer& OccupancyCon
   const size_t LatencySize = RD53Shared::setBits(RD53Shared::MAXBITCHIPREG) + 1;
 
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<LatencySize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<LatencySize>>() == nullptr) continue;
 
-          auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Occupancy1DHist = Occupancy1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (size_t i = startValue; i <= stopValue; i+=nTRIGxEvent)
-            Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<LatencySize>>().data[(i-startValue)/nTRIGxEvent]);
-        }
+            for (size_t i = startValue; i <= stopValue; i+=nTRIGxEvent)
+              Occupancy1DHist->SetBinContent(Occupancy1DHist->FindBin(i), cChip->getSummary<GenericDataArray<LatencySize>>().data[(i-startValue)/nTRIGxEvent]);
+          }
 }
 
 void LatencyHistograms::fillLatency (const DetectorDataContainer& LatencyContainer)
 {
   for (const auto cBoard : LatencyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
 
-          auto* LatencyHist = Latency.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* LatencyHist = Latency.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (auto i = 0u; i < nTRIGxEvent; i++) LatencyHist->Fill(cChip->getSummary<uint16_t>() - i);
-        }
+            for (auto i = 0u; i < nTRIGxEvent; i++) LatencyHist->Fill(cChip->getSummary<uint16_t>() - i);
+          }
 }
 
 void LatencyHistograms::process ()
diff --git a/DQMUtils/RD53PhysicsHistograms.cc b/DQMUtils/RD53PhysicsHistograms.cc
index 175993b02..d70a46c1a 100644
--- a/DQMUtils/RD53PhysicsHistograms.cc
+++ b/DQMUtils/RD53PhysicsHistograms.cc
@@ -75,29 +75,30 @@ bool PhysicsHistograms::fill (std::vector<char>& dataBuffer)
 void PhysicsHistograms::fill (const DetectorDataContainer& DataContainer)
 {
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
-
-          auto* ToT1DHist          = ToT1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* ToT2DHist          = ToT2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* Occupancy2DHist    = Occupancy2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              {
-                if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != 0)
-                  {
-                    ToT1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fPh);
-                    ToT2DHist->SetBinContent(col+1, row+1, ToT2DHist->GetBinContent(col+1, row+1) + cChip->getChannel<OccupancyAndPh>(row,col).fPh);
-                    Occupancy2DHist->SetBinContent(col+1, row+1, Occupancy2DHist->GetBinContent(col+1, row+1) + cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
-                  }
-
-                if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
-              }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
+
+            auto* ToT1DHist          = ToT1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* ToT2DHist          = ToT2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* Occupancy2DHist    = Occupancy2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                {
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != 0)
+                    {
+                      ToT1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fPh);
+                      ToT2DHist->SetBinContent(col+1, row+1, ToT2DHist->GetBinContent(col+1, row+1) + cChip->getChannel<OccupancyAndPh>(row,col).fPh);
+                      Occupancy2DHist->SetBinContent(col+1, row+1, Occupancy2DHist->GetBinContent(col+1, row+1) + cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
+                    }
+
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
+                }
+          }
 }
 
 void PhysicsHistograms::fillBCID (const DetectorDataContainer& DataContainer)
@@ -105,15 +106,16 @@ void PhysicsHistograms::fillBCID (const DetectorDataContainer& DataContainer)
   const size_t BCIDsize = RD53Shared::setBits(RD53EvtEncoder::NBIT_BCID) + 1;
 
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<BCIDsize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<BCIDsize>>() == nullptr) continue;
 
-          auto* BCIDHist = BCID.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* BCIDHist = BCID.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (auto i = 0u; i < BCIDsize; i++) BCIDHist->SetBinContent(i+1, BCIDHist->GetBinContent(i+1) + cChip->getSummary<GenericDataArray<BCIDsize>>().data[i]);
-        }
+            for (auto i = 0u; i < BCIDsize; i++) BCIDHist->SetBinContent(i+1, BCIDHist->GetBinContent(i+1) + cChip->getSummary<GenericDataArray<BCIDsize>>().data[i]);
+          }
 }
 
 void PhysicsHistograms::fillTrgID (const DetectorDataContainer& DataContainer)
@@ -121,15 +123,16 @@ void PhysicsHistograms::fillTrgID (const DetectorDataContainer& DataContainer)
   const size_t TrgIDsize = RD53Shared::setBits(RD53EvtEncoder::NBIT_TRIGID) + 1;
 
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<TrgIDsize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<TrgIDsize>>() == nullptr) continue;
 
-          auto* TriggerIDHist = TriggerID.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* TriggerIDHist = TriggerID.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (auto i = 0u; i < TrgIDsize; i++) TriggerIDHist->SetBinContent(i+1, TriggerIDHist->GetBinContent(i+1) + cChip->getSummary<GenericDataArray<TrgIDsize>>().data[i]);
-        }
+            for (auto i = 0u; i < TrgIDsize; i++) TriggerIDHist->SetBinContent(i+1, TriggerIDHist->GetBinContent(i+1) + cChip->getSummary<GenericDataArray<TrgIDsize>>().data[i]);
+          }
 }
 
 void PhysicsHistograms::process ()
diff --git a/DQMUtils/RD53PixelAliveHistograms.cc b/DQMUtils/RD53PixelAliveHistograms.cc
index a5adbd25d..944c3fb46 100644
--- a/DQMUtils/RD53PixelAliveHistograms.cc
+++ b/DQMUtils/RD53PixelAliveHistograms.cc
@@ -83,28 +83,29 @@ bool PixelAliveHistograms::fill (std::vector<char>& dataBuffer)
 void PixelAliveHistograms::fill (const DetectorDataContainer& DataContainer)
 {
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
-
-          auto* Occupancy1DHist    = Occupancy1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* Occupancy2DHist    = Occupancy2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ToTHist            = ToT.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              {
-                if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != 0)
-                  {
-                    Occupancy1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy * nEvents);
-                    Occupancy2DHist->SetBinContent(col+1, row+1, cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
-                    ToTHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fPh);
-                  }
-                if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
-              }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
+
+            auto* Occupancy1DHist    = Occupancy1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Occupancy2DHist    = Occupancy2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ToTHist            = ToT.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                {
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != 0)
+                    {
+                      Occupancy1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy * nEvents);
+                      Occupancy2DHist->SetBinContent(col+1, row+1, cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
+                      ToTHist->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fPh);
+                    }
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
+                }
+          }
 }
 
 void PixelAliveHistograms::fillBCID (const DetectorDataContainer& DataContainer)
@@ -112,15 +113,16 @@ void PixelAliveHistograms::fillBCID (const DetectorDataContainer& DataContainer)
   const size_t BCIDsize = RD53Shared::setBits(RD53EvtEncoder::NBIT_BCID) + 1;
 
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<BCIDsize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<BCIDsize>>() == nullptr) continue;
 
-          auto* BCIDHist = BCID.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* BCIDHist = BCID.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (auto i = 0u; i < BCIDsize; i++) BCIDHist->SetBinContent(i+1, cChip->getSummary<GenericDataArray<BCIDsize>>().data[i]);
-        }
+            for (auto i = 0u; i < BCIDsize; i++) BCIDHist->SetBinContent(i+1, cChip->getSummary<GenericDataArray<BCIDsize>>().data[i]);
+          }
 }
 
 void PixelAliveHistograms::fillTrgID (const DetectorDataContainer& DataContainer)
@@ -128,16 +130,17 @@ void PixelAliveHistograms::fillTrgID (const DetectorDataContainer& DataContainer
   const size_t TrgIDsize = RD53Shared::setBits(RD53EvtEncoder::NBIT_TRIGID) + 1;
 
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<GenericDataArray<TrgIDsize>>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<GenericDataArray<TrgIDsize>>() == nullptr) continue;
 
-          auto* TriggerIDHist = TriggerID.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* TriggerIDHist = TriggerID.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          for (auto i = 0u; i < TrgIDsize; i++) TriggerIDHist->SetBinContent(i+1, cChip->getSummary<GenericDataArray<TrgIDsize>>().data[i]);
-        }
-}
+            for (auto i = 0u; i < TrgIDsize; i++) TriggerIDHist->SetBinContent(i+1, cChip->getSummary<GenericDataArray<TrgIDsize>>().data[i]);
+          }
+  }
 
 void PixelAliveHistograms::process ()
 {
diff --git a/DQMUtils/RD53SCurveHistograms.cc b/DQMUtils/RD53SCurveHistograms.cc
index 1f0e076eb..95e04aca7 100644
--- a/DQMUtils/RD53SCurveHistograms.cc
+++ b/DQMUtils/RD53SCurveHistograms.cc
@@ -75,49 +75,51 @@ bool SCurveHistograms::fill (std::vector<char>& dataBuffer)
 void SCurveHistograms::fillOccupancy (const DetectorDataContainer& OccupancyContainer, int DELTA_VCAL)
 {
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
-
-          auto* hOcc2D             = Occupancy2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              {
-                if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
-                  hOcc2D->Fill(DELTA_VCAL, cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy + hOcc2D->GetYaxis()->GetBinWidth(0) / 2.);
-                if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
-              }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
+
+            auto* hOcc2D             = Occupancy2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorReadOut2DHist = ErrorReadOut2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                {
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
+                    hOcc2D->Fill(DELTA_VCAL, cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy + hOcc2D->GetYaxis()->GetBinWidth(0) / 2.);
+                  if (cChip->getChannel<OccupancyAndPh>(row,col).readoutError == true) ErrorReadOut2DHist->Fill(col+1, row+1);
+                }
+          }
 }
 
 void SCurveHistograms::fillThrAndNoise (const DetectorDataContainer& ThrAndNoiseContainer)
 {
   for (const auto cBoard : ThrAndNoiseContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<ThresholdAndNoise>() == nullptr) continue;
-
-          auto* Threshold1DHist = Threshold1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* Noise1DHist     = Noise1D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-          auto* Threshold2DHist = Threshold2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* Noise2DHist     = Noise2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-          auto* ErrorFit2DHist  = ErrorFit2D.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              if (cChip->getChannel<ThresholdAndNoise>(row,col).fNoise == RD53Shared::FITERROR) ErrorFit2DHist->Fill(col+1, row+1);
-              else if (cChip->getChannel<ThresholdAndNoise>(row,col).fNoise != 0)
-                {
-                  Threshold1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row,col).fThreshold);
-                  Noise1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row,col).fNoise);
-                  Threshold2DHist->SetBinContent(col+1, row+1, cChip->getChannel<ThresholdAndNoise>(row,col).fThreshold);
-                  Noise2DHist->SetBinContent(col+1, row+1, cChip->getChannel<ThresholdAndNoise>(row,col).fNoise);
-                }
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<ThresholdAndNoise>() == nullptr) continue;
+
+            auto* Threshold1DHist = Threshold1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Noise1DHist     = Noise1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* Threshold2DHist = Threshold2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* Noise2DHist     = Noise2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+            auto* ErrorFit2DHist  = ErrorFit2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                if (cChip->getChannel<ThresholdAndNoise>(row,col).fNoise == RD53Shared::FITERROR) ErrorFit2DHist->Fill(col+1, row+1);
+                else if (cChip->getChannel<ThresholdAndNoise>(row,col).fNoise != 0)
+                  {
+                    Threshold1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row,col).fThreshold);
+                    Noise1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row,col).fNoise);
+                    Threshold2DHist->SetBinContent(col+1, row+1, cChip->getChannel<ThresholdAndNoise>(row,col).fThreshold);
+                    Noise2DHist->SetBinContent(col+1, row+1, cChip->getChannel<ThresholdAndNoise>(row,col).fNoise);
+                  }
+          }
 }
 
 void SCurveHistograms::process ()
diff --git a/DQMUtils/RD53ThrEqualizationHistograms.cc b/DQMUtils/RD53ThrEqualizationHistograms.cc
index e4e6ebf07..82f8f618b 100644
--- a/DQMUtils/RD53ThrEqualizationHistograms.cc
+++ b/DQMUtils/RD53ThrEqualizationHistograms.cc
@@ -59,18 +59,19 @@ bool ThrEqualizationHistograms::fill (std::vector<char>& dataBuffer)
 void ThrEqualizationHistograms::fillOccupancy (const DetectorDataContainer& OccupancyContainer)
 {
   for (const auto cBoard : OccupancyContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
-
-          auto* hThrEqualization = ThrEqualization.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
-
-          for (auto row = 0u; row < RD53::nRows; row++)
-            for (auto col = 0u; col < RD53::nCols; col++)
-              if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
-                hThrEqualization->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
-        }
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getChannelContainer<OccupancyAndPh>() == nullptr) continue;
+
+            auto* hThrEqualization = ThrEqualization.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+
+            for (auto row = 0u; row < RD53::nRows; row++)
+              for (auto col = 0u; col < RD53::nCols; col++)
+                if (cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy != RD53Shared::ISDISABLED)
+                  hThrEqualization->Fill(cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy);
+          }
 }
 
 void ThrEqualizationHistograms::fillTDAC (const DetectorDataContainer& TDACContainer)
@@ -78,12 +79,13 @@ void ThrEqualizationHistograms::fillTDAC (const DetectorDataContainer& TDACConta
   size_t TDACsize = RD53Shared::setBits(RD53Constants::NBIT_TDAC) + 1;
 
   for (const auto cBoard : TDACContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+    for (const auto cHybrid : *cOpticalGroup)
+      for (const auto cChip : *cHybrid)
         {
           if (cChip->getChannelContainer<uint16_t>() == nullptr) continue;
 
-          auto* hTDAC = TDAC.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+          auto* hTDAC = TDAC.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
diff --git a/DQMUtils/RD53ThresholdHistograms.cc b/DQMUtils/RD53ThresholdHistograms.cc
index 8a15112ec..23930a69e 100644
--- a/DQMUtils/RD53ThresholdHistograms.cc
+++ b/DQMUtils/RD53ThresholdHistograms.cc
@@ -17,7 +17,7 @@ void ThresholdHistograms::book (TFile* theOutputFile, const DetectorContainer& t
   ContainerFactory::copyStructure(theDetectorStructure, DetectorData);
 
 
-  uint16_t rangeThreshold = RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0))->getNumberOfBits("Vthreshold_LIN")) + 1;
+  uint16_t rangeThreshold = RD53Shared::setBits(static_cast<RD53*>(theDetectorStructure.at(0)->at(0)->at(0)->at(0))->getNumberOfBits("Vthreshold_LIN")) + 1;
 
   auto hThrehsold = CanvasContainer<TH1F>("Threhsold", "Threhsold", rangeThreshold, 0, rangeThreshold);
   bookImplementer(theOutputFile, theDetectorStructure, Threhsold, hThrehsold, "Threhsold", "Entries");
@@ -41,15 +41,16 @@ bool ThresholdHistograms::fill (std::vector<char>& dataBuffer)
 void ThresholdHistograms::fill (const DetectorDataContainer& DataContainer)
 {
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
+          {
+            if (cChip->getSummaryContainer<uint16_t>() == nullptr) continue;
 
-          auto* hThrehsold = Threhsold.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
+            auto* hThrehsold = Threhsold.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
 
-          hThrehsold->Fill(cChip->getSummary<uint16_t>());
-        }
+            hThrehsold->Fill(cChip->getSummary<uint16_t>());
+          }
 }
 
 void ThresholdHistograms::process ()
diff --git a/DQMUtils/SSAPhysicsHistograms.cc b/DQMUtils/SSAPhysicsHistograms.cc
index c230dec4d..4e491966a 100644
--- a/DQMUtils/SSAPhysicsHistograms.cc
+++ b/DQMUtils/SSAPhysicsHistograms.cc
@@ -42,22 +42,23 @@ bool SSAPhysicsHistograms::fill(std::vector<char> &dataBuffer)
 void SSAPhysicsHistograms::fillOccupancy(const DetectorDataContainer &DataContainer)
 {
   for (const auto cBoard : DataContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-      {
-        if (cChip->getChannelContainer<Occupancy>() == nullptr)
-          continue;
-        
-        auto *chipOccupancy = fOccupancy.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
-        uint channelBin=1;
-        
-        // Get channel data and fill the histogram
-        for(auto channel : *cChip->getChannelContainer<Occupancy>()) //for on channel - begin 
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cHybrid : *cOpticalGroup)
+        for (const auto cChip : *cHybrid)
         {
-          chipOccupancy->Fill(channelBin++,channel.fOccupancy);
-        }
+          if (cChip->getChannelContainer<Occupancy>() == nullptr)
+            continue;
+          
+          auto *chipOccupancy = fOccupancy.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<HistContainer<TH1F>>().fTheHistogram;
+          uint channelBin=1;
+          
+          // Get channel data and fill the histogram
+          for(auto channel : *cChip->getChannelContainer<Occupancy>()) //for on channel - begin 
+          {
+            chipOccupancy->Fill(channelBin++,channel.fOccupancy);
+          }
 
-      }
+        }
 }
 
 void SSAPhysicsHistograms::process()
@@ -67,26 +68,31 @@ void SSAPhysicsHistograms::process()
     for(auto board : fOccupancy) //for on boards - begin 
     {
         size_t boardIndex = board->getIndex();
-        for(auto module: *board) //for on module - begin 
+        for(auto opticalGroup: *board) //for on opticalGroup - begin 
         {
-            size_t moduleIndex = module->getIndex();
+          size_t opticalGroupIndex = opticalGroup->getIndex();
+
+          for(auto hybrid: *opticalGroup) //for on hybrid - begin 
+          {
+              size_t hybridIndex = hybrid->getIndex();
 
-            //Create a canvas do draw the plots
-            TCanvas *cOccupancy = new TCanvas(("Occupalcy_module_" + std::to_string(module->getId())).data(),("Hits module " + std::to_string(module->getId())).data(),   0, 0, 650, 650 );
-            cOccupancy->Divide(module->size());
+              //Create a canvas do draw the plots
+              TCanvas *cOccupancy = new TCanvas(("Occupancy_hybrid_" + std::to_string(hybrid->getId())).data(),("Hits hybrid " + std::to_string(hybrid->getId())).data(),   0, 0, 650, 650 );
+              cOccupancy->Divide(hybrid->size());
 
-            for(auto chip: *module)  //for on chip - begin 
-            {
-                size_t chipIndex = chip->getIndex();
-                cOccupancy->cd(chipIndex+1);
-                // Retreive the corresponging chip histogram:
-                TH1F *chipHitHistogram = fOccupancy.at(boardIndex)->at(moduleIndex)->at(chipIndex)
-                    ->getSummary<HistContainer<TH1F>>().fTheHistogram;
+              for(auto chip: *hybrid)  //for on chip - begin 
+              {
+                  size_t chipIndex = chip->getIndex();
+                  cOccupancy->cd(chipIndex+1);
+                  // Retreive the corresponging chip histogram:
+                  TH1F *chipHitHistogram = fOccupancy.at(boardIndex)->at(opticalGroupIndex)->at(hybridIndex)->at(chipIndex)
+                      ->getSummary<HistContainer<TH1F>>().fTheHistogram;
 
-                //Format the histogram (here you are outside from the SoC so you can use all the ROOT functions you need)
-                chipHitHistogram->SetStats(false);
-                chipHitHistogram->DrawCopy();
-            } //for on chip - end 
-        } //for on module - end 
+                  //Format the histogram (here you are outside from the SoC so you can use all the ROOT functions you need)
+                  chipHitHistogram->SetStats(false);
+                  chipHitHistogram->DrawCopy();
+              } //for on chip - end 
+          } //for on hybrid - end 
+        } //for on opticalGroup - end 
     } //for on boards - end 
 }
diff --git a/HWDescription/BeBoard.cc b/HWDescription/BeBoard.cc
index 086417ea2..5d4112a43 100644
--- a/HWDescription/BeBoard.cc
+++ b/HWDescription/BeBoard.cc
@@ -79,44 +79,44 @@ namespace Ph2_HwDescription {
 
     }
 
-    bool BeBoard::removeModule ( uint8_t pModuleId )
-    {
-
-        bool found = false;
-        std::vector<Module*>::iterator i;
-
-        for ( i = fModuleVector.begin(); i != fModuleVector.end(); ++i )
-        {
-            if ( ( *i )->getModuleId() == pModuleId )
-            {
-                found = true;
-                break;
-            }
-        }
-
-        if ( found )
-        {
-            fModuleVector.erase ( i );
-            return true;
-        }
-        else
-        {
-            LOG (INFO) << "Error:The BeBoard: " << +fBeId
-                       << " doesn't have the module " << +pModuleId ;
-            return false;
-        }
-    }
-
-    Module* BeBoard::getModule ( uint8_t pModuleId ) const
-    {
-        for ( Module* m : fModuleVector )
-        {
-            if ( m->getModuleId() == pModuleId )
-                return m;
-        }
-
-        return nullptr;
-    }
+    // bool BeBoard::removeModule ( uint8_t pModuleId )
+    // {
+
+    //     bool found = false;
+    //     std::vector<Module*>::iterator i;
+
+    //     for ( i = fModuleVector.begin(); i != fModuleVector.end(); ++i )
+    //     {
+    //         if ( ( *i )->getModuleId() == pModuleId )
+    //         {
+    //             found = true;
+    //             break;
+    //         }
+    //     }
+
+    //     if ( found )
+    //     {
+    //         fModuleVector.erase ( i );
+    //         return true;
+    //     }
+    //     else
+    //     {
+    //         LOG (INFO) << "Error:The BeBoard: " << +fBeId
+    //                    << " doesn't have the module " << +pModuleId ;
+    //         return false;
+    //     }
+    // }
+
+    // Module* BeBoard::getModule ( uint8_t pModuleId ) const
+    // {
+    //     for ( Module* m : fModuleVector )
+    //     {
+    //         if ( m->getModuleId() == pModuleId )
+    //             return m;
+    //     }
+
+    //     return nullptr;
+    // }
 
     void BeBoard::updateCondData (uint32_t& pTDCVal)
     {
@@ -131,17 +131,20 @@ namespace Ph2_HwDescription {
                 if (cCondItem.fUID == 3 ) cCondItem.fValue = pTDCVal;
                 else if (cCondItem.fUID == 1 )
                 {
-                    for (auto cFe : this->fModuleVector)
+                    for( auto cOpticalGroup : *this)
                     {
-                        if (cCondItem.fFeId != cFe->getFeId() ) continue;
-
-                        for (auto cCbc : cFe->fReadoutChipVector )
+                        for (auto cHybrid : *cOpticalGroup)
                         {
-                            if (cCondItem.fCbcId != cCbc->getChipId() ) continue;
-                            else if (cCbc->getFeId() == cCondItem.fFeId && cCbc->getChipId() == cCondItem.fCbcId)
+                            if (cCondItem.fFeId != cHybrid->getId() ) continue;
+
+                            for (auto cCbc : *cHybrid)
                             {
-                                ChipRegItem cRegItem = cCbc->getRegItem ( cCondItem.fRegName );
-                                cCondItem.fValue = cRegItem.fValue;
+                                if (cCondItem.fCbcId != cCbc->getId() ) continue;
+                                else if (cHybrid->getId() == cCondItem.fFeId && cCbc->getId() == cCondItem.fCbcId)
+                                {
+                                    ChipRegItem cRegItem = static_cast<ReadoutChip*>(cCbc)->getRegItem ( cCondItem.fRegName );
+                                    cCondItem.fValue = cRegItem.fValue;
+                                }
                             }
                         }
                     }
diff --git a/HWDescription/BeBoard.h b/HWDescription/BeBoard.h
index d772b3820..0106011b0 100644
--- a/HWDescription/BeBoard.h
+++ b/HWDescription/BeBoard.h
@@ -14,6 +14,7 @@
 
 #include "Definition.h"
 #include "Module.h"
+#include "OpticalGroup.h"
 #include "../Utils/Visitor.h"
 #include "../Utils/easylogging++.h"
 #include "../Utils/ConditionDataSet.h"
@@ -78,8 +79,8 @@ namespace Ph2_HwDescription {
         {
             pVisitor.visitBeBoard ( *this );
 
-            for ( auto& cFe : fModuleVector )
-                cFe->accept ( pVisitor );
+            for ( auto cOpticalGroup : *this )
+                static_cast<OpticalGroup*>(cOpticalGroup)->accept ( pVisitor );
         }
         // void accept( HwDescriptionVisitor& pVisitor ) const {
         //  pVisitor.visit( *this );
@@ -93,7 +94,9 @@ namespace Ph2_HwDescription {
         */
         uint8_t getNFe() const
         {
-            return fModuleVector.size();
+            uint16_t nFe = 0;
+            for(auto opticalGroup : *this) nFe += opticalGroup->size();
+            return nFe;
         }
 
         /*!
@@ -113,31 +116,31 @@ namespace Ph2_HwDescription {
          * \brief Adding a module to the vector
          * \param pModule
          */
-        void addModule ( Module& pModule )
-        {
-            fModuleVector.push_back ( &pModule );
-        }
-        void addModule ( Module* pModule )
-        {
-            fModuleVector.push_back ( pModule );
-        }
+        // void addModule ( Module& pModule )
+        // {
+        //     fModuleVector.push_back ( &pModule );
+        // }
+        // void addModule ( Module* pModule )
+        // {
+        //     fModuleVector.push_back ( pModule );
+        // }
 
-        /*!
-         * \brief Remove a Module from the vector
-         * \param pModuleId
-         * \return a bool which indicate if the removing was successful
-         */
-        bool removeModule ( uint8_t pModuleId );
-        /*!
-         * \brief Get a module from the vector
-         * \param pModuleId
-         * \return a pointer of module, so we can manipulate directly the module contained in the vector
-         */
-        Module* getModule ( uint8_t pModuleId ) const;
-        /*!
-        * \brief Get the Map of the registers
-        * \return The map of register
-        */
+        // /*!
+        //  * \brief Remove a Module from the vector
+        //  * \param pModuleId
+        //  * \return a bool which indicate if the removing was successful
+        //  */
+        // bool removeModule ( uint8_t pModuleId );
+        // /*!
+        //  * \brief Get a module from the vector
+        //  * \param pModuleId
+        //  * \return a pointer of module, so we can manipulate directly the module contained in the vector
+        //  */
+        // Module* getModule ( uint8_t pModuleId ) const;
+        // /*!
+        // * \brief Get the Map of the registers
+        // * \return The map of register
+        // */
         BeBoardRegMap getBeBoardRegMap() const
         {
             return fRegMap;
@@ -247,7 +250,7 @@ namespace Ph2_HwDescription {
             return fSparsifed;
         }
         // Vector of FEModules, each module is supposed to know which FMC slot it is connected to...
-        std::vector< Module* > fModuleVector;
+        // std::vector< Module* > fModuleVector;
 
         int dummyValue_ = 1989;
       protected:
diff --git a/HWDescription/Module.cc b/HWDescription/Module.cc
index 8157c399e..a61e03d1f 100644
--- a/HWDescription/Module.cc
+++ b/HWDescription/Module.cc
@@ -15,21 +15,18 @@ namespace Ph2_HwDescription
   Module::Module()
     : FrontEndDescription( )
     , ModuleContainer    (0)
-    , fModuleId          (0)
   {
   }
 
   Module::Module (const FrontEndDescription& pFeDesc, uint8_t pModuleId)
     : FrontEndDescription(pFeDesc  )
     , ModuleContainer    (pModuleId)
-    , fModuleId          (pModuleId)
   {
   }
 
   Module::Module (uint8_t pBeId, uint8_t pFMCId, uint8_t pFeId, uint8_t pModuleId)
     : FrontEndDescription(pBeId, pFMCId, pFeId)
     , ModuleContainer    (pModuleId)
-    , fModuleId          (pModuleId)
   {
   }
 
diff --git a/HWDescription/Module.h b/HWDescription/Module.h
index 6c4d2b26f..b223447bc 100644
--- a/HWDescription/Module.h
+++ b/HWDescription/Module.h
@@ -60,8 +60,8 @@ namespace Ph2_HwDescription {
         {
             pVisitor.visitModule ( *this );
 
-            for ( Chip* cChip : fReadoutChipVector )
-                cChip->accept ( pVisitor );
+            for ( auto cChip : *this )
+                static_cast<ReadoutChip*>(cChip)->accept ( pVisitor );
         }
         /*!
         * \brief Get the number of Chip connected to the Module
@@ -69,7 +69,7 @@ namespace Ph2_HwDescription {
         */
         uint8_t getNChip() const
         {
-            return fReadoutChipVector.size();
+            return this->size();
         }
 
         // void addReadoutChip ( ReadoutChip& pChip )
@@ -88,40 +88,40 @@ namespace Ph2_HwDescription {
 
         //     fReadoutChipVector.push_back ( &pChip );
         // }
-        void addReadoutChip ( ReadoutChip* pChip )
-        {
-            //get the FrontEndType of the Chip and set the module one accordingly
-            //this is the case when no chip type has been set so get the one from the Chip
-            if (fType == FrontEndType::UNDEFINED)
-                fType = pChip->getFrontEndType();
-            //else, the chip type has already been set - if it is different from another Chip, rais a warning
-            //no different chips should be on a module
-            else if (fType != pChip->getFrontEndType() )
-            {
-                LOG (ERROR) << "Error, Chips of a module should not be of different type! - aborting";
-                exit (1);
-            }
-
-            fReadoutChipVector.push_back ( pChip );
-        }
+        // void addReadoutChip ( ReadoutChip* pChip )
+        // {
+        //     //get the FrontEndType of the Chip and set the module one accordingly
+        //     //this is the case when no chip type has been set so get the one from the Chip
+        //     if (fType == FrontEndType::UNDEFINED)
+        //         fType = pChip->getFrontEndType();
+        //     //else, the chip type has already been set - if it is different from another Chip, rais a warning
+        //     //no different chips should be on a module
+        //     else if (fType != pChip->getFrontEndType() )
+        //     {
+        //         LOG (ERROR) << "Error, Chips of a module should not be of different type! - aborting";
+        //         exit (1);
+        //     }
 
-        uint8_t getModuleId() const
-        {
-            return fModuleId;
-        };
+        //     fReadoutChipVector.push_back ( pChip );
+        // }
+
+        // uint8_t getModuleId() const
+        // {
+        //     return fModuleId;
+        // };
 
         uint8_t getLinkId() const
         {
             return fLinkId;
         };
-        /*!
-         * \brief Set the Module Id
-         * \param pModuleId
-         */
-        void setModuleId ( uint8_t pModuleId )
-        {
-            fModuleId = pModuleId;
-        };
+        // /*!
+        //  * \brief Set the Module Id
+        //  * \param pModuleId
+        //  */
+        // void setModuleId ( uint8_t pModuleId )
+        // {
+        //     fModuleId = pModuleId;
+        // };
         void setLinkId ( uint8_t pLinkId )
         {
             fLinkId = pLinkId;
@@ -129,11 +129,11 @@ namespace Ph2_HwDescription {
 
 
         // std::vector < RD53* > fRD53Vector;
-        std::vector < ReadoutChip* > fReadoutChipVector;
+        // std::vector < ReadoutChip* > fReadoutChipVector;
 
 
       protected:
-        uint8_t fModuleId;
+        // uint8_t fModuleId;
         //link ID 
         uint8_t fLinkId;
     };
diff --git a/HWDescription/OuterTrackerModule.h b/HWDescription/OuterTrackerModule.h
index 8fe2035b2..d515d5fe8 100644
--- a/HWDescription/OuterTrackerModule.h
+++ b/HWDescription/OuterTrackerModule.h
@@ -55,15 +55,15 @@ namespace Ph2_HwDescription {
             fCic = nullptr;
         };
 
-        uint8_t getNMPA() const
-        {
-            return fMPAVector.size();
-        }
+        // uint8_t getNMPA() const
+        // {
+        //     return fMPAVector.size();
+        // }
 
-        uint8_t getNSSA() const
-        {
-            return fSSAVector.size();
-        }
+        // uint8_t getNSSA() const
+        // {
+        //     return fSSAVector.size();
+        // }
 
         // /*!
         //  * \brief Adding a Chip to the vector
@@ -97,18 +97,18 @@ namespace Ph2_HwDescription {
             pCic = nullptr;
         }
         
-        void addMPA ( MPA& pMPA )
-        {
-            fMPAVector.push_back ( &pMPA );
-        }
-        void addMPA ( MPA* pMPA )
-        {
-            fMPAVector.push_back ( pMPA );
-        }
+        // void addMPA ( MPA& pMPA )
+        // {
+        //     fMPAVector.push_back ( &pMPA );
+        // }
+        // void addMPA ( MPA* pMPA )
+        // {
+        //     fMPAVector.push_back ( pMPA );
+        // }
 
         Cic *fCic;
-        std::vector < MPA* > fMPAVector;
-        std::vector < SSA* > fSSAVector;
+        // std::vector < MPA* > fMPAVector;
+        // std::vector < SSA* > fSSAVector;
 
       protected:
 
diff --git a/HWInterface/BeBoardInterface.cc b/HWInterface/BeBoardInterface.cc
index c405b0bb1..58d19804b 100644
--- a/HWInterface/BeBoardInterface.cc
+++ b/HWInterface/BeBoardInterface.cc
@@ -37,7 +37,7 @@ namespace Ph2_HwInterface
       }
   }
 
-  void BeBoardInterface::SetFileHandler (BeBoard* pBoard, FileHandler* pHandler)
+  void BeBoardInterface::SetFileHandler (const BeBoard* pBoard, FileHandler* pHandler)
   {
     setBoard(pBoard->getBeBoardId());
     fBoardFW->setFileHandler(pHandler);
diff --git a/HWInterface/BeBoardInterface.h b/HWInterface/BeBoardInterface.h
index 4a607ee92..f0149620a 100644
--- a/HWInterface/BeBoardInterface.h
+++ b/HWInterface/BeBoardInterface.h
@@ -89,7 +89,7 @@ namespace Ph2_HwInterface
      * \param pBoard
      * \param pHandler : pointer to FileHandler object
      */
-    void SetFileHandler (Ph2_HwDescription::BeBoard* pBoard, FileHandler* pHandler);
+    void SetFileHandler (const Ph2_HwDescription::BeBoard* pBoard, FileHandler* pHandler);
 
     /*!
      * \brief enable the file handler
diff --git a/HWInterface/CbcInterface.cc b/HWInterface/CbcInterface.cc
index 4b134ee9f..fe0a93298 100644
--- a/HWInterface/CbcInterface.cc
+++ b/HWInterface/CbcInterface.cc
@@ -681,12 +681,12 @@ namespace Ph2_HwInterface
         }
     }
 
-    void CbcInterface::WriteModuleBroadcastChipReg ( const Module* pModule, const std::string& pRegNode, uint16_t pValue )
+    void CbcInterface::WriteModuleBroadcastChipReg ( const Module* pHybrid, const std::string& pRegNode, uint16_t pValue )
     {
         //first set the correct BeBoard
-        setBoard ( pModule->getBeBoardId() );
+        setBoard ( pHybrid->getBeBoardId() );
 
-        ChipRegItem cRegItem = pModule->fReadoutChipVector.at (0)->getRegItem ( pRegNode );
+        ChipRegItem cRegItem = static_cast<ReadoutChip*>(pHybrid->at(0))->getRegItem ( pRegNode );
         cRegItem.fValue = pValue;
 
         //vector for transaction
@@ -694,7 +694,7 @@ namespace Ph2_HwInterface
 
         // encode the reg specific to the FW, pVerifLoop decides if it should be read back, true means to write it
         // the 1st boolean could be true if I acually wanted to read back from each CBC but this somehow does not make sense!
-        fBoardFW->BCEncodeReg ( cRegItem, pModule->fReadoutChipVector.size(), cVec, false, true );
+        fBoardFW->BCEncodeReg ( cRegItem, pHybrid->size(), cVec, false, true );
 
         //true is the readback bit - the IC FW just checks that the transaction was successful and the
         //Strasbourg FW does nothing
@@ -707,15 +707,15 @@ namespace Ph2_HwInterface
 
         //update the HWDescription object -- not sure if the transaction was successfull
         if (cSuccess)
-            for (auto& cCbc : pModule->fReadoutChipVector)
-                cCbc->setReg ( pRegNode, pValue );
+            for (auto cCbc : *pHybrid)
+                static_cast<ReadoutChip*>(cCbc)->setReg ( pRegNode, pValue );
     }
 
 
-    void CbcInterface::WriteBroadcastCbcMultiReg (const Module* pModule, const std::vector<std::pair<std::string, uint8_t>> pVecReg)
+    void CbcInterface::WriteBroadcastCbcMultiReg (const Module* pHybrid, const std::vector<std::pair<std::string, uint8_t>> pVecReg)
     {
         //first set the correct BeBoard
-        setBoard ( pModule->getBeBoardId() );
+        setBoard ( pHybrid->getBeBoardId() );
 
         std::vector<uint32_t> cVec;
 
@@ -724,10 +724,10 @@ namespace Ph2_HwInterface
 
         for ( const auto& cReg : pVecReg )
         {
-            cRegItem = pModule->fReadoutChipVector.at (0)->getRegItem ( cReg.first );
+            cRegItem = static_cast<ReadoutChip*>(pHybrid->at(0))->getRegItem ( cReg.first );
             cRegItem.fValue = cReg.second;
 
-            fBoardFW->BCEncodeReg ( cRegItem, pModule->fReadoutChipVector.size(), cVec, false, true );
+            fBoardFW->BCEncodeReg ( cRegItem, pHybrid->size(), cVec, false, true );
             #ifdef COUNT_FLAG
                 fRegisterCount++;
             #endif
@@ -741,11 +741,11 @@ namespace Ph2_HwInterface
         #endif
 
         if (cSuccess)
-            for (auto& cCbc : pModule->fReadoutChipVector)
+            for (auto& cCbc : *pHybrid)
                 for (auto& cReg : pVecReg)
                 {
-                    cRegItem = cCbc->getRegItem ( cReg.first );
-                    cCbc->setReg ( cReg.first, cReg.second );
+                    cRegItem = static_cast<ReadoutChip*>(cCbc)->getRegItem ( cReg.first );
+                    static_cast<ReadoutChip*>(cCbc)->setReg ( cReg.first, cReg.second );
                 }
     }
 
diff --git a/HWInterface/D19cFWInterface.cc b/HWInterface/D19cFWInterface.cc
index 22fe3e35d..68f6de6a7 100755
--- a/HWInterface/D19cFWInterface.cc
+++ b/HWInterface/D19cFWInterface.cc
@@ -522,20 +522,24 @@ namespace Ph2_HwInterface
         // get link Ids 
         std::vector<uint8_t> cLinkIds;
         
-        for (auto& cFe : pBoard->fModuleVector)
+        for (auto cOpticalReadout : *pBoard)
         {
-            LOG (INFO) << BOLDBLUE << "Link " << +cFe->getLinkId() << RESET;
-            if ( std::find(cLinkIds.begin(), cLinkIds.end(), cFe->getLinkId() ) == cLinkIds.end() )
+            for (auto cHybrid : *cOpticalReadout)
             {
-                cLinkIds.push_back(cFe->getLinkId() );
-                //GBTInterface cControlGBTx;
-                //uint32_t cReadBack = cControlGBTx.icRead( this, 50 , 1); //watchdog on
-                //cControlGBTx.icWrite(this, 50, (cReadBack & 0xF8) |  0x7 );
-
-                //cControlGBTx.icWrite(this, 50, (cReadBack & 0xC7) |  (0x7 << 3 ));
-                //std::this_thread::sleep_for (std::chrono::milliseconds (200) );
-                //cControlGBTx.icWrite(this, 50, (cReadBack & 0xC7) |  (0x0 << 3 ));
-                //std::this_thread::sleep_for (std::chrono::milliseconds (200) );
+                Module* theHybrid = static_cast<Module*>(cHybrid);
+                LOG (INFO) << BOLDBLUE << "Link " << +theHybrid->getLinkId() << RESET;
+                if ( std::find(cLinkIds.begin(), cLinkIds.end(), theHybrid->getLinkId() ) == cLinkIds.end() )
+                {
+                    cLinkIds.push_back(theHybrid->getLinkId() );
+                    //GBTInterface cControlGBTx;
+                    //uint32_t cReadBack = cControlGBTx.icRead( this, 50 , 1); //watchdog on
+                    //cControlGBTx.icWrite(this, 50, (cReadBack & 0xF8) |  0x7 );
+
+                    //cControlGBTx.icWrite(this, 50, (cReadBack & 0xC7) |  (0x7 << 3 ));
+                    //std::this_thread::sleep_for (std::chrono::milliseconds (200) );
+                    //cControlGBTx.icWrite(this, 50, (cReadBack & 0xC7) |  (0x0 << 3 ));
+                    //std::this_thread::sleep_for (std::chrono::milliseconds (200) );
+                }
             }
         }
         //reset GBT-FPGA
@@ -597,10 +601,15 @@ namespace Ph2_HwInterface
     void D19cFWInterface::configureLink(const BeBoard* pBoard )
     {
         std::vector<uint8_t> cLinkIds(0);
-        for (auto& cFe : pBoard->fModuleVector)
+
+        for (auto& cOpticalReadout : *pBoard)
         {
-            if ( std::find(cLinkIds.begin(), cLinkIds.end(), cFe->getLinkId() ) == cLinkIds.end() )
-                cLinkIds.push_back(cFe->getLinkId() );
+            for (auto& cHybrid : *cOpticalReadout)
+            {
+                Module* theHybrid = static_cast<Module*>(cHybrid);
+                if ( std::find(cLinkIds.begin(), cLinkIds.end(), theHybrid->getLinkId() ) == cLinkIds.end() )
+                    cLinkIds.push_back(theHybrid->getLinkId() );
+            }
         }
 
         // now configure SCA + GBTx 
@@ -647,6 +656,7 @@ namespace Ph2_HwInterface
           std::this_thread::sleep_for (std::chrono::milliseconds (100) );
         }
     }
+
     void D19cFWInterface::ConfigureBoard ( const BeBoard* pBoard )
     {
         //this is where I should get all the clocking and FastCommandInterface settings
@@ -782,10 +792,14 @@ namespace Ph2_HwInterface
         }
         // unique link Ids
         std::vector<uint8_t> cLinkIds(0);
-        for (auto& cFe : pBoard->fModuleVector)
+        for (auto& cOpticalReadout : *pBoard)
         {
-            if ( std::find(cLinkIds.begin(), cLinkIds.end(), cFe->getLinkId() ) == cLinkIds.end() )
-                cLinkIds.push_back(cFe->getLinkId() );
+            for (auto& cHybrid : *cOpticalReadout)
+            {
+                Module* theHybrid = static_cast<Module*>(cHybrid);
+                if ( std::find(cLinkIds.begin(), cLinkIds.end(), theHybrid->getLinkId() ) == cLinkIds.end() )
+                    cLinkIds.push_back(theHybrid->getLinkId() );
+            }
         }
 
         // read info about current firmware
@@ -821,7 +835,7 @@ namespace Ph2_HwInterface
         if( fFirmwareFrontEndType == FrontEndType::CIC ||  fFirmwareFrontEndType == FrontEndType::CIC2 ) 
         {
             // assuming only one type of CIC per board ... 
-            auto& cCic = static_cast<OuterTrackerModule*>(pBoard->fModuleVector[0])->fCic;
+            auto& cCic = static_cast<OuterTrackerModule*>(pBoard->at(0)->at(0))->fCic;
             std::vector< std::pair<std::string, uint32_t> > cVecReg;
                 // make sure CIC is receiving clock 
             //cVecReg.push_back( {"fc7_daq_cnfg.physical_interface_block.cic.clock_enable" , 1 } ) ;
@@ -829,7 +843,7 @@ namespace Ph2_HwInterface
             cVecReg.push_back( {"fc7_daq_cnfg.stub_debug.enable" , 0 } ) ;
             std::string cFwRegName = "fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable";
             std::string cRegName = ( cCic->getFrontEndType()  == FrontEndType::CIC ) ? "CBC_SPARSIFICATION_SEL" : "FE_CONFIG"; 
-            ChipRegItem cRegItem = static_cast<OuterTrackerModule*>(pBoard->fModuleVector[0])->fCic->getRegItem (cRegName);
+            ChipRegItem cRegItem = static_cast<OuterTrackerModule*>(pBoard->at(0)->at(0))->fCic->getRegItem (cRegName);
             uint8_t cRegValue = (cCic->getFrontEndType()  == FrontEndType::CIC ) ? cRegItem.fValue  :  (cRegItem.fValue & 0x10) >> 4;
             LOG (INFO) << BOLDBLUE << "Sparsification set to " << +cRegValue << RESET;
             cVecReg.push_back( { cFwRegName , (cCic->getFrontEndType()  == FrontEndType::CIC ) ? cRegItem.fValue  :  (cRegItem.fValue & 0x10) >> 4}  ) ;
@@ -861,12 +875,16 @@ namespace Ph2_HwInterface
         // after firmware loading it seems that I need this ... so putting it in
         if( fFirmwareFrontEndType == FrontEndType::CIC || fFirmwareFrontEndType == FrontEndType::CIC2 ) 
         {
-            for (Module* cModule : pBoard->fModuleVector)
+            for (auto cOpticalGroup : *pBoard)
             {
+                for (auto cHybrid : *cOpticalGroup)
+                {
+                    Module* theHybrid = static_cast<Module*>(cHybrid);
                     if( pBoard->ifOptical() )
-                        this->selectLink(  cModule->getLinkId() );
+                        this->selectLink(  theHybrid->getLinkId() );
                     this->ChipReset();
-            }
+                }
+            }  
         }
         else
         {
@@ -893,72 +911,76 @@ namespace Ph2_HwInterface
         this->ChipReSync();
 
         // now check that I2C communication is functioning
-        for (Module* cFe : pBoard->fModuleVector)
+        for(auto cOpticalGroup : *pBoard)
         {
-            this->selectLink( cFe->getLinkId() );
-            std::vector<uint32_t> cVec; 
-            std::vector<uint32_t> cReplies;
-            uint8_t cChipsEnable=0x00;
-            LOG (INFO) << BOLDBLUE << "Enabling FE hybrid : " << +cFe->getFeId() << " - link Id " << +cFe->getLinkId() << RESET;
-            for ( Chip* cReadoutChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                cVec.clear();       
-                cReplies.clear();
-                // find first non-zero register in the map 
-                size_t cIndex=0;
-                auto cRegisterMap = cReadoutChip->getRegMap();
-                auto cIterator = cRegisterMap.begin();
-                do
-                {
-                  cIndex++;
-                  if( (*cIterator).second.fValue != 0 )
-                    cIterator++;
-                }while( (*cIterator).second.fValue != 0 && cIndex < cRegisterMap.size() );
-                ChipRegItem cRegItem = cReadoutChip->getRegItem (  (*cIterator).first );
-                bool cWrite=false;
-                this->EncodeReg( cRegItem, cFe->getFeId(), cReadoutChip->getChipId() , cVec , true, cWrite ) ; 
-                bool cWriteSuccess = !this->WriteI2C ( cVec, cReplies, true, false);
-                if( cWriteSuccess) 
+                Module* theHybrid = static_cast<Module*>(cHybrid);
+                this->selectLink( theHybrid->getLinkId() );
+                std::vector<uint32_t> cVec; 
+                std::vector<uint32_t> cReplies;
+                uint8_t cChipsEnable=0x00;
+                LOG (INFO) << BOLDBLUE << "Enabling FE hybrid : " << +theHybrid->getFeId() << " - link Id " << +theHybrid->getLinkId() << RESET;
+                for (auto cReadoutChip : *theHybrid)
                 {
-                    LOG (INFO) << BOLDGREEN << "Successful read from " << (*cIterator).first << " [first non-zero I2C register of CBC] on hybrid " << +cFe->getFeId() << " .... Enabling CBC" << +cReadoutChip->getChipId() << RESET;
-                    cChipsEnable |= ( 1 << cReadoutChip->getChipId());
-                    fNReadoutChip++;
+                    ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cReadoutChip);
+                    cVec.clear();       
+                    cReplies.clear();
+                    // find first non-zero register in the map 
+                    size_t cIndex=0;
+                    auto cRegisterMap = theReadoutChip->getRegMap();
+                    auto cIterator = cRegisterMap.begin();
+                    do
+                    {
+                    cIndex++;
+                    if( (*cIterator).second.fValue != 0 )
+                        cIterator++;
+                    }while( (*cIterator).second.fValue != 0 && cIndex < cRegisterMap.size() );
+                    ChipRegItem cRegItem = theReadoutChip->getRegItem (  (*cIterator).first );
+                    bool cWrite=false;
+                    this->EncodeReg( cRegItem, cHybrid->getId(), cReadoutChip->getId() , cVec , true, cWrite ) ; 
+                    bool cWriteSuccess = !this->WriteI2C ( cVec, cReplies, true, false);
+                    if( cWriteSuccess) 
+                    {
+                        LOG (INFO) << BOLDGREEN << "Successful read from " << (*cIterator).first << " [first non-zero I2C register of CBC] on hybrid " << +cHybrid->getId() << " .... Enabling CBC" << +cReadoutChip->getId() << RESET;
+                        cChipsEnable |= ( 1 << cReadoutChip->getId());
+                        fNReadoutChip++;
+                    }
                 }
-            }
-            char name[50];
-            std::sprintf (name, "fc7_daq_cnfg.global.chips_enable_hyb_%02d", cFe->getFeId() );
-            std::string name_str (name);
-            cVecReg.push_back ({name_str, cChipsEnable});
-            LOG (INFO) << BOLDBLUE << "Setting chips enable register on hybrid" << +cFe->getFeId() << " to " << std::bitset<32>( cChipsEnable ) << RESET;
-            
-            cVec.clear();
-            cReplies.clear();
-            if( fFirmwareFrontEndType == FrontEndType::CIC || fFirmwareFrontEndType == FrontEndType::CIC2 ) 
-            {
-                auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-                size_t cIndex=0;
-                auto cRegisterMap = cCic->getRegMap();
-                auto cIterator = cRegisterMap.begin();
-                do
-                {
-                  cIndex++;
-                  if( (*cIterator).second.fValue != 0 )
-                    cIterator++;
-                }while( (*cIterator).second.fValue != 0 && cIndex < cRegisterMap.size() );
-                ChipRegItem cRegItem = cCic->getRegItem ( (*cIterator).first );
-                bool cWrite=false;
-                this->EncodeReg( cRegItem, cFe->getFeId(), cCic->getChipId() , cVec , true, cWrite ) ; 
-                bool cWriteSuccess = !this->WriteI2C ( cVec, cReplies, true, false);
-                if( cWriteSuccess) 
+                char name[50];
+                std::sprintf (name, "fc7_daq_cnfg.global.chips_enable_hyb_%02d", cHybrid->getId() );
+                std::string name_str (name);
+                cVecReg.push_back ({name_str, cChipsEnable});
+                LOG (INFO) << BOLDBLUE << "Setting chips enable register on hybrid" << +cHybrid->getId() << " to " << std::bitset<32>( cChipsEnable ) << RESET;
+                
+                cVec.clear();
+                cReplies.clear();
+                if( fFirmwareFrontEndType == FrontEndType::CIC || fFirmwareFrontEndType == FrontEndType::CIC2 ) 
                 {
-                    LOG (INFO) << BOLDGREEN << "Successful read from " << (*cIterator).first << " [first non-zero I2C register of CIC] on hybrid " << +cFe->getFeId() << " .... Enabling CIC" << +cCic->getChipId() << RESET;
-                    hybrid_enable |= 1 << cFe->getFeId();
-                    fNCic++;
+                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                    size_t cIndex=0;
+                    auto cRegisterMap = cCic->getRegMap();
+                    auto cIterator = cRegisterMap.begin();
+                    do
+                    {
+                    cIndex++;
+                    if( (*cIterator).second.fValue != 0 )
+                        cIterator++;
+                    }while( (*cIterator).second.fValue != 0 && cIndex < cRegisterMap.size() );
+                    ChipRegItem cRegItem = cCic->getRegItem ( (*cIterator).first );
+                    bool cWrite=false;
+                    this->EncodeReg( cRegItem, cHybrid->getId(), cCic->getChipId() , cVec , true, cWrite ) ; 
+                    bool cWriteSuccess = !this->WriteI2C ( cVec, cReplies, true, false);
+                    if( cWriteSuccess) 
+                    {
+                        LOG (INFO) << BOLDGREEN << "Successful read from " << (*cIterator).first << " [first non-zero I2C register of CIC] on hybrid " << +cHybrid->getId() << " .... Enabling CIC" << +cCic->getChipId() << RESET;
+                        hybrid_enable |= 1 << cHybrid->getId();
+                        fNCic++;
+                    }
                 }
+                else if( fNReadoutChip == cHybrid->size() )
+                    hybrid_enable |= 1 << cHybrid->getId();
             }
-            else if( fNReadoutChip == cFe->fReadoutChipVector.size() )
-                hybrid_enable |= 1 << cFe->getFeId();
-
         }
         LOG (INFO) << BOLDBLUE << +fNCic <<  " CICs enabled." << RESET;
         cVecReg.push_back ({"fc7_daq_cnfg.global.hybrid_enable", hybrid_enable});
@@ -1526,37 +1548,40 @@ bool D19cFWInterface::L1PhaseTuning(const BeBoard* pBoard , bool pScope)
     PhaseTuner pTuner; 
     bool cSuccess=true;
     // back-end tuning on l1 lines
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalGroup : *pBoard)
     {
-        selectLink (cFe->getLinkId());
-        uint8_t cHybrid= cFe->getFeId() ;
-        uint8_t cChip = 0;
-        int cChipId = static_cast<OuterTrackerModule*>(cFe)->fCic->getChipId();
-        // need to know the address 
-        //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybrid) ;
-        // here in case you want to look at the L1A by scoping the lines in firmware - useful when debuging 
-        
-        uint8_t cLineId=0;
-        // tune phase on l1A line - don't have t do anything on the FEs
-        if( fOptical )
+        for (auto cHybrid : *cOpticalGroup)
         {
-            LOG (INFO) << BOLDBLUE << "Optical readout .. don't have to do anything here" << RESET;
-        }
-        else 
-        {
-            this->ChipReSync();
-            LOG (INFO) << BOLDBLUE << "Performing phase tuning [in the back-end] to prepare for receiving CIC L1A data ...: FE " << +cHybrid << " Chip" << +cChipId << RESET;
-            uint16_t cPattern = 0xAA;
-            // configure pattern
-            pTuner.SetLineMode(this, cHybrid, cChip  , cLineId, 0 );    
-            pTuner.SetLinePattern( this, cHybrid, cChip, cLineId , cPattern, 8);
-            std::this_thread::sleep_for (std::chrono::microseconds (10) );
-            // start phase aligner 
-            pTuner.SendControl(this, cHybrid, cChip, cLineId, "PhaseAlignment");
-            std::this_thread::sleep_for (std::chrono::microseconds (10) );
-            this->Start();
-            std::this_thread::sleep_for (std::chrono::milliseconds (100) );
-            this->Stop();
+            selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+            uint8_t cHybridId= cHybrid->getId() ;
+            uint8_t cChip = 0;
+            int cChipId = static_cast<OuterTrackerModule*>(cHybrid)->fCic->getChipId();
+            // need to know the address 
+            //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybridId) ;
+            // here in case you want to look at the L1A by scoping the lines in firmware - useful when debuging 
+            
+            uint8_t cLineId=0;
+            // tune phase on l1A line - don't have t do anything on the FEs
+            if( fOptical )
+            {
+                LOG (INFO) << BOLDBLUE << "Optical readout .. don't have to do anything here" << RESET;
+            }
+            else 
+            {
+                this->ChipReSync();
+                LOG (INFO) << BOLDBLUE << "Performing phase tuning [in the back-end] to prepare for receiving CIC L1A data ...: FE " << +cHybridId << " Chip" << +cChipId << RESET;
+                uint16_t cPattern = 0xAA;
+                // configure pattern
+                pTuner.SetLineMode(this, cHybridId, cChip  , cLineId, 0 );    
+                pTuner.SetLinePattern( this, cHybridId, cChip, cLineId , cPattern, 8);
+                std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                // start phase aligner 
+                pTuner.SendControl(this, cHybridId, cChip, cLineId, "PhaseAlignment");
+                std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                this->Start();
+                std::this_thread::sleep_for (std::chrono::milliseconds (100) );
+                this->Stop();
+            }
         }
     }
 
@@ -1623,93 +1648,96 @@ bool D19cFWInterface::L1WordAlignment(const BeBoard* pBoard , bool pScope)
     std::this_thread::sleep_for (std::chrono::microseconds (10) );
 
     // back-end tuning on l1 lines
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalReadout : *pBoard)
     {
-        uint8_t cBitslip=0;
-        selectLink (cFe->getLinkId());
-        uint8_t cHybrid= cFe->getFeId() ;
-        uint8_t cChip = 0;
-        int cChipId = static_cast<OuterTrackerModule*>(cFe)->fCic->getChipId();
-        // need to know the address 
-        //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybrid) ;
-        // here in case you want to look at the L1A by scoping the lines in firmware - useful when debuging 
-        
-        uint8_t cLineId=0;
-        this->ChipReSync();
-        LOG (INFO) << BOLDBLUE << "Performing word alignment [in the back-end] to prepare for receiving CIC L1A data ...: FE " << +cHybrid << " Chip" << +cChipId << RESET;
-        uint16_t cPattern = 0xFE;
-        // configure pattern
-        pTuner.SetLineMode(this, cHybrid, cChip  , cLineId, 0 );    
-        if( fFirmwareFrontEndType == FrontEndType::CIC || fFirmwareFrontEndType == FrontEndType::CIC2 ) 
-        {    
-            for(uint16_t cPatternLength=40; cPatternLength < 41; cPatternLength++)
-            {
-                pTuner.SetLinePattern( this, cHybrid, cChip, cLineId , cPattern, cPatternLength);
-                std::this_thread::sleep_for (std::chrono::microseconds (10) );
-                // start word aligner 
-                pTuner.SendControl(this, cHybrid, cChip, cLineId, "WordAlignment");
-                std::this_thread::sleep_for (std::chrono::microseconds (10) );
-                this->Start();
-                std::this_thread::sleep_for (std::chrono::milliseconds (500) );
-                this->Stop();
-                cSuccess = pTuner.fDone;
-            }
-            // if the above doesn't work.. try and find the correct bitslip manually in software 
-            if( !cSuccess)
-            {
-                LOG (INFO) << BOLDBLUE << "Going to try and align manually in software..." << RESET; 
-                for( cBitslip=0; cBitslip < 8; cBitslip++)
+        for (auto cHybrid : *cOpticalReadout)
+        {
+            uint8_t cBitslip=0;
+            selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+            uint8_t cHybridId= cHybrid->getId() ;
+            uint8_t cChip = 0;
+            int cChipId = static_cast<OuterTrackerModule*>(cHybrid)->fCic->getChipId();
+            // need to know the address 
+            //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybridId) ;
+            // here in case you want to look at the L1A by scoping the lines in firmware - useful when debuging 
+            
+            uint8_t cLineId=0;
+            this->ChipReSync();
+            LOG (INFO) << BOLDBLUE << "Performing word alignment [in the back-end] to prepare for receiving CIC L1A data ...: FE " << +cHybridId << " Chip" << +cChipId << RESET;
+            uint16_t cPattern = 0xFE;
+            // configure pattern
+            pTuner.SetLineMode(this, cHybridId, cChip  , cLineId, 0 );    
+            if( fFirmwareFrontEndType == FrontEndType::CIC || fFirmwareFrontEndType == FrontEndType::CIC2 ) 
+            {    
+                for(uint16_t cPatternLength=40; cPatternLength < 41; cPatternLength++)
                 {
-                    LOG (INFO) << BOLDMAGENTA << "Manually setting bitslip to " << +cBitslip << RESET;
-                    pTuner.SetLineMode( this, cHybrid , cChip , cLineId , 2 , 0, cBitslip, 0, 0 );
-                     this->Start();
-                    std::this_thread::sleep_for (std::chrono::microseconds (100) );
+                    pTuner.SetLinePattern( this, cHybridId, cChip, cLineId , cPattern, cPatternLength);
+                    std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                    // start word aligner 
+                    pTuner.SendControl(this, cHybridId, cChip, cLineId, "WordAlignment");
+                    std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                    this->Start();
+                    std::this_thread::sleep_for (std::chrono::milliseconds (500) );
                     this->Stop();
-                    
-                    auto cWords = ReadBlockReg("fc7_daq_stat.physical_interface_block.l1a_debug", 50);
-                    std::string cBuffer = "";
-                    bool cAligned=false;
-                    std::string cOutput="\n";
-                    for( auto cWord : cWords )
+                    cSuccess = pTuner.fDone;
+                }
+                // if the above doesn't work.. try and find the correct bitslip manually in software 
+                if( !cSuccess)
+                {
+                    LOG (INFO) << BOLDBLUE << "Going to try and align manually in software..." << RESET; 
+                    for( cBitslip=0; cBitslip < 8; cBitslip++)
                     {
-                        auto cString=std::bitset<32>(cWord).to_string();
-                        std::vector<std::string> cOutputWords(0);
-                        for( size_t cIndex = 0 ; cIndex < 4 ; cIndex++)
+                        LOG (INFO) << BOLDMAGENTA << "Manually setting bitslip to " << +cBitslip << RESET;
+                        pTuner.SetLineMode( this, cHybridId , cChip , cLineId , 2 , 0, cBitslip, 0, 0 );
+                        this->Start();
+                        std::this_thread::sleep_for (std::chrono::microseconds (100) );
+                        this->Stop();
+                        
+                        auto cWords = ReadBlockReg("fc7_daq_stat.physical_interface_block.l1a_debug", 50);
+                        std::string cBuffer = "";
+                        bool cAligned=false;
+                        std::string cOutput="\n";
+                        for( auto cWord : cWords )
                         {
-                            auto c8bitWord = cString.substr(cIndex*8, 8) ;
-                            cOutputWords.push_back(c8bitWord);
-                            cAligned = (cAligned | (std::stoi( c8bitWord , nullptr,2 ) == cPattern) );
+                            auto cString=std::bitset<32>(cWord).to_string();
+                            std::vector<std::string> cOutputWords(0);
+                            for( size_t cIndex = 0 ; cIndex < 4 ; cIndex++)
+                            {
+                                auto c8bitWord = cString.substr(cIndex*8, 8) ;
+                                cOutputWords.push_back(c8bitWord);
+                                cAligned = (cAligned | (std::stoi( c8bitWord , nullptr,2 ) == cPattern) );
+                            }
+                            for( auto cIt = cOutputWords.end()-1 ; cIt >= cOutputWords.begin() ; cIt--)
+                            {
+                                cOutput += *cIt + " "; 
+                            }
+                            cOutput += "\n";
                         }
-                        for( auto cIt = cOutputWords.end()-1 ; cIt >= cOutputWords.begin() ; cIt--)
+                        if( cAligned)
                         {
-                            cOutput += *cIt + " "; 
+                            LOG (INFO) << BOLDGREEN << cOutput << RESET;
+                            this->ResetReadout();
+                            cSuccess=true;
+                            break;
                         }
-                        cOutput += "\n";
-                    }
-                    if( cAligned)
-                    {
-                        LOG (INFO) << BOLDGREEN << cOutput << RESET;
-                        this->ResetReadout();
-                        cSuccess=true;
-                        break;
+                        else
+                            LOG (INFO) << BOLDRED << cOutput << RESET;
+                        this->ResetReadout(); 
                     }
-                    else
-                        LOG (INFO) << BOLDRED << cOutput << RESET;
-                    this->ResetReadout(); 
                 }
             }
-        }
-        else if( fFirmwareFrontEndType == FrontEndType::CBC3 )
-        {
+            else if( fFirmwareFrontEndType == FrontEndType::CBC3 )
+            {
 
-        }
-        else if( fFirmwareFrontEndType == FrontEndType::SSA )
-        {
+            }
+            else if( fFirmwareFrontEndType == FrontEndType::SSA )
+            {
 
-        }
-        else
-        {
-            LOG (INFO) << BOLDBLUE << "Word alignment in the back-end not implemented for this firmware type.." << RESET;
+            }
+            else
+            {
+                LOG (INFO) << BOLDBLUE << "Word alignment in the back-end not implemented for this firmware type.." << RESET;
+            }
         }
     }
     if( pScope )
@@ -1758,62 +1786,65 @@ bool D19cFWInterface::StubTuning(const BeBoard* pBoard, bool pScope)
     bool cSuccess=true;
 
     // back-end tuning on stub lines
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalGroup : *pBoard)
     {
-        selectLink (cFe->getLinkId());
-        uint8_t cHybrid= cFe->getFeId() ;
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
+        for (auto& cHybrid : *cOpticalGroup)
+        {
+            selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+            uint8_t cHybridId= cHybrid->getId() ;
+            auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
 
-        if( cCic == NULL )
-            continue;
+            if( cCic == NULL )
+                continue;
 
-        //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybrid) ;
-        if( pScope) 
-          this->StubDebug ();
+            //this->WriteReg( "fc7_daq_cnfg.physical_interface_block.cic.debug_select" , cHybridId) ;
+            if( pScope) 
+            this->StubDebug ();
 
-        LOG (INFO) << BOLDBLUE << "Performing phase tuning [in the back-end] to prepare for receiving CIC stub data ...: FE " << +cHybrid << " Chip" << +cCic->getChipId() << RESET;
-        uint8_t cNlines=6;
-        for( uint8_t cLineId=1; cLineId < cNlines; cLineId+=1)
-        {
-            if( fOptical )
+            LOG (INFO) << BOLDBLUE << "Performing phase tuning [in the back-end] to prepare for receiving CIC stub data ...: FE " << +cHybridId << " Chip" << +cCic->getChipId() << RESET;
+            uint8_t cNlines=6;
+            for( uint8_t cLineId=1; cLineId < cNlines; cLineId+=1)
             {
-                LOG (INFO) << BOLDBLUE << "\t..... running word alignment...." << RESET;
-                pTuner.SetLineMode( this, cHybrid , 0 , cLineId , 2 , 0, 1, 0, 0 );
-                std::this_thread::sleep_for (std::chrono::milliseconds (10) );
-                pTuner.SetLineMode(this, cHybrid, 0  , cLineId, 0 );    
-                std::this_thread::sleep_for (std::chrono::milliseconds (10) );
-                pTuner.SendControl(this, cHybrid, 0 , cLineId , "WordAlignment"); 
-                std::this_thread::sleep_for (std::chrono::milliseconds (50) );
-                //LOG (DEBUG) << BOLDBLUE << "Line status " << +cLineStatus << RESET;
-                uint8_t cAttempts=0;
-                if( pTuner.fBitslip == 0 )
+                if( fOptical )
                 {
-                    do
+                    LOG (INFO) << BOLDBLUE << "\t..... running word alignment...." << RESET;
+                    pTuner.SetLineMode( this, cHybridId , 0 , cLineId , 2 , 0, 1, 0, 0 );
+                    std::this_thread::sleep_for (std::chrono::milliseconds (10) );
+                    pTuner.SetLineMode(this, cHybridId, 0  , cLineId, 0 );    
+                    std::this_thread::sleep_for (std::chrono::milliseconds (10) );
+                    pTuner.SendControl(this, cHybridId, 0 , cLineId , "WordAlignment"); 
+                    std::this_thread::sleep_for (std::chrono::milliseconds (50) );
+                    //LOG (DEBUG) << BOLDBLUE << "Line status " << +cLineStatus << RESET;
+                    uint8_t cAttempts=0;
+                    if( pTuner.fBitslip == 0 )
                     {
-                        if( cAttempts > 10 )
+                        do
                         {
-                            LOG (INFO) << BOLDRED << "Back-end alignment FAILED. Stopping... " << RESET;
-                            exit(0);
-                        }
-                        // try again 
-                        LOG (INFO) << BOLDBLUE << "Trying to reset phase on GBTx... bit slip of 0!" << RESET;
-                        GbtInterface cGBTx;
-                        cGBTx.gbtxSetPhase(this, fGBTphase) ; 
-                        pTuner.SendControl(this, cHybrid, 0 , cLineId , "WordAlignment"); 
-                        std::this_thread::sleep_for (std::chrono::milliseconds (50) );
-                        cAttempts++;
-                    }while( pTuner.fBitslip == 0) ;
+                            if( cAttempts > 10 )
+                            {
+                                LOG (INFO) << BOLDRED << "Back-end alignment FAILED. Stopping... " << RESET;
+                                exit(0);
+                            }
+                            // try again 
+                            LOG (INFO) << BOLDBLUE << "Trying to reset phase on GBTx... bit slip of 0!" << RESET;
+                            GbtInterface cGBTx;
+                            cGBTx.gbtxSetPhase(this, fGBTphase) ; 
+                            pTuner.SendControl(this, cHybridId, 0 , cLineId , "WordAlignment"); 
+                            std::this_thread::sleep_for (std::chrono::milliseconds (50) );
+                            cAttempts++;
+                        }while( pTuner.fBitslip == 0) ;
+                    }
+                }
+                else
+                {
+                    pTuner.TuneLine(this,  cHybridId , 0 , cLineId , 0xEA , 8 , true);   
+                    cSuccess = cSuccess && pTuner.fDone;
+                }
+                if( pTuner.fDone != 1  ) 
+                {
+                    LOG (ERROR) << BOLDRED << "FAILED " << BOLDBLUE << " to tune stub line " << +(cLineId-1) << " in the back-end." << RESET;
+                    exit(0);
                 }
-            }
-            else
-            {
-                pTuner.TuneLine(this,  cHybrid , 0 , cLineId , 0xEA , 8 , true);   
-                cSuccess = cSuccess && pTuner.fDone;
-            }
-            if( pTuner.fDone != 1  ) 
-            {
-                LOG (ERROR) << BOLDRED << "FAILED " << BOLDBLUE << " to tune stub line " << +(cLineId-1) << " in the back-end." << RESET;
-                exit(0);
             }
         }
     }
@@ -1840,25 +1871,28 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
 
                 cVecReq.clear();
 
-                for (auto cFe : pBoard->fModuleVector)
+                for(auto cOpticalReadout : *pBoard)
                 {
-                    for (auto cCbc : cFe->fReadoutChipVector)
+                    for (auto cHybrid : *cOpticalReadout)
                     {
-
-                        uint8_t cOriginalStubLogicInput = cCbc->getReg ("Pipe&StubInpSel&Ptwidth");
-                        uint8_t cOriginalHipReg = cCbc->getReg ("HIP&TestMode");
-                        cStubLogictInputMap[cCbc] = cOriginalStubLogicInput;
-                        cHipRegMap[cCbc] = cOriginalHipReg;
+                        for (auto cCbc : *cHybrid)
+                        {
+                            ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                            uint8_t cOriginalStubLogicInput = theCbc->getReg ("Pipe&StubInpSel&Ptwidth");
+                            uint8_t cOriginalHipReg = theCbc->getReg ("HIP&TestMode");
+                            cStubLogictInputMap[theCbc] = cOriginalStubLogicInput;
+                            cHipRegMap[theCbc] = cOriginalHipReg;
 
 
-                        ChipRegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" );
-                        cRegItem.fValue = (cOriginalStubLogicInput & 0xCF) | (0x20 & 0x30);
-                        this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getChipId(), cVecReq, true, true);
+                            ChipRegItem cRegItem = theCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" );
+                            cRegItem.fValue = (cOriginalStubLogicInput & 0xCF) | (0x20 & 0x30);
+                            this->EncodeReg (cRegItem, cHybrid->getId(), cCbc->getId(), cVecReq, true, true);
 
-                        cRegItem = cCbc->getRegItem ( "HIP&TestMode" );
-                        cRegItem.fValue = (cOriginalHipReg & ~ (0x1 << 4) );
-                        this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getChipId(), cVecReq, true, true);
+                            cRegItem = theCbc->getRegItem ( "HIP&TestMode" );
+                            cRegItem.fValue = (cOriginalHipReg & ~ (0x1 << 4) );
+                            this->EncodeReg (cRegItem, cHybrid->getId(), cCbc->getId(), cVecReq, true, true);
 
+                        }
                     }
                 }
 
@@ -1876,19 +1910,22 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
                     {
                         LOG(ERROR) << BOLDRED << "Failed phase tuning, debug information: " << RESET;
                         // print statuses
-                        for (auto cFe : pBoard->fModuleVector)
+                        for(auto cOpticalGroup : *pBoard)
                         {
-                            for (auto cCbc : cFe->fReadoutChipVector)
+                            for (auto cHybrid : *cOpticalGroup)
                             {
-                            pTuner.GetLineStatus(this, cFe->getFeId(), cCbc->getChipId(), 5);//
-                            //PhaseTuningGetLineStatus(cFe->getFeId(), cCbc->getChipId(), 5);
+                                for (auto cCbc : *cHybrid)
+                                {
+                                pTuner.GetLineStatus(this, cHybrid->getId(), cCbc->getId(), 5);//
+                                //PhaseTuningGetLineStatus(cFe->getFeId(), cCbc->getChipId(), 5);
+                                }
                             }
                         }
                         exit (1);
                     }
 
-        this->ChipReSync();
-        usleep (10);
+                    this->ChipReSync();
+                    usleep (10);
                     // reset  the timing tuning
                     WriteReg ("fc7_daq_ctrl.physical_interface_block.control.cbc3_tune_again", 0x1);
 
@@ -1898,19 +1935,21 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
 
                     //re-enable the stub logic
                 cVecReq.clear();
-                for (auto cFe : pBoard->fModuleVector)
+                for(auto cOpticalGroup : *pBoard)
                 {
-                    for (auto cCbc : cFe->fReadoutChipVector)
+                    for (auto cHybrid : *cOpticalGroup)
                     {
-
-                        ChipRegItem cRegItem = cCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" );
-                        cRegItem.fValue = cStubLogictInputMap[cCbc];
-                        //this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getChipId(), cVecReq, true, true);
-
-                        cRegItem = cCbc->getRegItem ( "HIP&TestMode" );
-                        cRegItem.fValue = cHipRegMap[cCbc];
-                        this->EncodeReg (cRegItem, cCbc->getFeId(), cCbc->getChipId(), cVecReq, true, true);
-
+                        for (auto cCbc : *cHybrid)
+                        {
+                            ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                            ChipRegItem cRegItem = theCbc->getRegItem ( "Pipe&StubInpSel&Ptwidth" );
+                            cRegItem.fValue = cStubLogictInputMap[theCbc];
+                            //this->EncodeReg (cRegItem, theCbc->getFeId(), theCbc->getChipId(), cVecReq, true, true);
+
+                            cRegItem = theCbc->getRegItem ( "HIP&TestMode" );
+                            cRegItem.fValue = cHipRegMap[theCbc];
+                            this->EncodeReg (cRegItem, cHybrid->getId(), cCbc->getId(), cVecReq, true, true);
+                        }
                     }
                 }
 
@@ -1924,27 +1963,33 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
             uint8_t cDelay = 15;
             uint8_t cBitslip=3;
                 // manual mode apply
-            for (auto cFe : pBoard->fModuleVector)
+            for (auto cOpticalGroup : *pBoard)
             {
-                for (auto cCbc : cFe->fReadoutChipVector)
+                for (auto cHybrid : *cOpticalGroup)
                 {
-                    uint8_t cMode=2;
-                    uint8_t cMasterLine=0;
-                    uint8_t cEnableL1=0;
-                    for( uint8_t cLineId=0; cLineId<6; cLineId+=1)
-                        pTuner.SetLineMode( this, cCbc->getFeId() , cCbc->getChipId() , cLineId , cMode , cDelay, cBitslip, cEnableL1, cMasterLine );
+                    for (auto cCbc : *cHybrid)
+                    {
+                        uint8_t cMode=2;
+                        uint8_t cMasterLine=0;
+                        uint8_t cEnableL1=0;
+                        for( uint8_t cLineId=0; cLineId<6; cLineId+=1)
+                            pTuner.SetLineMode( this, cHybrid->getId() , cCbc->getId() , cLineId , cMode , cDelay, cBitslip, cEnableL1, cMasterLine );
 
+                    }
+                    }
+                    LOG (INFO) << GREEN << "CBC3 Phase tuning " << RESET << RED << "APPLIED" << RESET << GREEN <<" succesfully" << RESET;
                 }
-                }
-                LOG (INFO) << GREEN << "CBC3 Phase tuning " << RESET << RED << "APPLIED" << RESET << GREEN <<" succesfully" << RESET;
             }
                 // print statuses
-            for (auto cFe : pBoard->fModuleVector)
+            for (auto cOpticalGroup : *pBoard)
             {
-                for (auto cCbc : cFe->fReadoutChipVector)
+                for (auto cHybrid : *cOpticalGroup)
                 {
-                pTuner.GetLineStatus(this, cFe->getFeId(), cCbc->getChipId(), 5);//
-                //PhaseTuningGetLineStatus(cFe->getFeId(), cCbc->getChipId(), 5);
+                    for (auto cCbc : *cHybrid)
+                    {
+                    pTuner.GetLineStatus(this, cHybrid->getId(), cCbc->getId(), 5);//
+                    //PhaseTuningGetLineStatus(cHybrid->getFeId(), cCbc->getChipId(), 5);
+                    }
                 }
             }
 
@@ -1953,40 +1998,43 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
     else if (fFirmwareFrontEndType == FrontEndType::MPA)
     {
             // first need to set the proper i2c settings of the chip for the phase alignment
-            std::map<MPA*, uint8_t> cReadoutModeMap;
-            std::map<MPA*, uint8_t> cStubModeMap;
+            std::map<ChipContainer*, uint8_t> cReadoutModeMap;
+            std::map<ChipContainer*, uint8_t> cStubModeMap;
             std::vector<uint32_t> cVecReq;
 
             cVecReq.clear();
 
-            for (auto cFe : pBoard->fModuleVector)
+            for (auto cOpticalGroup : *pBoard)
             {
-                for (auto cMpa : static_cast<OuterTrackerModule*>(cFe)->fMPAVector)
+                for (auto *cHybrid : *cOpticalGroup)
                 {
+                    for (auto cMpa : *cHybrid)
+                    {
+                        ReadoutChip *theMpa = static_cast<ReadoutChip*>(cMpa);
+                        uint8_t cOriginalReadoutMode = theMpa->getReg ("ReadoutMode");
+                        uint8_t cOriginalStubMode = theMpa->getReg ("ECM");
+                        cReadoutModeMap[theMpa] = cOriginalReadoutMode;
+                        cStubModeMap[theMpa] = cOriginalStubMode;
+
+                            // sync mode
+                        ChipRegItem cRegItem = theMpa->getRegItem ( "ReadoutMode" );
+                        cRegItem.fValue = 0x00;
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cMpa->getId(), cVecReq, true, true);
+
+                        uint8_t cWriteAttempts = 0;
+                        this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
+                        cVecReq.clear();
+
+                            // ps stub mode
+                        cRegItem = theMpa->getRegItem ( "ECM" );
+                        cRegItem.fValue = 0x08;
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cMpa->getId(), cVecReq, true, true);
+
+                        cWriteAttempts = 0;
+                        this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
+                        cVecReq.clear();
 
-                    uint8_t cOriginalReadoutMode = cMpa->getReg ("ReadoutMode");
-                    uint8_t cOriginalStubMode = cMpa->getReg ("ECM");
-                    cReadoutModeMap[cMpa] = cOriginalReadoutMode;
-                    cStubModeMap[cMpa] = cOriginalStubMode;
-
-                        // sync mode
-                    ChipRegItem cRegItem = cMpa->getRegItem ( "ReadoutMode" );
-                    cRegItem.fValue = 0x00;
-                    this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true);
-
-                    uint8_t cWriteAttempts = 0;
-                    this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
-                    cVecReq.clear();
-
-                        // ps stub mode
-                    cRegItem = cMpa->getRegItem ( "ECM" );
-                    cRegItem.fValue = 0x08;
-                    this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true);
-
-                    cWriteAttempts = 0;
-                    this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
-                    cVecReq.clear();
-
+                    }
                 }
             }
 
@@ -1999,27 +2047,30 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
 
             //re-enable everything back
             cVecReq.clear();
-            for (auto cFe : pBoard->fModuleVector)
+            for (auto cOpticalGroup : *pBoard)
             {
-                for (auto cMpa : static_cast<OuterTrackerModule*>(cFe)->fMPAVector)
+                for (auto *cHybrid : *cOpticalGroup)
                 {
+                    for (auto cMpa : *cHybrid)
+                    {
+                        ReadoutChip *theMpa = static_cast<ReadoutChip*>(cMpa);
+                        ChipRegItem cRegItem = theMpa->getRegItem ( "ReadoutMode" );
+                        cRegItem.fValue = cReadoutModeMap[theMpa];
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cMpa->getId(), cVecReq, true, true);
 
-                    ChipRegItem cRegItem = cMpa->getRegItem ( "ReadoutMode" );
-                    cRegItem.fValue = cReadoutModeMap[cMpa];
-                    this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true);
-
-                    cWriteAttempts = 0;
-                    this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
-                    cVecReq.clear();
+                        cWriteAttempts = 0;
+                        this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
+                        cVecReq.clear();
 
-                    cRegItem = cMpa->getRegItem ( "ECM" );
-                    cRegItem.fValue = cStubModeMap[cMpa];
-                    this->EncodeReg (cRegItem, cMpa->getFeId(), cMpa->getMPAId(), cVecReq, true, true);
+                        cRegItem = theMpa->getRegItem ( "ECM" );
+                        cRegItem.fValue = cStubModeMap[cMpa];
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cMpa->getId(), cVecReq, true, true);
 
-                    cWriteAttempts = 0;
-                    this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
-                    cVecReq.clear();
+                        cWriteAttempts = 0;
+                        this->WriteChipBlockReg (cVecReq, cWriteAttempts, true);
+                        cVecReq.clear();
 
+                    }
                 }
             }
 
@@ -2033,104 +2084,110 @@ void D19cFWInterface::PhaseTuning (const BeBoard* pBoard)
     {
         LOG (INFO) << GREEN << "Trying Phase Tuning for SSA Chip(s)" << RESET;
 
-        std::map<Chip*, uint8_t> cReadoutModeMap; // stores mode settings of chips
-        std::map<Chip*, uint8_t> cStubModeMap; // stores stub output settings of chips
+        std::map<ChipContainer*, uint8_t> cReadoutModeMap; // stores mode settings of chips
+        std::map<ChipContainer*, uint8_t> cStubModeMap; // stores stub output settings of chips
         std::vector<uint32_t> cVecReq; // for communication (will be re-used... make sure it's cleared?)
 
         cVecReq.clear(); // bam
 
         // read back original values 
-        for (auto cFe : pBoard->fModuleVector) // probably could do this one step outside?
+        for (auto cOpticalGroup : *pBoard)
         {
-            for (auto cReadoutChip : cFe->fReadoutChipVector) // fills the modes to be stored (and re-applied later)
+            for (auto *cHybrid : *cOpticalGroup)
             {
-
-                uint8_t cOriginalReadoutMode = cReadoutChip->getReg ("ReadoutMode");
-                uint8_t cOriginalStubMode = cReadoutChip->getReg ("OutPattern0");
-                cReadoutModeMap[cReadoutChip] = cOriginalReadoutMode;
-                cStubModeMap[cReadoutChip] = cOriginalStubMode;
+                for (auto cReadoutChip : *cHybrid)
+                {
+                    uint8_t cOriginalReadoutMode = static_cast<ReadoutChip*>(cReadoutChip)->getReg ("ReadoutMode");
+                    uint8_t cOriginalStubMode = static_cast<ReadoutChip*>(cReadoutChip)->getReg ("OutPattern0");
+                    cReadoutModeMap[cReadoutChip] = cOriginalReadoutMode;
+                    cStubModeMap[cReadoutChip] = cOriginalStubMode;
+                }
             }
         }
 
         // configure patterns 
         std::vector<uint32_t> cVec(0); std::vector<uint32_t> cReplies(0); // might be superceding cVecReq?
-        for (auto cFe : pBoard->fModuleVector)
+        for (auto cOpticalGroup : *pBoard)
         {
-            for (auto cReadoutChip : cFe->fReadoutChipVector) // for each chip (makes sense)
+            for (auto *cHybrid : *cOpticalGroup)
             {
-                // configure SLVS drive strength and readout mode 
-                std::vector<std::string> cRegNames{ "SLVS_pad_current" , "ReadoutMode" };
-                std::vector<uint8_t> cRegValues{0x7 , 2}; 
-                uint16_t cOriginalMode=0;
-                for( size_t cIndex = 0 ;cIndex < 2 ; cIndex ++ )
+                for (auto cReadoutChip : *cHybrid)
                 {
-                    auto cRegItem = static_cast<ChipRegItem>(cReadoutChip->getRegItem ( cRegNames[cIndex] ));
-                    // read back original mode 
-                    if( cRegNames[cIndex] == "ReadoutMode") 
-                        cOriginalMode = cRegItem.fValue;
-                    
-                    cRegItem.fValue = cRegValues[cIndex];
-                    bool cWrite = true; 
-                    this->EncodeReg (cRegItem, cReadoutChip->getFeId(), cReadoutChip->getChipId(), cVec, true, cWrite);
-                    if( WriteI2C ( cVec, cReplies, true, false) )// return true if failed 
+                    ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cReadoutChip);
+                    // configure SLVS drive strength and readout mode 
+                    std::vector<std::string> cRegNames{ "SLVS_pad_current" , "ReadoutMode" };
+                    std::vector<uint8_t> cRegValues{0x7 , 2}; 
+                    uint16_t cOriginalMode=0;
+                    for( size_t cIndex = 0 ;cIndex < 2 ; cIndex ++ )
                     {
-                        LOG (INFO) << BOLDRED << "Failed to write to I2C register..." << RESET;
-                        exit(0);
+                        auto cRegItem = static_cast<ChipRegItem>(theReadoutChip->getRegItem ( cRegNames[cIndex] ));
+                        // read back original mode 
+                        if( cRegNames[cIndex] == "ReadoutMode") 
+                            cOriginalMode = cRegItem.fValue;
+                        
+                        cRegItem.fValue = cRegValues[cIndex];
+                        bool cWrite = true; 
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cReadoutChip->getId(), cVec, true, cWrite);
+                        if( WriteI2C ( cVec, cReplies, true, false) )// return true if failed 
+                        {
+                            LOG (INFO) << BOLDRED << "Failed to write to I2C register..." << RESET;
+                            exit(0);
+                        }
+                        cVec.clear(); cReplies.clear();
+                    } // all that did was set our pad current to max and our readout mode to transmit known patterns
+
+                    // configure output pattern on sutb lines 
+                    uint8_t cPattern = 0x80;
+                    for( uint8_t cLineId = 1 ; cLineId < 3 ; cLineId ++ )
+                    {
+                        PhaseTuner cTuner;
+                        char cBuffer[11];
+                        sprintf(cBuffer,"OutPattern%d", cLineId-1); 
+                        std::string cRegName = (cLineId == 8 ) ? "OutPattern7/FIFOconfig" : std::string(cBuffer,sizeof(cBuffer));
+                        auto cRegItem = static_cast<ChipRegItem>(theReadoutChip->getRegItem ( cRegName ));
+                        cRegItem.fValue = cPattern; 
+                        bool cWrite = true; 
+                        this->EncodeReg (cRegItem, cHybrid->getId(), cReadoutChip->getId(), cVec, true, cWrite);
+                        if( WriteI2C ( cVec, cReplies, true, false) )// return true if failed 
+                        {
+                            LOG (INFO) << BOLDRED << "Failed to write to I2C register..." << RESET;
+                            exit(0);
+                        }
+                        cVec.clear(); cReplies.clear();
+
+                        unsigned int cAttempts=0;
+                        bool cSuccess = false;
+                        cTuner.SetLineMode( this, cHybrid->getId() , cReadoutChip->getId() , cLineId , 2 , 0, 0, 0, 0 );
+                        do 
+                        {
+                            cSuccess = cTuner.TuneLine(this,  cHybrid->getId() , cReadoutChip->getId() , cLineId , cPattern , 8 , true);
+                            std::this_thread::sleep_for (std::chrono::milliseconds (200) );
+                            //LOG (INFO) << BOLDBLUE << "Automated phase tuning attempt" << cAttempts << " : " << ((cSuccess) ? "Worked" : "Failed") << RESET;
+                            cAttempts++;
+                        }while(!cSuccess && cAttempts <10);
+                        if( cLineId == 1 && cSuccess ) 
+                        {
+                            // force L1A line to match phase tuning result for first stub lines to match 
+                            uint8_t cEnableL1=0; 
+                            uint8_t cDelay = cTuner.fDelay;
+                            uint8_t cMode=2;
+                            uint8_t cBitslip = cTuner.fBitslip;
+                            cTuner.SetLineMode( this, cHybrid->getId() , cReadoutChip->getId() , 0 , cMode , cDelay, cBitslip, cEnableL1, 0 );
+                        }
                     }
-                    cVec.clear(); cReplies.clear();
-                } // all that did was set our pad current to max and our readout mode to transmit known patterns
 
-                // configure output pattern on sutb lines 
-                uint8_t cPattern = 0x80;
-                for( uint8_t cLineId = 1 ; cLineId < 3 ; cLineId ++ )
-                {
-                    PhaseTuner cTuner;
-                    char cBuffer[11];
-                    sprintf(cBuffer,"OutPattern%d", cLineId-1); 
-                    std::string cRegName = (cLineId == 8 ) ? "OutPattern7/FIFOconfig" : std::string(cBuffer,sizeof(cBuffer));
-                    auto cRegItem = static_cast<ChipRegItem>(cReadoutChip->getRegItem ( cRegName ));
-                    cRegItem.fValue = cPattern; 
+                    // set readout mode back to original value 
+                    auto cRegItem = static_cast<ChipRegItem>(theReadoutChip->getRegItem ( "ReadoutMode" ));
+                    cRegItem.fValue = cOriginalMode;
                     bool cWrite = true; 
-                    this->EncodeReg (cRegItem, cReadoutChip->getFeId(), cReadoutChip->getChipId(), cVec, true, cWrite);
+                    this->EncodeReg (cRegItem, cHybrid->getId(), cReadoutChip->getId(), cVec, true, cWrite);
                     if( WriteI2C ( cVec, cReplies, true, false) )// return true if failed 
                     {
                         LOG (INFO) << BOLDRED << "Failed to write to I2C register..." << RESET;
                         exit(0);
                     }
                     cVec.clear(); cReplies.clear();
-
-                    unsigned int cAttempts=0;
-                    bool cSuccess = false;
-                    cTuner.SetLineMode( this, cReadoutChip->getFeId() , cReadoutChip->getChipId() , cLineId , 2 , 0, 0, 0, 0 );
-                    do 
-                    {
-                        cSuccess = cTuner.TuneLine(this,  cReadoutChip->getFeId() , cReadoutChip->getChipId() , cLineId , cPattern , 8 , true);
-                        std::this_thread::sleep_for (std::chrono::milliseconds (200) );
-                        //LOG (INFO) << BOLDBLUE << "Automated phase tuning attempt" << cAttempts << " : " << ((cSuccess) ? "Worked" : "Failed") << RESET;
-                        cAttempts++;
-                    }while(!cSuccess && cAttempts <10);
-                    if( cLineId == 1 && cSuccess ) 
-                    {
-                        // force L1A line to match phase tuning result for first stub lines to match 
-                        uint8_t cEnableL1=0; 
-                        uint8_t cDelay = cTuner.fDelay;
-                        uint8_t cMode=2;
-                        uint8_t cBitslip = cTuner.fBitslip;
-                        cTuner.SetLineMode( this, cReadoutChip->getFeId() , cReadoutChip->getChipId() , 0 , cMode , cDelay, cBitslip, cEnableL1, 0 );
-                    }
-                }
-
-                // set readout mode back to original value 
-                auto cRegItem = static_cast<ChipRegItem>(cReadoutChip->getRegItem ( "ReadoutMode" ));
-                cRegItem.fValue = cOriginalMode;
-                bool cWrite = true; 
-                this->EncodeReg (cRegItem, cReadoutChip->getFeId(), cReadoutChip->getChipId(), cVec, true, cWrite);
-                if( WriteI2C ( cVec, cReplies, true, false) )// return true if failed 
-                {
-                    LOG (INFO) << BOLDRED << "Failed to write to I2C register..." << RESET;
-                    exit(0);
                 }
-                cVec.clear(); cReplies.clear();
             }
         }
         LOG (INFO) << GREEN << "SSA Phase tuning finished succesfully" << RESET;
@@ -2441,11 +2498,14 @@ uint32_t D19cFWInterface::computeEventSize ( BeBoard* pBoard )
 
     uint32_t cNEventSize32 = 0;
 
-    for (const auto& cFe : pBoard->fModuleVector)
+    for(const auto cOpticalGroup : *pBoard)
     {
-        cNCbc += cFe->getNChip();
-        cNMPA += static_cast<OuterTrackerModule*>(cFe)->getNMPA();
-        cNSSA += static_cast<OuterTrackerModule*>(cFe)->getNSSA();
+        for (const auto cHybrid : *cOpticalGroup)
+        {
+            cNCbc += cHybrid->size();
+            cNMPA += cHybrid->size();
+            cNSSA += cHybrid->size();
+        }
     }
     if( fNCic != 0 ) 
     {
diff --git a/HWInterface/RD53FWInterface.cc b/HWInterface/RD53FWInterface.cc
index deb80019f..5e57e98b3 100644
--- a/HWInterface/RD53FWInterface.cc
+++ b/HWInterface/RD53FWInterface.cc
@@ -131,15 +131,15 @@ namespace Ph2_HwInterface
     this->singleChip  = ReadReg("user.stat_regs.aurora_rx.Module_type") == 1;
     uint32_t chips_en = 0;
     enabledModules    = 0;
-    for (const auto& cModule : pBoard->fModuleVector)
+    for (const auto cHybrid : *pBoard->at(0)) //Fabio::FIXME
       {
-        uint16_t module_id = cModule->getFeId(); // @TMP@
+        uint16_t module_id = cHybrid->getId(); // @TMP@
         enabledModules |= 1 << module_id;
         if (this->singleChip == true) chips_en = enabledModules;
         else
           {
             uint16_t mod_chips_en = 0;
-            for (const auto cChip : *cModule)
+            for (const auto cChip : *cHybrid)
               {
                 uint16_t chip_lane = static_cast<RD53*>(cChip)->getChipLane();
                 mod_chips_en |= 1 << chip_lane;
@@ -836,12 +836,12 @@ namespace Ph2_HwInterface
     // #############################
     if (pBoard != nullptr)
       {
-        Module* module = pBoard->getModule(module_id);
+        Module* module = static_cast<Module*>(pBoard->at(0)->at(module_id)); //Fabio::FIXME
         if (module != nullptr)
           {
-            auto it = std::find_if(module->fReadoutChipVector.begin(), module->fReadoutChipVector.end(), [=] (ReadoutChip* pChip)
+            auto it = std::find_if(module->begin(), module->end(), [=] (ChipContainer* pChip)
                                    { return static_cast<RD53*>(pChip)->getChipLane() == chip_lane; });
-            if (it != module->fReadoutChipVector.end()) return (*it)->getChipId();
+            if (it != module->end()) return (*it)->getId();
           }
       }
     return -1; // Chip not found
diff --git a/HWInterface/RD53Interface.cc b/HWInterface/RD53Interface.cc
index 3aa3c2ab0..aac3be1c0 100644
--- a/HWInterface/RD53Interface.cc
+++ b/HWInterface/RD53Interface.cc
@@ -191,7 +191,7 @@ namespace Ph2_HwInterface
   {
     this->setBoard(pBoard->getId());
 
-    uint16_t address = pBoard->fModuleVector.at(0)->fReadoutChipVector.at(0)->getRegItem(pRegNode).fAddress;
+    uint16_t address = static_cast<RD53*>(pBoard->at(0)->at(0)->at(0))->getRegItem(pRegNode).fAddress;
     static_cast<RD53FWInterface*>(fBoardFW)->WriteChipCommand(RD53Cmd::WrReg(RD53Constants::BROADCAST_CHIPID, address, data).getFrames(), -1);
   }
 
diff --git a/System/FileParser.cc b/System/FileParser.cc
index ba5413015..23bc744ab 100644
--- a/System/FileParser.cc
+++ b/System/FileParser.cc
@@ -10,16 +10,16 @@ using namespace Ph2_HwInterface;
 
 namespace Ph2_System
 {
-  void FileParser::parseHW (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile)
+  void FileParser::parseHW (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile)
   {
     //FIXME-FR
     if (pIsFile && pFilename.find(".xml") != std::string::npos)
       {
-        parseHWxml(pFilename, pBeBoardFWMap, pBoardVector, pDetectorContainer, os, pIsFile);
+        parseHWxml(pFilename, pBeBoardFWMap, pDetectorContainer, os, pIsFile);
       }
     else if (!pIsFile)
       {
-        parseHWxml(pFilename, pBeBoardFWMap, pBoardVector, pDetectorContainer, os, pIsFile);
+        parseHWxml(pFilename, pBeBoardFWMap, pDetectorContainer, os, pIsFile);
       }
     else
       {
@@ -38,7 +38,7 @@ namespace Ph2_System
       LOG (ERROR) << "Could not parse settings file " << pFilename << " - it is not .xm";
   }
 
-  void FileParser::parseHWxml (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile)
+  void FileParser::parseHWxml (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile)
   {
     int i, j;
 
@@ -77,7 +77,7 @@ namespace Ph2_System
       {
         if (static_cast<std::string>(cBeBoardNode.name()) == "BeBoard")
           {
-            this->parseBeBoard(cBeBoardNode, pBeBoardFWMap, pBoardVector, pDetectorContainer, os);
+            this->parseBeBoard(cBeBoardNode, pBeBoardFWMap, pDetectorContainer, os);
           }
       }
 
@@ -95,12 +95,11 @@ namespace Ph2_System
       os << "*";
   }
 
-  void FileParser::parseBeBoard (pugi::xml_node pBeBordNode, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os)
+  void FileParser::parseBeBoard (pugi::xml_node pBeBordNode, BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os)
   {
     uint32_t cBeId = pBeBordNode.attribute("Id").as_int();
     BeBoard* cBeBoard = pDetectorContainer->addBoardContainer(cBeId, new BeBoard(cBeId));//FIX Change it to Reference!!!!
-    pBoardVector.emplace_back(cBeBoard);
-
+    
     pugi::xml_attribute cBoardTypeAttribute = pBeBordNode.attribute("boardType");
 
     if (cBoardTypeAttribute == nullptr)
@@ -378,24 +377,25 @@ namespace Ph2_System
 
                     //ok, now I need to loop th CBCs to find page & address and the initial value
 
-                    for (auto cFe : pBoard->fModuleVector )
-                      {
-                        if (cFe->getFeId() != cFeId) continue;
-
-                        for (auto cCbc : cFe->fReadoutChipVector )
-                          {
-                            if (cCbc->getChipId() != cCbcId) continue;
-                            else if (cCbc->getFeId() == cFeId && cCbc->getChipId() == cCbcId)
-                              {
-                                ChipRegItem cRegItem = cCbc->getRegItem ( cRegName );
-                                cPage = cRegItem.fPage;
-                                cAddress = cRegItem.fAddress;
-                                cValue = cRegItem.fValue;
-                              }
-                            else
-                              LOG (ERROR) << RED << "SLINK ERROR: no Chip with Id " << +cCbcId << " on Fe " << +cFeId << " - check your SLink Settings!";
-                          }
-                      }
+                    for(auto cOpticalGroup : *pBoard)
+                      for (auto cHybrid : *cOpticalGroup)
+                        {
+                          if (cHybrid->getId() != cFeId) continue;
+
+                          for (auto cCbc : *cHybrid)
+                            {
+                              if (cCbc->getId() != cCbcId) continue;
+                              else if (cHybrid->getId() == cFeId && cCbc->getId() == cCbcId)
+                                {
+                                  ChipRegItem cRegItem = static_cast<ReadoutChip*>(cCbc)->getRegItem ( cRegName );
+                                  cPage = cRegItem.fPage;
+                                  cAddress = cRegItem.fAddress;
+                                  cValue = cRegItem.fValue;
+                                }
+                              else
+                                LOG (ERROR) << RED << "SLINK ERROR: no Chip with Id " << +cCbcId << " on Fe " << +cFeId << " - check your SLink Settings!";
+                            }
+                        }
                   }
 
                 cSet->addCondData (cRegName, cUID, cFeId, cCbcId, cPage, cAddress, cValue);
@@ -423,8 +423,7 @@ namespace Ph2_System
                 cFileName = cFilePrefix + expandEnvironmentVariables (pModuleNode.attribute ( "configfile" ).value() );
             }
             else cFileName = expandEnvironmentVariables (pModuleNode.attribute ( "configfile" ).value() );
-        ReadoutChip* cSSA = pModule->addChipContainer(cChipId, new SSA ( pModule->getBeId(), pModule->getFMCId(), pModule->getFeId(), cChipId, 0, cFileName ));
-            pModule->addReadoutChip (cSSA);
+          ReadoutChip* cSSA = pModule->addChipContainer(cChipId, new SSA ( pModule->getBeId(), pModule->getFMCId(), pModule->getFeId(), cChipId, 0, cFileName ));
             cSSA->setNumberOfChannels(120);
         this->parseSSASettings (pModuleNode, cSSA);
     }
@@ -456,7 +455,7 @@ namespace Ph2_System
         else
           {
             cModule = pOpticalGroup->addModuleContainer( pModuleNode.attribute ( "FeId" ).as_int(), new OuterTrackerModule ( pOpticalGroup->getBeBoardId(), pOpticalGroup->getFMCId(), pModuleNode.attribute ( "FeId" ).as_int(),  pModuleNode.attribute ( "FeId" ).as_int() ));
-            cModule->setLinkId( pModuleNode.attribute ( "LinkId" ).as_int() );
+            static_cast<OuterTrackerModule*>(cModule)->setLinkId( pModuleNode.attribute ( "LinkId" ).as_int() );
           }
         // pOpticalGroup->addModule ( cModule );
 
@@ -588,7 +587,6 @@ namespace Ph2_System
 
     uint32_t cChipId = pCbcNode.attribute ( "Id" ).as_int();
     ReadoutChip* cCbc = cModule->addChipContainer( cChipId, new Cbc ( cModule->getBeId(), cModule->getFMCId(), cModule->getFeId(), cChipId, cFileName ));
-    cModule->addReadoutChip (cCbc);
     cCbc->setNumberOfChannels(254);
 
     // parse the specific CBC settings so that Registers take precedence
@@ -616,14 +614,14 @@ namespace Ph2_System
 
         int cCounter = 0;
 
-        for (auto cCbc : pModule->fReadoutChipVector)
+          for (auto cCbc : *pModule)
           {
             if (cCounter == 0)
-              this->parseCbcSettings (cGlobalCbcSettingsNode, cCbc, os);
+              this->parseCbcSettings (cGlobalCbcSettingsNode, static_cast<ReadoutChip*>(cCbc), os);
             else
               {
                 std::ofstream cDummy;
-                this->parseCbcSettings (cGlobalCbcSettingsNode, cCbc, cDummy);
+                this->parseCbcSettings (cGlobalCbcSettingsNode, static_cast<ReadoutChip*>(cCbc), cDummy);
               }
 
             cCounter++;
@@ -638,8 +636,8 @@ namespace Ph2_System
             std::string regname = std::string ( cCbcGlobalNode.attribute ( "name" ).value() );
             uint32_t regvalue = convertAnyInt ( cCbcGlobalNode.first_child().value() ) ;
 
-            for (auto cCbc : pModule->fReadoutChipVector)
-              cCbc->setReg ( regname, uint8_t ( regvalue ) ) ;
+            for (auto cCbc : *pModule)
+              static_cast<ReadoutChip*>(cCbc)->setReg ( regname, uint8_t ( regvalue ) ) ;
 
             os << BOLDGREEN << "|" << " " << "|" << "   " << "|" << "----" << cCbcGlobalNode.name()
                << "  " << cCbcGlobalNode.first_attribute().name() << " :"
@@ -889,7 +887,6 @@ namespace Ph2_System
 
     this->parseRD53Settings(theChipNode, theChip, os);
 
-    cModule->addReadoutChip(theChip);
   }
 
   void FileParser::parseGlobalRD53Settings (pugi::xml_node pModuleNode, Module* pModule, std::ostream& os)
@@ -905,7 +902,7 @@ namespace Ph2_System
             uint16_t regvalue   = convertAnyInt(attr.value());
             os << GREEN << "|\t|\t|\t|----" << regname << ": " << BOLDYELLOW << std::hex << "0x" << std::uppercase << regvalue << std::dec << " (" << regvalue << ")" << RESET << std::endl;
 
-            for (auto theChip : pModule->fReadoutChipVector) theChip->setReg(regname,regvalue,true);
+            for (auto theChip : *pModule) static_cast<ReadoutChip*>(theChip)->setReg(regname,regvalue,true);
           }
       }
   }
diff --git a/System/FileParser.h b/System/FileParser.h
index b6eb5f625..0a8f794b3 100644
--- a/System/FileParser.h
+++ b/System/FileParser.h
@@ -51,7 +51,7 @@ namespace Ph2_System
     FileParser()  {}
     ~FileParser() {}
 
-    void parseHW      (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile );
+    void parseHW      (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile );
     void parseSettings(const std::string& pFilename, SettingsMap&  pSettingsMap,                                                                   std::ostream& os, bool pIsFile );
 
   protected:
@@ -71,7 +71,7 @@ namespace Ph2_System
      * \param pFilename : HW Description file
      *\param os : ostream to dump output
      */
-    void parseHWxml (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile);
+    void parseHWxml (const std::string& pFilename, BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os, bool pIsFile);
 
     /*!
      * \brief Initialize the hardware via xml config file
@@ -80,7 +80,7 @@ namespace Ph2_System
      */
     void parseSettingsxml ( const std::string& pFilename, SettingsMap& pSettingsMap, std::ostream& os, bool pIsFile );
 
-    void parseBeBoard                (pugi::xml_node pBeBordNode,   BeBoardFWMap& pBeBoardFWMap, BeBoardVec& pBoardVector, DetectorContainer* pDetectorContainer, std::ostream& os );
+    void parseBeBoard                (pugi::xml_node pBeBordNode,   BeBoardFWMap& pBeBoardFWMap, DetectorContainer* pDetectorContainer, std::ostream& os );
     void parseRegister               (pugi::xml_node pRegisterNode, std::string& pAttributeString, uint32_t& pValue, Ph2_HwDescription::BeBoard* pBoard, std::ostream& os );
     void parseSLink                  (pugi::xml_node pSLinkNode       , Ph2_HwDescription::BeBoard*      pBoard       , std::ostream& os );
     void parseOpticalGroupContainer  (pugi::xml_node pOpticalGroupNode, Ph2_HwDescription::BeBoard*      pBoard       , std::ostream& os );
diff --git a/System/SystemController.cc b/System/SystemController.cc
index 54354b578..069bf3a9f 100644
--- a/System/SystemController.cc
+++ b/System/SystemController.cc
@@ -19,7 +19,6 @@ namespace Ph2_System
     , fReadoutChipInterface(nullptr)
     , fChipInterface       (nullptr)
     , fDetectorContainer   (nullptr)
-    , fBoardVector         ()
     , fSettingsMap         ()
     , fFileHandler         (nullptr)
     , fRawFileName         ("")
@@ -35,7 +34,6 @@ namespace Ph2_System
     fBeBoardInterface     = pController->fBeBoardInterface;
     fReadoutChipInterface = pController->fReadoutChipInterface;
     fChipInterface        = pController->fChipInterface;
-    fBoardVector          = pController->fBoardVector;
     fBeBoardFWMap         = pController->fBeBoardFWMap;
     fSettingsMap          = pController->fSettingsMap;
     fFileHandler          = pController->fFileHandler;
@@ -99,12 +97,13 @@ namespace Ph2_System
     if (streamData == true) fNetworkStreamer = new TCPPublishServer(6000,1);
 
     fDetectorContainer = new DetectorContainer;
-    this->fParser.parseHW(pFilename, fBeBoardFWMap, fBoardVector, fDetectorContainer, os, pIsFile);
+    this->fParser.parseHW(pFilename, fBeBoardFWMap, fDetectorContainer, os, pIsFile);
 
     fBeBoardInterface = new BeBoardInterface(fBeBoardFWMap);
-    if (fBoardVector[0]->getBoardType() != BoardType::RD53)
+    const BeBoard *theFirstBoard = static_cast<const BeBoard*>(fDetectorContainer->at(0));
+    if (theFirstBoard->getBoardType() != BoardType::RD53)
       {
-        if (fBoardVector[0]->getEventType() != EventType::SSA) fReadoutChipInterface = new CbcInterface(fBeBoardFWMap);
+        if (theFirstBoard->getEventType() != EventType::SSA) fReadoutChipInterface = new CbcInterface(fBeBoardFWMap);
         else                                                   fReadoutChipInterface = new SSAInterface(fBeBoardFWMap);
         fCicInterface = new CicInterface(fBeBoardFWMap);
         fMPAInterface = new MPAInterface(fBeBoardFWMap);
@@ -125,60 +124,66 @@ namespace Ph2_System
   {
     LOG (INFO) << BOLDMAGENTA << "@@@ Configuring HW parsed from .xml file @@@" << RESET;
 
-    for (auto& cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
       {
-        if (cBoard->getBoardType() != BoardType::RD53)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        if (theBoard->getBoardType() != BoardType::RD53)
           {
             //setting up back-end board
-            fBeBoardInterface->ConfigureBoard ( cBoard );
-            LOG (INFO) << GREEN << "Successfully configured Board " << int ( cBoard->getBeId() ) << RESET;
-            LOG (INFO) << BOLDBLUE << "Now going to configure chips on Board " << int ( cBoard->getBeId() ) << RESET;
+            fBeBoardInterface->ConfigureBoard ( theBoard );
+            LOG (INFO) << GREEN << "Successfully configured Board " << int ( cBoard->getId() ) << RESET;
+            LOG (INFO) << BOLDBLUE << "Now going to configure chips on Board " << int ( cBoard->getId() ) << RESET;
 
             // CIC start-up
-            for (auto& cFe : cBoard->fModuleVector)
-              {
-                if( static_cast<OuterTrackerModule*>(cFe)->fCic != NULL )
-                  {
-                    static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-                    auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-
-                    // read CIC sparsification setting 
-                    bool cSparsified = (fBeBoardInterface->ReadBoardReg(cBoard,"fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable") == 1);
-                    cBoard->setSparsification( cSparsified );
-
-                    LOG (INFO) << BOLDBLUE << "Configuring CIC" << +(cFe->getFeId()%2) << " on link " << +cFe->getLinkId() << " on hybrid " << +cFe->getFeId() << RESET;
-                    fCicInterface->ConfigureChip( static_cast<OuterTrackerModule*>(cFe)->fCic);
-
-                    // CIC start-up
-                    uint8_t cModeSelect = (cFe->fReadoutChipVector[0]->getFrontEndType() != FrontEndType::CBC3); // 0 --> CBC , 1 --> MPA
-                    // select CIC mode
-                    bool cSuccess = fCicInterface->SelectMode( static_cast<OuterTrackerModule*>(cFe)->fCic, cModeSelect );
-                    if(!cSuccess)
-                      {
-                        LOG (INFO) << BOLDRED << "FAILED " << BOLDBLUE << " to configure CIC mode.." << RESET;
-                        exit(0);
-                      }
-                    // CIC start-up sequence
-                    uint8_t cDriveStrength = 5;
-                    cSuccess = fCicInterface->StartUp(cCic , cDriveStrength);
-                    for (auto& cChip : cFe->fReadoutChipVector)
-                      {
-                        fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 1);
-                      }
-                    fBeBoardInterface->ChipReSync ( cBoard );
-                    LOG (INFO) << BOLDGREEN << "SUCCESSFULLY " << BOLDBLUE << " performed start-up sequence on CIC" << +(cFe->getFeId()%2) << " connected to link " << +cFe->getLinkId() <<  RESET ;
-                    LOG (INFO) << BOLDGREEN << "####################################################################################" << RESET;
-                  }
-                // Configure readout-chips [CBCs, MPAs, SSAs]
-                for (auto& cReadoutChip : cFe->fReadoutChipVector)
-                  {
-                    if ( !bIgnoreI2c ) 
-                      {
-                        LOG (INFO) << BOLDBLUE << "Configuring readout chip [CBC" << +cReadoutChip->getChipId() << " ]" << RESET;
-                        fReadoutChipInterface->ConfigureChip ( cReadoutChip );
-                      }
-                  }
-              }
+            for(auto cOpticalGroup : *cBoard)
+            {
+              for (auto cHybrid : *cOpticalGroup)
+                {
+                  OuterTrackerModule* theOuterTrackerModule = static_cast<OuterTrackerModule*>(cHybrid);
+                  if( theOuterTrackerModule->fCic != NULL )
+                    {
+                      static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (theOuterTrackerModule->getLinkId());
+                      auto& cCic = theOuterTrackerModule->fCic;
+
+                      // read CIC sparsification setting 
+                      bool cSparsified = (fBeBoardInterface->ReadBoardReg(theBoard,"fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable") == 1);
+                      theBoard->setSparsification( cSparsified );
+
+                      LOG (INFO) << BOLDBLUE << "Configuring CIC" << +(theOuterTrackerModule->getFeId()%2) << " on link " << +theOuterTrackerModule->getLinkId() << " on hybrid " << +theOuterTrackerModule->getFeId() << RESET;
+                      fCicInterface->ConfigureChip( theOuterTrackerModule->fCic);
+
+                      // CIC start-up
+                      uint8_t cModeSelect = (static_cast<ReadoutChip*>(theOuterTrackerModule->at(0))->getFrontEndType() != FrontEndType::CBC3); // 0 --> CBC , 1 --> MPA
+                      // select CIC mode
+                      bool cSuccess = fCicInterface->SelectMode( theOuterTrackerModule->fCic, cModeSelect );
+                      if(!cSuccess)
+                        {
+                          LOG (INFO) << BOLDRED << "FAILED " << BOLDBLUE << " to configure CIC mode.." << RESET;
+                          exit(0);
+                        }
+                      // CIC start-up sequence
+                      uint8_t cDriveStrength = 5;
+                      cSuccess = fCicInterface->StartUp(cCic , cDriveStrength);
+                      for (auto cChip : *cHybrid)
+                        {
+                          fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 1);
+                        }
+                      fBeBoardInterface->ChipReSync ( theBoard );
+                      LOG (INFO) << BOLDGREEN << "SUCCESSFULLY " << BOLDBLUE << " performed start-up sequence on CIC" << +(theOuterTrackerModule->getId()%2) << " connected to link " << +theOuterTrackerModule->getLinkId() <<  RESET ;
+                      LOG (INFO) << BOLDGREEN << "####################################################################################" << RESET;
+                    }
+                  // Configure readout-chips [CBCs, MPAs, SSAs]
+                  for (auto cReadoutChip : *cHybrid)
+                    {
+                      ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cReadoutChip);
+                      if ( !bIgnoreI2c ) 
+                        {
+                          LOG (INFO) << BOLDBLUE << "Configuring readout chip [CBC" << +cReadoutChip->getId() << " ]" << RESET;
+                          fReadoutChipInterface->ConfigureChip ( theReadoutChip );
+                        }
+                    }
+                }
+            }
           }
         else
           {
@@ -186,8 +191,8 @@ namespace Ph2_System
             // # Configuring Inner Tracker hardware #
             // ######################################
             LOG (INFO) << BOLDBLUE << "\t--> Found an Inner Tracker board" << RESET;
-            LOG (INFO) << GREEN << "Configuring Board: " << RESET << BOLDYELLOW << +cBoard->getBeId() << RESET;
-            fBeBoardInterface->ConfigureBoard(cBoard);
+            LOG (INFO) << GREEN << "Configuring Board: " << RESET << BOLDYELLOW << +cBoard->getId() << RESET;
+            fBeBoardInterface->ConfigureBoard(theBoard);
 
 
             // ###################
@@ -197,29 +202,32 @@ namespace Ph2_System
             size_t injType     = SystemController::findValueInSettings("INJtype");
             size_t nClkDelays  = SystemController::findValueInSettings("nClkDelays");
             size_t colStart    = SystemController::findValueInSettings("COLstart");
-            static_cast<RD53FWInterface*>(this->fBeBoardFWMap[cBoard->getBeBoardId()])->SetAndConfigureFastCommands(cBoard, nTRIGxEvent, injType, nClkDelays, colStart < RD53::LIN.colStart);
+            static_cast<RD53FWInterface*>(this->fBeBoardFWMap[cBoard->getId()])->SetAndConfigureFastCommands(theBoard, nTRIGxEvent, injType, nClkDelays, colStart < RD53::LIN.colStart);
             LOG (INFO) << GREEN << "Configured FSM fast command block" << RESET;
 
 
             // ########################
             // # Configuring from XML #
             // ########################
-            static_cast<RD53FWInterface*>(this->fBeBoardFWMap[cBoard->getBeBoardId()])->ConfigureFromXML(cBoard);
+            static_cast<RD53FWInterface*>(this->fBeBoardFWMap[cBoard->getId()])->ConfigureFromXML(theBoard);
 
 
             // ###################
             // # Configure chips #
             // ###################
-            for (const auto& cModule : cBoard->fModuleVector)
+            for(auto cOpticalGroup : *cBoard)
+            {
+              for (auto cHybrid : *cOpticalGroup)
               {
-                LOG (INFO) << GREEN << "Initializing communication to Module: " << RESET << BOLDYELLOW << +cModule->getModuleId() << RESET;
-                for (const auto& cRD53 : cModule->fReadoutChipVector)
-                  {
-                    LOG (INFO) << GREEN << "Configuring RD53: " << RESET << BOLDYELLOW << +cRD53->getChipId() << RESET;
-                    static_cast<RD53Interface*>(fReadoutChipInterface)->ConfigureChip(static_cast<RD53*>(cRD53));
-                    LOG (INFO) << GREEN << "Number of masked pixels: " << RESET << BOLDYELLOW << static_cast<RD53*>(cRD53)->getNbMaskedPixels() << RESET;
-                  }
+                LOG (INFO) << GREEN << "Initializing communication to Module: " << RESET << BOLDYELLOW << +cHybrid->getId() << RESET;
+                for (const auto cRD53 : *cHybrid)
+                {
+                  LOG (INFO) << GREEN << "Configuring RD53: " << RESET << BOLDYELLOW << +cRD53->getId() << RESET;
+                  static_cast<RD53Interface*>(fReadoutChipInterface)->ConfigureChip(static_cast<RD53*>(cRD53));
+                  LOG (INFO) << GREEN << "Number of masked pixels: " << RESET << BOLDYELLOW << static_cast<RD53*>(cRD53)->getNbMaskedPixels() << RESET;
+                }
               }
+            }
           }
       }
   }
@@ -227,25 +235,28 @@ namespace Ph2_System
 
   void SystemController::initializeFileHandler()
   {
-    for (const auto& cBoard : fBoardVector)
+    for (const auto* cBoard : *fDetectorContainer)
       {
+        const BeBoard* theBoard = static_cast<const BeBoard*>(cBoard);
         uint32_t cNChip        = 0;
-        uint32_t cBeId         = cBoard->getBeId();
-        uint32_t cNEventSize32 = this->computeEventSize32(cBoard);
+        uint32_t cBeId         = cBoard->getId();
+        uint32_t cNEventSize32 = this->computeEventSize32(theBoard);
 
         std::string cBoardTypeString;
-        BoardType cBoardType = cBoard->getBoardType();
+        BoardType cBoardType = theBoard->getBoardType();
 
-        for (const auto& cFe : cBoard->fModuleVector) cNChip += cFe->getNChip();
+        for (const auto cOpticalGroup : *cBoard) 
+          for (const auto cHybrid : *cOpticalGroup) 
+            cNChip += cHybrid->size();
 
         if      (cBoardType == BoardType::D19C) cBoardTypeString = "D19C";
         else if (cBoardType == BoardType::RD53) cBoardTypeString = "RD53";
 
-        uint32_t cFWWord  = fBeBoardInterface->getBoardInfo(cBoard);
+        uint32_t cFWWord  = fBeBoardInterface->getBoardInfo(theBoard);
         uint32_t cFWMajor = (cFWWord & 0xFFFF0000) >> 16;
         uint32_t cFWMinor = (cFWWord & 0x0000FFFF);
 
-        FileHeader cHeader(cBoardTypeString, cFWMajor, cFWMinor, cBeId, cNChip, cNEventSize32, cBoard->getEventType());
+        FileHeader cHeader(cBoardTypeString, cFWMajor, cFWMinor, cBeId, cNChip, cNEventSize32, theBoard->getEventType());
 
         std::stringstream cBeBoardString;
         cBeBoardString << "_Board" << std::setw(3) << std::setfill ('0') << cBeId;
@@ -255,46 +266,48 @@ namespace Ph2_System
 
         fFileHandler = new FileHandler(cFilename, 'w', cHeader);
 
-        fBeBoardInterface->SetFileHandler(cBoard, fFileHandler);
+        fBeBoardInterface->SetFileHandler(theBoard, fFileHandler);
         LOG (INFO) << GREEN << "Saving binary data into: " << RESET << BOLDYELLOW << cFilename << RESET;
       }
   }
 
-  uint32_t SystemController::computeEventSize32 (BeBoard* pBoard)
+  uint32_t SystemController::computeEventSize32 (const BeBoard* pBoard)
   {
     uint32_t cNEventSize32 = 0;
-    uint32_t cNCbc = 0;
+    uint32_t cNChip = 0;
+
+    for (const auto cOpticalGroup : *pBoard) 
+          for (const auto cHybrid : *cOpticalGroup) 
+            cNChip += cHybrid->size();
 
-    for (const auto& cFe : pBoard->fModuleVector)
-      cNCbc += cFe->getNChip();
     if (pBoard->getBoardType() == BoardType::D19C)
-      cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3;
+      cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNChip * D19C_EVENT_SIZE_32_CBC3;
 
     return cNEventSize32;
   }
 
   void SystemController::Start(int currentRun)
   {
-    for (auto& cBoard : fBoardVector)
-      fBeBoardInterface->Start(cBoard);
+    for (auto cBoard : *fDetectorContainer)
+      fBeBoardInterface->Start(static_cast<BeBoard*>(cBoard));
   }
 
   void SystemController::Stop()
   {
-    for (auto& cBoard : fBoardVector)
-      fBeBoardInterface->Stop(cBoard);
+    for (auto cBoard : *fDetectorContainer)
+      fBeBoardInterface->Stop(static_cast<BeBoard*>(cBoard));
   }
 
   void SystemController::Pause()
   {
-    for (auto& cBoard : fBoardVector)
-      fBeBoardInterface->Pause(cBoard);
+    for (auto cBoard : *fDetectorContainer)
+      fBeBoardInterface->Pause(static_cast<BeBoard*>(cBoard));
   }
 
   void SystemController::Resume()
   {
-    for (auto& cBoard : fBoardVector)
-      fBeBoardInterface->Resume(cBoard);
+    for (auto cBoard : *fDetectorContainer)
+      fBeBoardInterface->Resume(static_cast<BeBoard*>(cBoard));
   }
 
   void SystemController::ConfigureHardware(std::string cHWFile, bool enableStream)
@@ -342,8 +355,8 @@ namespace Ph2_System
 
   void SystemController::ReadData (bool pWait)
   {
-    for (auto cBoard : fBoardVector)
-      this->ReadData(cBoard, pWait);
+    for (auto cBoard : *fDetectorContainer)
+      this->ReadData(static_cast<BeBoard*>(cBoard), pWait);
   }
 
   uint32_t SystemController::ReadData (BeBoard* pBoard, std::vector<uint32_t>& pData, bool pWait)
@@ -361,8 +374,8 @@ namespace Ph2_System
 
   void SystemController::ReadNEvents (uint32_t pNEvents)
   {
-    for (auto cBoard : fBoardVector)
-      this->ReadNEvents(cBoard, pNEvents);
+    for (auto cBoard : *fDetectorContainer)
+      this->ReadNEvents(static_cast<BeBoard*>(cBoard), pNEvents);
   }
 
   void SystemController::ReadNEvents (BeBoard* pBoard, uint32_t pNEvents, std::vector<uint32_t>& pData, bool pWait)
diff --git a/System/SystemController.h b/System/SystemController.h
index 501fa4e41..50b9e7bb7 100644
--- a/System/SystemController.h
+++ b/System/SystemController.h
@@ -48,7 +48,7 @@
  */
 namespace Ph2_System
 {
-  using BeBoardVec  = std::vector<Ph2_HwDescription::BeBoard*>;                   /*!< Vector of Board pointers */
+  // using BeBoardVec  = std::vector<Ph2_HwDescription::BeBoard*>;                   /*!< Vector of Board pointers */
   using SettingsMap = std::unordered_map<std::string, double>; /*!< Maps the settings */
 
   /*!
@@ -67,7 +67,7 @@ namespace Ph2_System
     Ph2_HwInterface::MPAInterface* fMPAInterface;   //!< Interface to the MPA
 
     DetectorContainer* fDetectorContainer; //Detector Container
-    BeBoardVec fBoardVector;               //!< Vector of Board pointers
+    // BeBoardVec fBoardVector;               //!< Vector of Board pointers
     BeBoardFWMap fBeBoardFWMap;
     SettingsMap fSettingsMap;
     FileHandler* fFileHandler;
@@ -109,7 +109,7 @@ namespace Ph2_System
      * \brief issues a FileHandler for writing files to every BeBoardFWInterface if addFileHandler was called
      */
     void initializeFileHandler();
-    uint32_t computeEventSize32(Ph2_HwDescription::BeBoard *pBoard);
+    uint32_t computeEventSize32(const Ph2_HwDescription::BeBoard *pBoard);
 
     /*!
      * \brief read file in the a FileHandler object
@@ -125,8 +125,8 @@ namespace Ph2_System
     {
       pVisitor.visitSystemController(*this);
 
-      for (Ph2_HwDescription::BeBoard *cBoard : fBoardVector)
-        cBoard->accept(pVisitor);
+      for (auto *cBoard : *fDetectorContainer)
+        static_cast<Ph2_HwDescription::BeBoard*>(cBoard)->accept(pVisitor);
     }
 
     /*!
@@ -158,13 +158,14 @@ namespace Ph2_System
       void ReadSystemMonitor(Ph2_HwDescription::BeBoard* pBoard, const Ts&... args)
       {
         if (sizeof...(Ts) > 0)
-          for (const auto cModule : *pBoard)
-            for (const auto cChip : *cModule)
-              {
-                LOG (INFO) << GREEN << "Monitor data for [board/module/chip = " << BOLDYELLOW << pBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
-                fBeBoardInterface->ReadChipMonitor(fReadoutChipInterface, static_cast<Ph2_HwDescription::ReadoutChip*>(cChip), args...);
-                LOG (INFO) << BOLDBLUE << "\t--> Done" << RESET;
-              }
+          for (const auto cOpticalGroup : *pBoard)
+            for (const auto cModule : *cOpticalGroup)
+              for (const auto cChip : *cModule)
+                {
+                  LOG (INFO) << GREEN << "Monitor data for [board/opticalGroup/module/chip = " << BOLDYELLOW << pBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+                  fBeBoardInterface->ReadChipMonitor(fReadoutChipInterface, static_cast<Ph2_HwDescription::ReadoutChip*>(cChip), args...);
+                  LOG (INFO) << BOLDBLUE << "\t--> Done" << RESET;
+                }
       }
 
     /*!
@@ -225,7 +226,7 @@ namespace Ph2_System
 
     const Ph2_HwDescription::BeBoard* getBoard(int index) const
     {
-      return (index < static_cast<int>(fBoardVector.size()) ? fBoardVector.at(index) : nullptr);
+      return (index < static_cast<int>(fDetectorContainer->size()) ? static_cast<Ph2_HwDescription::BeBoard*>(fDetectorContainer->at(index)) : nullptr);
     }
 
     /*!
diff --git a/Utils/ContainerFactory.h b/Utils/ContainerFactory.h
index cc1ae6cda..d5091896e 100644
--- a/Utils/ContainerFactory.h
+++ b/Utils/ContainerFactory.h
@@ -62,7 +62,7 @@ namespace ContainerFactory
 		{
 			BoardDataContainer* copyBoard = copy.addBoardDataContainer(board->getId());
 			copy.back()->initialize<SB,SO>();
-			for(const OpticalGroupDataContainer *opticalGroup : *board)
+			for(const OpticalGroupContainer *opticalGroup : *board)
 			{
 				OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
 				copyBoard->back()->initialize<SO,SM>();
@@ -138,10 +138,10 @@ namespace ContainerFactory
 		{
 			BoardDataContainer* copyBoard = copy.addBoardDataContainer(board->getId());
 			static_cast<BoardDataContainer*>(copy.back())->initialize<SB,SO>(boardSummary);
-			for(const OpticalGroupDataContainer *opticalGroup : *board)
+			for(const OpticalGroupContainer *opticalGroup : *board)
 			{
 				OpticalGroupDataContainer* copyOpticalGroup = copyBoard->addOpticalGroupDataContainer(opticalGroup->getId());
-				static_cast<BoardDataContainer*>(copyBoard->back())->initialize<SO,SM>(opticalGroupSummary);
+				static_cast<OpticalGroupDataContainer*>(copyBoard->back())->initialize<SO,SM>(opticalGroupSummary);
 				for(const ModuleContainer* hybrid : *opticalGroup)
 				{
 					ModuleDataContainer* copyModule = copyOpticalGroup->addModuleDataContainer(hybrid->getId());
diff --git a/Utils/ContainerRecycleBin.h b/Utils/ContainerRecycleBin.h
index e93266b3b..f9de912bd 100644
--- a/Utils/ContainerRecycleBin.h
+++ b/Utils/ContainerRecycleBin.h
@@ -8,21 +8,25 @@
 template<typename... Ts>
 using TestType = decltype(ContainerFactory::copyAndInitStructure(std::declval<const DetectorContainer&>(), std::declval<DetectorDataContainer&>(), std::declval<Ts&>()...))(const DetectorContainer&, DetectorDataContainer&, Ts&...);
 
-template<typename T, typename SC, typename SM, typename SB, typename SD>
-void reinitializeContainer(DetectorDataContainer *theDataContainer, T& channel, SC& chipSummary, SM& moduleSummary, SB& boardSummary, SD& detectorSummary)
+template<typename T, typename SC, typename SM, typename SO, typename SB, typename SD>
+void reinitializeContainer(DetectorDataContainer *theDataContainer, T& channel, SC& chipSummary, SM& moduleSummary, SO& opticalGroupSummary, SB& boardSummary, SD& detectorSummary)
 {
     theDataContainer->resetSummary<SD, SB>(detectorSummary);
     for(auto board : *theDataContainer)
     {
-        board->resetSummary<SB, SM>(boardSummary);
-        for(auto module : *board)
+        board->resetSummary<SB, SO>(boardSummary);
+        for(auto opticalGroup : *board)
         {
-            module->resetSummary<SM, SC>(moduleSummary);
-            for(auto chip : *module)
+            opticalGroup->resetSummary<SO, SM>(opticalGroupSummary);
+            for(auto module : *opticalGroup)
             {
-                chip->resetSummary<SC, T>(chipSummary);
-                chip->resetChannels<T>(channel);
-            }   
+                module->resetSummary<SM, SC>(moduleSummary);
+                for(auto chip : *module)
+                {
+                    chip->resetSummary<SC, T>(chipSummary);
+                    chip->resetChannels<T>(channel);
+                }   
+            }
         }
     }
 }
@@ -30,13 +34,13 @@ void reinitializeContainer(DetectorDataContainer *theDataContainer, T& channel,
 template<typename T, typename S>
 void reinitializeContainer(DetectorDataContainer* theDataContainer, T& channel, S& summay)
 {
-    reinitializeContainer<T,S,S,S,S>(theDataContainer, channel, summay, summay, summay, summay);
+    reinitializeContainer<T,S,S,S,S,S>(theDataContainer, channel, summay, summay, summay, summay, summay);
 }
 
 template<typename T>
 void reinitializeContainer(DetectorDataContainer *theDataContainer, T& channel)
 {
-    reinitializeContainer<T,T,T,T,T>(theDataContainer, channel, channel, channel, channel, channel); 
+    reinitializeContainer<T,T,T,T,T,T>(theDataContainer, channel, channel, channel, channel, channel, channel); 
 }
 
 
diff --git a/Utils/D19cCbc3Event.cc b/Utils/D19cCbc3Event.cc
index 8fea1b6b4..89c5a9a2c 100644
--- a/Utils/D19cCbc3Event.cc
+++ b/Utils/D19cCbc3Event.cc
@@ -118,14 +118,14 @@ namespace Ph2_HwInterface {
             {
                 // just use board to figure out how many CBCs there are 
                 size_t cHybridIndex=0;
-                for (auto& cFe : pBoard->fModuleVector)
+                for (auto& cFe : *pBoard->at(0))
                 {
-                    if( cFe->getFeId()== cFeId )
+                    if( cFe->getId()== cFeId )
                         cHybridIndex = cFe->getIndex();
                 }
-                auto& cReadoutChips = pBoard->fModuleVector[cHybridIndex]->fReadoutChipVector; 
+                auto cReadoutChips = pBoard->at(0)->at(cHybridIndex); 
                 std::vector<uint32_t> cCbcData(cIterator, cIterator+cDataSize);
-                fEventDataVector[encodeVectorIndex(cFeId, cCbcId,cReadoutChips.size())] = cCbcData;
+                fEventDataVector[encodeVectorIndex(cFeId, cCbcId,cReadoutChips->size())] = cCbcData;
             }
             cIterator += cL1DataSize + cStubDataSize;     
         }while( cIterator < list.end() - fDummySize );
@@ -617,9 +617,9 @@ namespace Ph2_HwInterface {
         GenericPayload cPayload;
         GenericPayload cStubPayload;
 
-        for (auto cFe : pBoard->fModuleVector)
+        for (auto cFe : *pBoard->at(0))
         {
-            uint8_t cFeId = cFe->getFeId();
+            uint8_t cFeId = cFe->getId();
 
             // firt get the list of enabled front ends
             if (cEnabledFe.find (cFeId) == std::end (cEnabledFe) )
@@ -632,9 +632,9 @@ namespace Ph2_HwInterface {
             //stub counter per FE
             uint8_t cFeStubCounter = 0;
 
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cCbc : *cFe)
             {
-                uint8_t cCbcId = cCbc->getChipId();
+                uint8_t cCbcId = cCbc->getId();
                 const std::vector<uint32_t> &hitVector = fEventDataVector.at(encodeVectorIndex(cFeId, cCbcId,fNCbc));
                 
                 try
diff --git a/Utils/D19cCbc3EventZS.cc b/Utils/D19cCbc3EventZS.cc
index d2b9a8fc2..49fcc8d5e 100644
--- a/Utils/D19cCbc3EventZS.cc
+++ b/Utils/D19cCbc3EventZS.cc
@@ -77,7 +77,7 @@ namespace Ph2_HwInterface
 
         for (uint8_t cFe = 0; cFe < fNFe_software; cFe++)
         {
-            uint8_t cFeId = pBoard->fModuleVector.at (cFe)->getFeId();
+            uint8_t cFeId = pBoard->at(0)->at (cFe)->getId();
             fFeMask_software |= 1 << cFeId;
         }
 
@@ -97,7 +97,7 @@ namespace Ph2_HwInterface
 
         for (uint8_t cFe = 0; cFe < fNFe_software; cFe++)
         {
-            uint8_t cFeId = pBoard->fModuleVector.at(cFe)->getFeId();
+            uint8_t cFeId = pBoard->at(0)->at(cFe)->getId();
             if (((fFeMask_software >> cFeId) & 1) && ((fFeMask_event >> cFeId) & 1))
             {
                 //uint8_t chip_data_mask = static_cast<uint8_t> ( ( (0xFF000000) & list.at (address_offset + 0) ) >> 24);
@@ -835,9 +835,9 @@ namespace Ph2_HwInterface
         GenericPayload cPayload;
         GenericPayload cStubPayload;
 
-        for (auto cFe : pBoard->fModuleVector)
+        for (auto cFe : *pBoard->at(0))
         {
-            uint8_t cFeId = cFe->getFeId();
+            uint8_t cFeId = cFe->getId();
 
             // firt get the list of enabled front ends
             if (cEnabledFe.find (cFeId) == std::end (cEnabledFe) )
@@ -856,9 +856,9 @@ namespace Ph2_HwInterface
             //TODO
             cStatusPayload.append (this->GetEventCount(), 9);
 
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cCbc : *cFe)
             {
-                uint8_t cCbcId = cCbc->getChipId();
+                uint8_t cCbcId = cCbc->getId();
                 uint16_t cKey = encodeId (cFeId, cCbcId);
                 EventDataMap::const_iterator cData = fEventDataMap.find (cKey);
 
diff --git a/Utils/D19cCic2Event.cc b/Utils/D19cCic2Event.cc
index c5b2b383d..0e6f54921 100644
--- a/Utils/D19cCic2Event.cc
+++ b/Utils/D19cCic2Event.cc
@@ -56,7 +56,7 @@ namespace Ph2_HwInterface {
     void D19cCic2Event::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list )
     {
         fIsSparsified=pBoard->getSparsification();
-        LOG (DEBUG) << BOLDBLUE << " Found " << +pBoard->fModuleVector.size() << " FE connected to this board.." << RESET;
+        
         fEventHitList.clear();
         fEventStubList.clear();
         for( size_t cFeIndex=0; cFeIndex < N2SMODULES*2 ; cFeIndex++)
@@ -155,26 +155,26 @@ namespace Ph2_HwInterface {
                 //  LOG (INFO) << BOLDBLUE << std::bitset<32>(*(cIterator+cIndex)) << RESET;
 
                 size_t cHybridIndex=0;
-                for (auto& cFe : pBoard->fModuleVector)
+                for (auto cFe : *pBoard->at(0))
                 {
-                    if( cFe->getFeId()== cFeId )
+                    if( cFe->getId()== cFeId )
                         cHybridIndex = cFe->getIndex();
                 }
-                auto& cReadoutChips = pBoard->fModuleVector[cHybridIndex]->fReadoutChipVector; 
-                const size_t cNblocks = RAW_L1_CBC*cReadoutChips.size()/L1_BLOCK_SIZE; // 275 bits per chip ... 8chips... blocks of 11 bits 
+                auto cReadoutChips = pBoard->at(cHybridIndex); 
+                const size_t cNblocks = RAW_L1_CBC*cReadoutChips->size()/L1_BLOCK_SIZE; // 275 bits per chip ... 8chips... blocks of 11 bits 
                 std::vector<std::bitset<L1_BLOCK_SIZE>> cL1Words(cNblocks , 0);
                 this->splitStream(list , cL1Words , cOffset+3 , cNblocks ); // split 32 bit words in  blocks of 11 bits 
                 
                 // now try and arrange them by CBC again ... 
                 fEventRawList[cFeId].first = cL1Information;
                 fEventRawList[cFeId].second.clear();
-                for(size_t cChipIndex=0; cChipIndex < cReadoutChips.size() ; cChipIndex++)
+                for(size_t cChipIndex=0; cChipIndex < cReadoutChips->size() ; cChipIndex++)
                 {
                     std::bitset<RAW_L1_CBC> cBitset(0);
                     size_t cPosition=0;
                     for( size_t cBlockIndex =0; cBlockIndex < RAW_L1_CBC/L1_BLOCK_SIZE ; cBlockIndex ++) // RAW_L1_CBC/L1_BLOCK_SIZE blocks per chip
                     {
-                        auto cIndex = cChipIndex + cReadoutChips.size()*cBlockIndex; 
+                        auto cIndex = cChipIndex + cReadoutChips->size()*cBlockIndex; 
                         auto& cL1block = cL1Words[cIndex];
                         LOG (DEBUG) << BOLDBLUE << "\t\t... L1 block " << +cIndex << " -- " << std::bitset<L1_BLOCK_SIZE>(cL1block) << RESET;
                         for(size_t cNbit=0; cNbit < cL1block.size() ; cNbit++ )
diff --git a/Utils/D19cCicEvent.cc b/Utils/D19cCicEvent.cc
index a859bc4fc..5eb89d9c6 100644
--- a/Utils/D19cCicEvent.cc
+++ b/Utils/D19cCicEvent.cc
@@ -702,12 +702,13 @@ namespace Ph2_HwInterface {
         // get link Ids 
         std::vector<uint8_t> cLinkIds(0);
         std::set<uint8_t> cEnabledFe;
-        for (auto& cFe : pBoard->fModuleVector)
+        for (auto& cFe : *pBoard->at(0))
         {
-            if ( std::find(cLinkIds.begin(), cLinkIds.end(), cFe->getLinkId() ) == cLinkIds.end() )
+            uint8_t linkId = static_cast<OuterTrackerModule*>(cFe)->getLinkId();
+            if ( std::find(cLinkIds.begin(), cLinkIds.end(), linkId ) == cLinkIds.end() )
             {
-                cEnabledFe.insert (cFe->getLinkId());
-                cLinkIds.push_back(cFe->getLinkId() );
+                cEnabledFe.insert (linkId);
+                cLinkIds.push_back(linkId);
             }
         }
 
@@ -730,15 +731,16 @@ namespace Ph2_HwInterface {
             uint8_t cFeStubCounter = 0;
             auto cPositionStubs = cStubString.length(); 
             auto cPositionHits = cHitString.length();
-            for (auto cFe : pBoard->fModuleVector)
+            for (auto cFe : *pBoard->at(0))
             {
-                if( cFe->getLinkId() != cLinkId )
+                uint8_t linkId = static_cast<OuterTrackerModule*>(cFe)->getLinkId();
+                if( linkId != cLinkId )
                     continue;
                 
-                uint8_t cFeId = cFe->getFeId();
-                for (auto cChip : cFe->fReadoutChipVector)
+                uint8_t cFeId = cFe->getId();
+                for (auto cChip : *cFe)
                 {
-                    uint8_t cChipId = cChip->getChipId() ;
+                    uint8_t cChipId = cChip->getId() ;
                     auto cIndex = 7 - std::distance( fFeMapping.begin() , std::find( fFeMapping.begin(), fFeMapping.end() , cChipId ) ) ; 
                 	if( cIndex >= (int)fEventDataList[cFeId].second.size() ) 
                 	    continue;
@@ -748,7 +750,7 @@ namespace Ph2_HwInterface {
                     uint32_t cL1ACounter = this->L1Id( cFeId , cChipId);
                     uint32_t cStatusWord = cError << 18 | cPipeAddress << 9 | cL1ACounter;
                     
-                    auto cNHits = this->GetNHits(cFe->getFeId(), cChip->getChipId() );
+                    auto cNHits = this->GetNHits(cFe->getId(), cChip->getId() );
                     //now get the CBC status summary
                     if (pBoard->getConditionDataSet()->getDebugMode() == SLinkDebugMode::ERROR)
                        cStatusPayload.append ( (cError != 0) ? 1 : 0);
@@ -758,7 +760,7 @@ namespace Ph2_HwInterface {
                 
                     //generate the payload
                     //the first line sets the cbc presence bits
-                    cCbcPresenceWord |= 1 << (cChipId + 8*(cFe->getFeId()%2));
+                    cCbcPresenceWord |= 1 << (cChipId + 8*(cFe->getId()%2));
 
                     //254 channels + 2 padding bits at the end 
                     std::bitset<256> cBitsetHitData; 
@@ -770,18 +772,18 @@ namespace Ph2_HwInterface {
                     cHitString += cBitsetHitData.to_string();
                     if( cNHits > 0 )
                     {
-                        LOG (DEBUG) << BOLDBLUE << "Readout chip " << +cChip->getChipId() << " on link " << +cFe->getLinkId() << RESET;
+                        LOG (DEBUG) << BOLDBLUE << "Readout chip " << +cChip->getId() << " on link " << +linkId << RESET;
                         //" : " << cBitsetHitData.to_string() << RESET;
-                        auto cHits = this->GetHits(cFe->getFeId(), cChip->getChipId() );
-                        for( auto cHit : this->GetHits(cFe->getFeId(), cChip->getChipId() ) )
+                        auto cHits = this->GetHits(cFe->getId(), cChip->getId() );
+                        for( auto cHit : this->GetHits(cFe->getId(), cChip->getId() ) )
                         {
                             LOG (DEBUG) << BOLDBLUE << "\t... Hit in channel " << +cHit << RESET;
                         }
                     }
                     // now stubs
-                    for( auto cStub : this->StubVector (cFe->getFeId() , cChip->getChipId()) )
+                    for( auto cStub : this->StubVector (cFe->getId() , cChip->getId()) )
                     {
-                        std::bitset<16> cBitsetStubs( ( (cChip->getChipId() + 8*(cFe->getFeId()%2)) << 12) | (cStub.getPosition() << 4) | cStub.getBend() );
+                        std::bitset<16> cBitsetStubs( ( (cChip->getId() + 8*(cFe->getId()%2)) << 12) | (cStub.getPosition() << 4) | cStub.getBend() );
                         cStubString += cBitsetStubs.to_string();
                         LOG (DEBUG) << BOLDBLUE << "\t.. stub in seed " << +cStub.getPosition() << " and bench code " << std::bitset<4>(cStub.getBend()) << RESET;
                         cFeStubCounter+=1;
@@ -860,7 +862,7 @@ namespace Ph2_HwInterface {
 
     //     for (auto cFe : pBoard->fModuleVector)
     //     {
-    //         uint8_t cFeId = cFe->getFeId();
+    //         uint8_t cFeId = cFe->getId();
 
     //         // firt get the list of enabled front ends
     //         if (cEnabledFe.find (cFeId) == std::end (cEnabledFe) )
@@ -875,7 +877,7 @@ namespace Ph2_HwInterface {
 
     //         for (auto cCbc : cFe->fReadoutChipVector)
     //         {
-    //             uint8_t cCbcId = cCbc->getChipId();
+    //             uint8_t cCbcId = cCbc->getId();
     //             uint16_t cKey = encodeId (cFeId, cCbcId);
     //             EventDataMap::const_iterator cData = fEventDataMap.find (cKey);
 
diff --git a/Utils/D19cMPAEvent.cc b/Utils/D19cMPAEvent.cc
index 1bbb7ba43..1b18b0760 100755
--- a/Utils/D19cMPAEvent.cc
+++ b/Utils/D19cMPAEvent.cc
@@ -540,9 +540,9 @@ namespace Ph2_HwInterface
         GenericPayload cPayload;
         GenericPayload cStubPayload;
 
-        for (auto cFe : pBoard->fModuleVector)
+        for (auto cFe : *pBoard->at(0))
         {
-            uint8_t cFeId = cFe->getFeId();
+            uint8_t cFeId = cFe->getId();
 
             // firt get the list of enabled front ends
             if (cEnabledFe.find (cFeId) == std::end (cEnabledFe) )
@@ -555,9 +555,9 @@ namespace Ph2_HwInterface
             //stub counter per FE
             uint8_t cFeStubCounter = 0;
 
-            for (auto cMPA : static_cast<OuterTrackerModule*>(cFe)->fMPAVector)
+            for (auto cMPA : *cFe)
             {
-                uint8_t cMPAId = cMPA->getMPAId();
+                uint8_t cMPAId = cMPA->getId();
                 uint16_t cKey = encodeId (cFeId, cMPAId);
                 EventDataMap::const_iterator cData = fEventDataMap.find (cKey);
 
diff --git a/Utils/SSAEvent.cc b/Utils/SSAEvent.cc
index 25c9e0adf..53870cc63 100755
--- a/Utils/SSAEvent.cc
+++ b/Utils/SSAEvent.cc
@@ -37,28 +37,28 @@ namespace Ph2_HwInterface
     //}
 
 
-    void SSAEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list )
-    {
-        fEventSize = pNbCbc *  CBC_EVENT_SIZE_32  + EVENT_HEADER_TDC_SIZE_32;
+    // void SSAEvent::SetEvent ( const BeBoard* pBoard, uint32_t pNbCbc, const std::vector<uint32_t>& list )
+    // {
+    //     fEventSize = pNbCbc *  CBC_EVENT_SIZE_32  + EVENT_HEADER_TDC_SIZE_32;
 
 
-        //now decode FEEvents
-        uint32_t cNFe = static_cast<uint32_t> ( pBoard->getNFe() );
-        for ( uint8_t cFeId = 0; cFeId < cNFe; cFeId++ )
-        {
-            uint32_t cNSSA;
-            cNSSA = static_cast<uint32_t> ( static_cast<OuterTrackerModule*>(pBoard->getModule ( cFeId ))->getNSSA() );
+    //     //now decode FEEvents
+    //     uint32_t cNFe = static_cast<uint32_t> ( pBoard->getNFe() );
+    //     for ( uint8_t cFeId = 0; cFeId < cNFe; cFeId++ )
+    //     {
+    //         uint32_t cNSSA;
+    //         cNSSA = static_cast<uint32_t> ( static_cast<OuterTrackerModule*>(pBoard->getModule ( cFeId ))->getNSSA() );
 
-            for ( uint8_t cSSAId = 0; cSSAId < cNSSA; cSSAId++ )
-            {
-                uint16_t cKey = encodeId (cFeId, cSSAId);
+    //         for ( uint8_t cSSAId = 0; cSSAId < cNSSA; cSSAId++ )
+    //         {
+    //             uint16_t cKey = encodeId (cFeId, cSSAId);
 		
-                uint32_t begin = SSA_HEADER_SIZE_32 + cFeId * SSA_EVENT_SIZE_32 * cNSSA + cSSAId * SSA_EVENT_SIZE_32;
-                uint32_t end = begin + SSA_EVENT_SIZE_32;
+    //             uint32_t begin = SSA_HEADER_SIZE_32 + cFeId * SSA_EVENT_SIZE_32 * cNSSA + cSSAId * SSA_EVENT_SIZE_32;
+    //             uint32_t end = begin + SSA_EVENT_SIZE_32;
 
-                std::vector<uint32_t> cSSAData (std::next (std::begin (list), begin), std::next (std::begin (list), end) );
-                fEventDataMap[cKey] = cSSAData;
-            }
-        }
-    }
+    //             std::vector<uint32_t> cSSAData (std::next (std::begin (list), begin), std::next (std::begin (list), end) );
+    //             fEventDataMap[cKey] = cSSAData;
+    //         }
+    //     }
+    // }
 }
diff --git a/setup.sh b/setup.sh
index 08d74dba3..a15fe8787 100755
--- a/setup.sh
+++ b/setup.sh
@@ -22,8 +22,8 @@ fi
 ########
 # ROOT #
 ########
-source $ROOTSYS/bin/thisroot.sh
-#source /usr/local/root/bin/thisroot.sh
+# source $ROOTSYS/bin/thisroot.sh
+source /usr/local/root/bin/thisroot.sh
 #source /opt/local/root/bin/thisroot.sh
 
 #######
diff --git a/tools/AntennaTester.cc b/tools/AntennaTester.cc
index 7a956994a..b3645c62f 100644
--- a/tools/AntennaTester.cc
+++ b/tools/AntennaTester.cc
@@ -115,12 +115,13 @@ void AntennaTester::InitialiseSettings()
 ///fBeBoardInterface->ReadBoardReg (cBoard, getDelAfterTPString ( cBoard->getBoardType() ) );
 //trigSource =ReadReg("fc7_daq_cnfg.fast_command_block.trigger_source");
 //         LOG (INFO)  <<int (trigSource);
-    for (auto& cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard)
+        trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
-}
+    }
 
 }
 void AntennaTester::InitializeHists()
@@ -184,36 +185,40 @@ void AntennaTester::UpdateHistsMerged()
 }
 void AntennaTester::ReconfigureCBCRegisters (std::string pDirectoryName )
 {
-    for (auto& cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        fBeBoardInterface->ChipReset ( cBoard );
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard)
+        fBeBoardInterface->ChipReset ( theBoard );
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
 
-        for (auto& cFe : cBoard->fModuleVector)
-        {
-            for (auto& cCbc : cFe->fReadoutChipVector)
-            {
-                std::string pRegFile ;
-                char buffer[120];
-
-                if ( pDirectoryName.empty() )
-                    sprintf (buffer, "%s/FE%dCBC%d.txt", fDirectoryName.c_str(), cCbc->getFeId(), cCbc->getChipId() );
-                else
-                    sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cCbc->getFeId(), cCbc->getChipId() );
+        for (auto cOpticalGroup : *cBoard)
 
-                pRegFile = buffer;
-                cCbc->loadfRegMap (pRegFile);
-                fReadoutChipInterface->ConfigureChip ( cCbc );
-                LOG (INFO)  << GREEN << "\t\t Successfully reconfigured CBC" << int ( cCbc->getChipId() ) << "'s regsiters from " << pRegFile << " ." << RESET;
+            for (auto cHybrid : *cOpticalGroup)
+            {
+                for (auto cCbc : *cHybrid)
+                {
+                    Cbc* theCBC = static_cast<Cbc*>(cCbc);
+                    std::string pRegFile ;
+                    char buffer[120];
+
+                    if ( pDirectoryName.empty() )
+                        sprintf (buffer, "%s/FE%dCBC%d.txt", fDirectoryName.c_str(), cHybrid->getId(), cCbc->getId() );
+                    else
+                        sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cHybrid->getId(), cCbc->getId() );
+
+                    pRegFile = buffer;
+                    Cbc->loadfRegMap (pRegFile);
+                    fReadoutChipInterface->ConfigureChip ( Cbc );
+                    LOG (INFO)  << GREEN << "\t\t Successfully reconfigured CBC" << int ( cCbc->getId() ) << "'s regsiters from " << pRegFile << " ." << RESET;
+                }
             }
-        }
 
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
 }
 
diff --git a/tools/BackEndAlignment.cc b/tools/BackEndAlignment.cc
index ceb9bd576..b4497d1d4 100644
--- a/tools/BackEndAlignment.cc
+++ b/tools/BackEndAlignment.cc
@@ -23,27 +23,32 @@ BackEndAlignment::~BackEndAlignment()
 void BackEndAlignment::Reset()
 {
     // set everything back to original values .. like I wasn't here 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Resetting all registers on back-end board " << +cBoard->getBeBoardId() << RESET;
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
+        LOG (INFO) << BOLDBLUE << "Resetting all registers on back-end board " << +cBoard->getId() << RESET;
         auto& cBeRegMap = fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>();
         std::vector< std::pair<std::string, uint32_t> > cVecBeBoardRegs; cVecBeBoardRegs.clear();
         for(auto cReg : cBeRegMap )
             cVecBeBoardRegs.push_back(make_pair(cReg.first, cReg.second));
-        fBeBoardInterface->WriteBoardMultReg ( cBoard, cVecBeBoardRegs);
+        fBeBoardInterface->WriteBoardMultReg ( theBoard, cVecBeBoardRegs);
 
         auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cRegMapThisHybrid = cRegMapThisBoard->at(cFe->getIndex());
-            LOG (INFO) << BOLDBLUE << "Resetting all registers on readout chips connected to FEhybrid#" << (cFe->getFeId() ) << " back to their original values..." << RESET;
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                auto& cRegMapThisChip = cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>(); 
-                std::vector< std::pair<std::string, uint16_t> > cVecRegisters; cVecRegisters.clear();
-                for(auto cReg : cRegMapThisChip )
-                    cVecRegisters.push_back(make_pair(cReg.first, cReg.second.fValue));
-                fReadoutChipInterface->WriteChipMultReg ( cChip , cVecRegisters );
+                auto& cRegMapThisHybrid = cRegMapThisBoard->at(cHybrid->getIndex());
+                LOG (INFO) << BOLDBLUE << "Resetting all registers on readout chips connected to FEhybrid#" << (cHybrid->getId() ) << " back to their original values..." << RESET;
+                for (auto cChip : *cHybrid)
+                {
+                    auto& cRegMapThisChip = cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>(); 
+                    std::vector< std::pair<std::string, uint16_t> > cVecRegisters; cVecRegisters.clear();
+                    for(auto cReg : cRegMapThisChip )
+                        cVecRegisters.push_back(make_pair(cReg.first, cReg.second.fValue));
+                    fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cChip) , cVecRegisters );
+                }
             }
         }
     }
@@ -59,16 +64,19 @@ void BackEndAlignment::Initialise ()
     // retreive original settings for all chips and all back-end boards 
     ContainerFactory::copyAndInitStructure<ChipRegMap>(*fDetectorContainer, fRegMapContainer);
     ContainerFactory::copyAndInitStructure<BeBoardRegMap>(*fDetectorContainer, fBoardRegContainer);
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>() = cBoard->getBeBoardRegMap();
+        fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>() = static_cast<BeBoard*>(cBoard)->getBeBoardRegMap();
         auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalReadout : *cBoard)
         {
-            auto& cRegMapThisHybrid = cRegMapThisBoard->at(cFe->getIndex());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalReadout)
             {
-                cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>() = cChip->getRegMap();
+                auto& cRegMapThisHybrid = cRegMapThisBoard->at(cHybrid->getIndex());
+                for (auto cChip : *cHybrid)
+                {
+                    cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>() = static_cast<ReadoutChip*>(cChip)->getRegMap();
+                }
             }
         }
     }
@@ -104,14 +112,17 @@ bool BackEndAlignment::CICAlignment(BeBoard* pBoard)
         return false;
     }
     // force CIC to output empty L1A frames [by disabling all FEs]
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalReadout : *pBoard)
     {
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-        /*if( cCic->getFrontEndType() == FrontEndType::CIC )
+        for (auto cHybrid : *cOpticalReadout)
         {
-            fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cFe)->fCic, false );
-        }*/
-        fCicInterface->EnableFEs(cCic , {0,1,2,3,4,5,6,7}, false );  
+            auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+            /*if( cCic->getFrontEndType() == FrontEndType::CIC )
+            {
+                fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cFe)->fCic, false );
+            }*/
+            fCicInterface->EnableFEs(cCic , {0,1,2,3,4,5,6,7}, false );  
+        }
     }
     cAligned = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->L1WordAlignment (pBoard,fL1Debug);
     if( !cAligned )
@@ -121,21 +132,27 @@ bool BackEndAlignment::CICAlignment(BeBoard* pBoard)
     }
 
     // enable CIC output of pattern .. and enable all FEs again
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalReadout : *pBoard)
     {
-        // select link [ if optical ]
-        fCicInterface->EnableFEs(static_cast<OuterTrackerModule*>(cFe)->fCic , {0,1,2,3,4,5,6,7}, true );
-        fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cFe)->fCic, true );
+        for (auto cHybrid : *cOpticalReadout)
+        {
+            // select link [ if optical ]
+            fCicInterface->EnableFEs(static_cast<OuterTrackerModule*>(cHybrid)->fCic , {0,1,2,3,4,5,6,7}, true );
+            fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cHybrid)->fCic, true );
+        }
     }
     cAligned = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->StubTuning (pBoard, fStubDebug);
 
     // disable CIC output of pattern 
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalReadout : *pBoard)
     {
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-        fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cFe)->fCic, false );
-        if( !cSparsified && cCic->getFrontEndType() == FrontEndType::CIC2 ) 
-            fBeBoardInterface->WriteBoardReg (pBoard, "fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable", 0);
+        for (auto cHybrid : *cOpticalReadout)
+        {
+            auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+            fCicInterface->SelectOutput( static_cast<OuterTrackerModule*>(cHybrid)->fCic, false );
+            if( !cSparsified && cCic->getFrontEndType() == FrontEndType::CIC2 ) 
+                fBeBoardInterface->WriteBoardReg (pBoard, "fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable", 0);
+        }
     }
 
     // re-load configuration of fast command block from register map loaded from xml file 
@@ -148,91 +165,95 @@ bool BackEndAlignment::CBCAlignment(BeBoard* pBoard )
 {
     bool cAligned = false;
 
-    for (auto& cFe : pBoard->fModuleVector)
+    for(auto cOpticalReadout : *pBoard)
     {
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-        for (auto& cReadoutChip : cFe->fReadoutChipVector)
+        for (auto cHybrid : *cOpticalReadout)
         {
-            //fBeBoardInterface->WriteBoardReg (pBoard, "fc7_daq_cnfg.physical_interface_block.slvs_debug.chip_select", cReadoutChip->getChipId() );
-            // original mask
-            const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(cReadoutChip->getChipOriginalMask());
-            // original threshold 
-            uint16_t cThreshold = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cReadoutChip, "VCth" );
-            // original HIT OR setting 
-            uint16_t cHitOR = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cReadoutChip, "HitOr" );
-            
-            // make sure hit OR is turned off 
-            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cReadoutChip , "HitOr" , 0); 
-            // make sure pT cut is set to maximum 
-            // make sure hit OR is turned off 
-            auto cPtCut = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg( cReadoutChip , "PtCut" ); 
-            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cReadoutChip , "PtCut" , 14); 
+            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<Module*>(cHybrid)->getLinkId());
+            for (auto cReadoutChip : *cHybrid)
+            {
+                ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cReadoutChip);
+                //fBeBoardInterface->WriteBoardReg (pBoard, "fc7_daq_cnfg.physical_interface_block.slvs_debug.chip_select", cReadoutChip->getChipId() );
+                // original mask
+                const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(cReadoutChip->getChipOriginalMask());
+                // original threshold 
+                uint16_t cThreshold = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(theReadoutChip, "VCth" );
+                // original HIT OR setting 
+                uint16_t cHitOR = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(theReadoutChip, "HitOr" );
+                
+                // make sure hit OR is turned off 
+                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theReadoutChip , "HitOr" , 0); 
+                // make sure pT cut is set to maximum 
+                // make sure hit OR is turned off 
+                auto cPtCut = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg( theReadoutChip , "PtCut" ); 
+                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theReadoutChip , "PtCut" , 14); 
 
-            LOG (INFO) << BOLDBLUE << "Running phase tuning and word alignment on FE" << +cFe->getFeId() << " CBC" << +cReadoutChip->getId() << "..." << RESET;
-            uint8_t cBendCode_phAlign = 2;
-            std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cReadoutChip );
-            auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), cBendCode_phAlign);
-            // if bend code isn't there ... quit
-            if( cIterator == cBendLUT.end() )
-                continue;
+                LOG (INFO) << BOLDBLUE << "Running phase tuning and word alignment on FE" << +cHybrid->getId() << " CBC" << +cReadoutChip->getId() << "..." << RESET;
+                uint8_t cBendCode_phAlign = 2;
+                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theReadoutChip );
+                auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), cBendCode_phAlign);
+                // if bend code isn't there ... quit
+                if( cIterator == cBendLUT.end() )
+                    continue;
 
-            int cPosition = std::distance( cBendLUT.begin(), cIterator);
-            double cBend_strips = -7. + 0.5*cPosition; 
-            LOG (DEBUG) << BOLDBLUE << "Bend code of " << +cBendCode_phAlign << " found in register " << cPosition << " so a bend of " << cBend_strips << RESET;
-            
-            uint8_t cSuccess = 0x00;
-            std::vector<uint8_t> cSeeds{0x82,0x8E, 0x9E};
-            std::vector<int> cBends ( cSeeds.size() , static_cast<int>( cBend_strips*2));
-            static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cReadoutChip , cSeeds , cBends);
-            //LOG (DEBUG) << BOLDMAGENTA << "Before alignment ... stub lines : "<< RESET;
-            //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
-            // first align lines with stub seeds 
-            uint8_t cLineId=1;
-            for(size_t cIndex=0; cIndex < 3 ; cIndex++)
-            {
-                cSuccess = cSuccess | (static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cFe->getFeId(), cReadoutChip->getChipId() , cLineId , cSeeds[cIndex] , 8) << cIndex);
+                int cPosition = std::distance( cBendLUT.begin(), cIterator);
+                double cBend_strips = -7. + 0.5*cPosition; 
+                LOG (DEBUG) << BOLDBLUE << "Bend code of " << +cBendCode_phAlign << " found in register " << cPosition << " so a bend of " << cBend_strips << RESET;
+                
+                uint8_t cSuccess = 0x00;
+                std::vector<uint8_t> cSeeds{0x82,0x8E, 0x9E};
+                std::vector<int> cBends ( cSeeds.size() , static_cast<int>( cBend_strips*2));
+                static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theReadoutChip , cSeeds , cBends);
+                //LOG (DEBUG) << BOLDMAGENTA << "Before alignment ... stub lines : "<< RESET;
+                //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
+                // first align lines with stub seeds 
+                uint8_t cLineId=1;
+                for(size_t cIndex=0; cIndex < 3 ; cIndex++)
+                {
+                    cSuccess = cSuccess | (static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cHybrid->getId(), cReadoutChip->getId() , cLineId , cSeeds[cIndex] , 8) << cIndex);
+                    cLineId++;
+                }
+                //LOG (DEBUG) << BOLDMAGENTA << "After alignment ... stub lines with seeds : "<< RESET;
+                //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,3);
+                // then align lines with stub bends
+                uint8_t cAlignmentPattern = (cBendCode_phAlign << 4) | cBendCode_phAlign;
+                // first align lines with stub seeds 
+                //LOG (DEBUG) << BOLDMAGENTA << "Before alignment ... stub lines 0-4: alignment pattern is  "<< std::bitset<8>(cAlignmentPattern) << RESET;
+                //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->StubDebug(true,4);
+                cSuccess = cSuccess | ( static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cHybrid->getId(), cReadoutChip->getId() , cLineId , cAlignmentPattern , 8) << (cLineId-1)) ;
                 cLineId++;
+                //LOG (DEBUG) << BOLDMAGENTA << "After alignment ... stub lines 0-4 : "<< RESET;
+                //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,4);
+                // finally align lines with sync bit
+                //LOG (DEBUG) << BOLDMAGENTA << "Before alignment of last stub line ... stub lines 0-5: "<< RESET;
+                //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
+                cAlignmentPattern = (1 << 7) | cBendCode_phAlign; // sync bit + bend 
+                bool cTuned = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cHybrid->getId(), cReadoutChip->getId() , cLineId , cAlignmentPattern , 8);
+                if( !cTuned )
+                {
+                    LOG (INFO) << BOLDMAGENTA << "Checking if error bit is set ..."<< RESET;
+                    // check if error bit is set 
+                    cAlignmentPattern = (1 << 7) | (1 << 6) | cBendCode_phAlign;
+                    cSuccess = cSuccess | ( static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cHybrid->getId(), cReadoutChip->getId() , cLineId , cAlignmentPattern , 8) << (cLineId-1)) ;
+                }
+                else
+                    cSuccess = cSuccess | ( static_cast<uint8_t>(cTuned) << (cLineId-1)) ;
+                
+                
+                // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>(cSeeds[0]) << ", " << std::bitset<8>(cSeeds[1]) << ", " << std::bitset<8>(cSeeds[2]) << " on stub lines  0, 1 and 2." << RESET;
+                // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>((cBendCode_phAlign <<4)| cBendCode_phAlign) << " on stub line  4." << RESET;
+                // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>((1 << 7) | cBendCode_phAlign) << " on stub line  5." << RESET;
+                // LOG (INFO) << BOLDMAGENTA << "After alignment of last stub line ... stub lines 0-5: "<< RESET;
+                // (static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
+                
+                //now unmask all channels and set threshold and hit or logic back to their original values
+                fReadoutChipInterface-> maskChannelsGroup (theReadoutChip, cOriginalMask);
+                std::this_thread::sleep_for (std::chrono::milliseconds (50) );
+                LOG (INFO) << BOLDBLUE << "Setting threshold and HitOR back to orginal value [ " << +cThreshold << " ] DAC units." << RESET;
+                fReadoutChipInterface->WriteChipReg(theReadoutChip, "VCth" , cThreshold);
+                fReadoutChipInterface->WriteChipReg(theReadoutChip, "HitOr" , cHitOR);
+                fReadoutChipInterface->WriteChipReg( theReadoutChip , "PtCut" , cPtCut ); 
             }
-            //LOG (DEBUG) << BOLDMAGENTA << "After alignment ... stub lines with seeds : "<< RESET;
-            //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,3);
-            // then align lines with stub bends
-            uint8_t cAlignmentPattern = (cBendCode_phAlign << 4) | cBendCode_phAlign;
-            // first align lines with stub seeds 
-            //LOG (DEBUG) << BOLDMAGENTA << "Before alignment ... stub lines 0-4: alignment pattern is  "<< std::bitset<8>(cAlignmentPattern) << RESET;
-            //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->StubDebug(true,4);
-            cSuccess = cSuccess | ( static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cFe->getFeId(), cReadoutChip->getChipId() , cLineId , cAlignmentPattern , 8) << (cLineId-1)) ;
-            cLineId++;
-            //LOG (DEBUG) << BOLDMAGENTA << "After alignment ... stub lines 0-4 : "<< RESET;
-            //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,4);
-            // finally align lines with sync bit
-            //LOG (DEBUG) << BOLDMAGENTA << "Before alignment of last stub line ... stub lines 0-5: "<< RESET;
-            //(static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
-            cAlignmentPattern = (1 << 7) | cBendCode_phAlign; // sync bit + bend 
-            bool cTuned = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cFe->getFeId(), cReadoutChip->getChipId() , cLineId , cAlignmentPattern , 8);
-            if( !cTuned )
-            {
-                LOG (INFO) << BOLDMAGENTA << "Checking if error bit is set ..."<< RESET;
-                // check if error bit is set 
-                cAlignmentPattern = (1 << 7) | (1 << 6) | cBendCode_phAlign;
-                cSuccess = cSuccess | ( static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->PhaseTuning( pBoard, cFe->getFeId(), cReadoutChip->getChipId() , cLineId , cAlignmentPattern , 8) << (cLineId-1)) ;
-            }
-            else
-                cSuccess = cSuccess | ( static_cast<uint8_t>(cTuned) << (cLineId-1)) ;
-            
-            
-            // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>(cSeeds[0]) << ", " << std::bitset<8>(cSeeds[1]) << ", " << std::bitset<8>(cSeeds[2]) << " on stub lines  0, 1 and 2." << RESET;
-            // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>((cBendCode_phAlign <<4)| cBendCode_phAlign) << " on stub line  4." << RESET;
-            // LOG (INFO) << BOLDMAGENTA << "Expect pattern : " << std::bitset<8>((1 << 7) | cBendCode_phAlign) << " on stub line  5." << RESET;
-            // LOG (INFO) << BOLDMAGENTA << "After alignment of last stub line ... stub lines 0-5: "<< RESET;
-            // (static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface()))->StubDebug(true,5);
-            
-            //now unmask all channels and set threshold and hit or logic back to their original values
-            fReadoutChipInterface-> maskChannelsGroup (cReadoutChip, cOriginalMask);
-            std::this_thread::sleep_for (std::chrono::milliseconds (50) );
-            LOG (INFO) << BOLDBLUE << "Setting threshold and HitOR back to orginal value [ " << +cThreshold << " ] DAC units." << RESET;
-            fReadoutChipInterface->WriteChipReg(cReadoutChip, "VCth" , cThreshold);
-            fReadoutChipInterface->WriteChipReg(cReadoutChip, "HitOr" , cHitOR);
-            fReadoutChipInterface->WriteChipReg( cReadoutChip , "PtCut" , cPtCut ); 
         }
     }
     
@@ -242,22 +263,25 @@ bool BackEndAlignment::Align()
 {
     LOG (INFO) << BOLDBLUE << "Starting back-end alignment procedure .... " << RESET;
     bool cAligned=true;
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {   
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // read back register map before you've done anything 
-        auto cBoardRegisterMap = cBoard->getBeBoardRegMap();
+        auto cBoardRegisterMap = theBoard->getBeBoardRegMap();
         auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
         
-        bool cWithCIC = static_cast<OuterTrackerModule*>(cBoard->fModuleVector[0])->fCic != NULL;
+        OuterTrackerModule* theFirstHibrid = static_cast<OuterTrackerModule*>(cBoard->at(0)->at(0));
+        bool cWithCIC = theFirstHibrid->fCic != NULL;
         if( cWithCIC )
-            cAligned = this->CICAlignment(cBoard);
+            cAligned = this->CICAlignment(theBoard);
         else
         {
-            bool cWithCBC = (static_cast<OuterTrackerModule*>(cBoard->fModuleVector[0])->fReadoutChipVector[0]->getFrontEndType() == FrontEndType::CBC3);
-            bool cWithSSA = (static_cast<OuterTrackerModule*>(cBoard->fModuleVector[0])->fReadoutChipVector[0]->getFrontEndType() == FrontEndType::SSA);
+            ReadoutChip* theFirstReadoutChip = static_cast<ReadoutChip*>(cBoard->at(0)->at(0)->at(0));
+            bool cWithCBC = (theFirstReadoutChip->getFrontEndType() == FrontEndType::CBC3);
+            bool cWithSSA = (theFirstReadoutChip->getFrontEndType() == FrontEndType::SSA);
             if( cWithCBC )
             {
-                this->CBCAlignment(cBoard);
+                this->CBCAlignment(theBoard);
             }
             else if( cWithSSA )
             {
@@ -269,9 +293,9 @@ bool BackEndAlignment::Align()
         }
         // re-load configuration of fast command block from register map loaded from xml file 
         LOG (INFO) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
+        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(theBoard);
         // now send a fast reset 
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync(theBoard);
     }
     return cAligned;
 }
diff --git a/tools/BiasSweep.cc b/tools/BiasSweep.cc
index 95b493753..f03421f26 100644
--- a/tools/BiasSweep.cc
+++ b/tools/BiasSweep.cc
@@ -119,34 +119,38 @@ void BiasSweep::Initialize()
     //initialize empty bias sweep object
     fData = new BiasSweepData();
 
-    for (auto cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            fType = cFe->getFrontEndType();
-
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                cName = Form ("BiasSweep_Fe%d_Cbc%d", cCbc->getFeId(), cCbc->getChipId() );
-                cObj = gROOT->FindObject (cName);
-
-                if (cObj) delete cObj;
-
-                TTree* cTmpTree = new TTree (cName, cName);
-                //cTmpTree->Branch (Form ("BiasSweepData_Fe%d_Cbc%d", cCbc->getFeId(), cCbc->getChipId() ), "BiasSweepData", &fData);
-                cTmpTree->Branch ("Bias", &fData->fBias);
-                cTmpTree->Branch ("Fe", &fData->fFeId, "Fe/s" );
-                cTmpTree->Branch ("Chip", &fData->fCbcId, "Chip/s" );
-                cTmpTree->Branch ("Time", &fData->fTimestamp, "Time/l" );
-                cTmpTree->Branch ("Unit", &fData->fUnit, "Unit/C" );
-                cTmpTree->Branch ("InitialBiasValue", &fData->fInitialXValue, "InitialDAC/s");
-                cTmpTree->Branch ("InitialDMMValue", &fData->fInitialYValue, "InitialDMM/F");
-                cTmpTree->Branch ("BiasValues", &fData->fXValues);
-                cTmpTree->Branch ("DMMValues", &fData->fYValues);
-
-                this->bookHistogram (cCbc, "DataTree", cTmpTree);
-
-                LOG (INFO) << "TTree for BiasSweep data for Fe " << +cCbc->getFeId() << " Chip " << +cCbc->getChipId() << " created!";
+                Module* theHybrid = static_cast<Module*>(cHybrid);
+                fType = theHybrid->getFrontEndType();
+
+                for (auto cCbc : *cHybrid)
+                {
+                    cName = Form ("BiasSweep_Fe%d_Cbc%d", cHybrid->getId(), cCbc->getId() );
+                    cObj = gROOT->FindObject (cName);
+
+                    if (cObj) delete cObj;
+
+                    TTree* cTmpTree = new TTree (cName, cName);
+                    //cTmpTree->Branch (Form ("BiasSweepData_Fe%d_Cbc%d", cHybrid->getId(), cCbc->getId() ), "BiasSweepData", &fData);
+                    cTmpTree->Branch ("Bias", &fData->fBias);
+                    cTmpTree->Branch ("Fe", &fData->fFeId, "Fe/s" );
+                    cTmpTree->Branch ("Chip", &fData->fCbcId, "Chip/s" );
+                    cTmpTree->Branch ("Time", &fData->fTimestamp, "Time/l" );
+                    cTmpTree->Branch ("Unit", &fData->fUnit, "Unit/C" );
+                    cTmpTree->Branch ("InitialBiasValue", &fData->fInitialXValue, "InitialDAC/s");
+                    cTmpTree->Branch ("InitialDMMValue", &fData->fInitialYValue, "InitialDMM/F");
+                    cTmpTree->Branch ("BiasValues", &fData->fXValues);
+                    cTmpTree->Branch ("DMMValues", &fData->fYValues);
+
+                    this->bookHistogram (cCbc, "DataTree", cTmpTree);
+
+                    LOG (INFO) << "TTree for BiasSweep data for Fe " << +cHybrid->getId() << " Chip " << +cCbc->getId() << " created!";
+                }
             }
         }
 
diff --git a/tools/CBCPulseShape.cc b/tools/CBCPulseShape.cc
index 437f5346f..be6565e13 100644
--- a/tools/CBCPulseShape.cc
+++ b/tools/CBCPulseShape.cc
@@ -80,8 +80,7 @@ void CBCPulseShape::runCBCPulseShape(void)
 
         measureSCurves( findPedestal() );
         extractPedeNoise();
-        LOG(INFO) << BOLDYELLOW << "The threshold = " << fThresholdAndNoiseContainer.at(0)->at(0)->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold << RESET;
-
+        
         #ifdef __USE_ROOT__
             fCBCHistogramPulseShape.fillCBCPulseShapePlots(delay, fThresholdAndNoiseContainer);
         #else
diff --git a/tools/CMTester.cc b/tools/CMTester.cc
index 314a34e94..e09a7658d 100644
--- a/tools/CMTester.cc
+++ b/tools/CMTester.cc
@@ -15,186 +15,189 @@ void CMTester::Initialize()
 {
     // gStyle->SetOptStat( 000000 );
     // gStyle->SetTitleOffset( 1.3, "Y" );
-    for ( auto& cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto& cFe : cBoard->fModuleVector )
+        for (auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-
-            for ( auto& cCbc : cFe->fReadoutChipVector )
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                uint32_t cCbcId = cCbc->getChipId();
+                uint32_t cHybridId = cHybrid->getId();
 
-                // Fill Canvas Map
-                TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d_cbc%d", cFeId, cCbcId ), Form ( "FE%d CBC%d Online Canvas", cFeId, cCbcId ), 800, 800 );
-                ctmpCanvas->Divide ( 2, 2 );
-                fCanvasMap[cCbc] = ctmpCanvas;
+                for ( auto cCbc : *cHybrid )
+                {
+                    uint32_t cCbcId = cCbc->getId();
 
-                // here create an empty std::set<int> for noisy strips
-                std::set<int> cTmpSet;
-                fNoiseStripMap[cCbc] = cTmpSet;
+                    // Fill Canvas Map
+                    TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d_cbc%d", cHybridId, cCbcId ), Form ( "FE%d CBC%d Online Canvas", cHybridId, cCbcId ), 800, 800 );
+                    ctmpCanvas->Divide ( 2, 2 );
+                    fCanvasMap[cCbc] = ctmpCanvas;
 
-                // here create the CBC-wise histos
+                    // here create an empty std::set<int> for noisy strips
+                    std::set<int> cTmpSet;
+                    fNoiseStripMap[cCbc] = cTmpSet;
 
-                // histogram for the number of hits
-                TString cName = Form ( "h_nhits_Fe%dCbc%d", cFeId, cCbcId ) ;
-                TObject* cObj = gROOT->FindObject ( cName );
+                    // here create the CBC-wise histos
 
-                if ( cObj ) delete cObj;
+                    // histogram for the number of hits
+                    TString cName = Form ( "h_nhits_Fe%dCbc%d", cHybridId, cCbcId ) ;
+                    TObject* cObj = gROOT->FindObject ( cName );
 
-                TH1F* cHist = new TH1F ( cName, Form ( "Number of Hits FE%d CBC%d; Hits; Count", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cHist->SetLineColor ( 9 );
-                cHist->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "nhits", cHist );
+                    if ( cObj ) delete cObj;
 
-                // 2D profile for the combined odccupancy
-                cName = Form ( "p_combinedoccupancy_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = ( TProfile2D* ) gROOT->FindObject ( cName );
+                    TH1F* cHist = new TH1F ( cName, Form ( "Number of Hits FE%d CBC%d; Hits; Count", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cHist->SetLineColor ( 9 );
+                    cHist->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "nhits", cHist );
 
-                if ( cObj ) delete cObj;
+                    // 2D profile for the combined odccupancy
+                    cName = Form ( "p_combinedoccupancy_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = ( TProfile2D* ) gROOT->FindObject ( cName );
 
-                //  no clue why i can not call it cName but when I do, it produces a segfault!!
-                TProfile2D* c2DOccProfile = new TProfile2D ( cName, Form ( "Combined Occupancy FE%d CBC%d; Strip; Strip; Occupancy", cFeId, cCbcId ),  NCHANNELS + 1, -0.5, NCHANNELS + 0.5, NCHANNELS + 1, -0.5, NCHANNELS + 0.5 );
+                    if ( cObj ) delete cObj;
 
-                c2DOccProfile->SetMarkerColor ( 1 );
-                bookHistogram ( cCbc, "combinedoccupancy", c2DOccProfile );
+                    //  no clue why i can not call it cName but when I do, it produces a segfault!!
+                    TProfile2D* c2DOccProfile = new TProfile2D ( cName, Form ( "Combined Occupancy FE%d CBC%d; Strip; Strip; Occupancy", cHybridId, cCbcId ),  NCHANNELS + 1, -0.5, NCHANNELS + 0.5, NCHANNELS + 1, -0.5, NCHANNELS + 0.5 );
 
-                // 2D Profile for correlation coefficient
-                cName =  Form ( "p_correlation_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    c2DOccProfile->SetMarkerColor ( 1 );
+                    bookHistogram ( cCbc, "combinedoccupancy", c2DOccProfile );
 
-                if ( cObj ) delete cObj;
+                    // 2D Profile for correlation coefficient
+                    cName =  Form ( "p_correlation_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                TH2F* c2DHist = new TH2F ( cName, Form ( "Correlation FE%d CBC%d; Strip; Strip; Correlation coefficient", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5, NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                bookHistogram ( cCbc, "correlation", c2DHist );
+                    if ( cObj ) delete cObj;
 
-                // 1D projection of the combined odccupancy
-                cName =  Form ( "p_occupancyprojection_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    TH2F* c2DHist = new TH2F ( cName, Form ( "Correlation FE%d CBC%d; Strip; Strip; Correlation coefficient", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5, NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    bookHistogram ( cCbc, "correlation", c2DHist );
 
-                if ( cObj ) delete cObj;
+                    // 1D projection of the combined odccupancy
+                    cName =  Form ( "p_occupancyprojection_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                TProfile* cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy FE%d CBC%d;  NNeighbors; Probability", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cProfile->SetLineColor ( 9 );
-                cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "occupancyprojection", cProfile );
+                    if ( cObj ) delete cObj;
 
-                // 1D projection of the combined occupancy, but nearest neighbor calculated on both sides
-                cName =  Form ( "p_occupancyprojectionsymmetric_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    TProfile* cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy FE%d CBC%d;  NNeighbors; Probability", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cProfile->SetLineColor ( 9 );
+                    cProfile->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "occupancyprojection", cProfile );
 
-                if ( cObj ) delete cObj;
+                    // 1D projection of the combined occupancy, but nearest neighbor calculated on both sides
+                    cName =  Form ( "p_occupancyprojectionsymmetric_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy (+ and -) FE%d CBC%d;  NNeighbors (+-N); Probability", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cProfile->SetLineColor ( 9 );
-                cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "occupancyprojectionplusminus", cProfile );
+                    if ( cObj ) delete cObj;
 
-                // 1D projection of the uncorrelated odccupancy
-                cName = Form ( "p_uncorr_occupancyprojection_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy (+ and -) FE%d CBC%d;  NNeighbors (+-N); Probability", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cProfile->SetLineColor ( 9 );
+                    cProfile->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "occupancyprojectionplusminus", cProfile );
 
-                if ( cObj ) delete cObj;
+                    // 1D projection of the uncorrelated odccupancy
+                    cName = Form ( "p_uncorr_occupancyprojection_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                cProfile = new TProfile ( cName, Form ( "Projection of uncorrelated Occupancy FE%d CBC%d;  NNeighbors; Probability", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cProfile->SetLineColor ( 2 );
-                cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "uncorr_occupancyprojection", cProfile );
+                    if ( cObj ) delete cObj;
 
-                // 1D projection of the correlation
-                cName =  Form ( "p_correlationprojection_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    cProfile = new TProfile ( cName, Form ( "Projection of uncorrelated Occupancy FE%d CBC%d;  NNeighbors; Probability", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cProfile->SetLineColor ( 2 );
+                    cProfile->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "uncorr_occupancyprojection", cProfile );
 
-                if ( cObj ) delete cObj;
+                    // 1D projection of the correlation
+                    cName =  Form ( "p_correlationprojection_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                cProfile = new TProfile ( cName, Form ( "Projection of Correlation FE%d CBC%d;  NNeighbors; Correlation", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cProfile->SetLineColor ( 9 );
-                cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "correlationprojection", cProfile );
+                    if ( cObj ) delete cObj;
 
-                // 1D hit probability profile
-                cName = Form ( "p_hitprob_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    cProfile = new TProfile ( cName, Form ( "Projection of Correlation FE%d CBC%d;  NNeighbors; Correlation", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cProfile->SetLineColor ( 9 );
+                    cProfile->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "correlationprojection", cProfile );
 
-                if ( cObj ) delete cObj;
+                    // 1D hit probability profile
+                    cName = Form ( "p_hitprob_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                cProfile = new TProfile ( cName, Form ( "Hit Probability FE%d CBC%d;  Strip; Probability", cFeId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
-                cProfile->SetLineColor ( 9 );
-                cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cCbc, "hitprob", cProfile );
+                    if ( cObj ) delete cObj;
 
-                // dummy TF1* for fit & dummy TH1F* for 0CM
-                cName = Form ( "f_nhitsfit_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    cProfile = new TProfile ( cName, Form ( "Hit Probability FE%d CBC%d;  Strip; Probability", cHybridId, cCbcId ), NCHANNELS + 1, -.5, NCHANNELS + 0.5 );
+                    cProfile->SetLineColor ( 9 );
+                    cProfile->SetLineWidth ( 2 );
+                    bookHistogram ( cCbc, "hitprob", cProfile );
 
-                if ( cObj ) delete cObj;
+                    // dummy TF1* for fit & dummy TH1F* for 0CM
+                    cName = Form ( "f_nhitsfit_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                TF1* cCmFit = new TF1 ( cName, hitProbFunction, 0, 255, 4 );
-                bookHistogram ( cCbc, "nhitsfit", cCmFit );
+                    if ( cObj ) delete cObj;
 
-                cName = Form ( "h_nocm_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
+                    TF1* cCmFit = new TF1 ( cName, hitProbFunction, 0, 255, 4 );
+                    bookHistogram ( cCbc, "nhitsfit", cCmFit );
 
-                if ( cObj ) delete cObj;
+                    cName = Form ( "h_nocm_Fe%dCbc%d", cHybridId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
 
-                TH1F* cNoCM = new TH1F ( cName, "Noise hit distributtion", NCHANNELS + 1, -0.5, NCHANNELS + 0.5 );
-                cNoCM->SetLineColor ( 16 );
-                bookHistogram ( cCbc, "nocm", cNoCM );
-            }
+                    if ( cObj ) delete cObj;
 
-            // PER MODULE PLOTS
-            uint32_t cNCbc = cFe->getNChip();
+                    TH1F* cNoCM = new TH1F ( cName, "Noise hit distributtion", NCHANNELS + 1, -0.5, NCHANNELS + 0.5 );
+                    cNoCM->SetLineColor ( 16 );
+                    bookHistogram ( cCbc, "nocm", cNoCM );
+                }
 
-            // 2D profile for the combined odccupancy
-            TString cName =  Form ( "p_module_combinedoccupancy_Fe%d", cFeId ) ;
-            TObject* cObj = gROOT->FindObject ( cName );
+                // PER MODULE PLOTS
+                uint32_t cNCbc = cFe->getNChip();
 
-            if ( cObj ) delete cObj;
+                // 2D profile for the combined odccupancy
+                TString cName =  Form ( "p_module_combinedoccupancy_Fe%d", cHybridId ) ;
+                TObject* cObj = gROOT->FindObject ( cName );
 
-            TProfile2D* c2DProfile = new TProfile2D ( cName, Form ( "Combined Occupancy FE%d; Strip; Strip; Occupancy", cFeId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-            bookHistogram ( cFe, "module_combinedoccupancy", c2DProfile );
+                if ( cObj ) delete cObj;
 
-            // 2D Hist for correlation coefficient
-            cName =  Form ( "p_module_correlation_Fe%d", cFeId );
-            cObj = gROOT->FindObject ( cName );
+                TProfile2D* c2DProfile = new TProfile2D ( cName, Form ( "Combined Occupancy FE%d; Strip; Strip; Occupancy", cHybridId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
+                bookHistogram ( cFe, "module_combinedoccupancy", c2DProfile );
 
-            if ( cObj ) delete cObj;
+                // 2D Hist for correlation coefficient
+                cName =  Form ( "p_module_correlation_Fe%d", cHybridId );
+                cObj = gROOT->FindObject ( cName );
 
-            TH2F* c2DHist = new TH2F ( cName, Form ( "Correlation FE%d; Strip; Strip; Correlation coefficient", cFeId  ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-            bookHistogram ( cFe, "module_correlation", c2DHist );
+                if ( cObj ) delete cObj;
 
-            // 1D projection of the combined odccupancy
-            cName =  Form ( "p_module_occupancyprojection_Fe%d", cFeId );
-            cObj = gROOT->FindObject ( cName );
+                TH2F* c2DHist = new TH2F ( cName, Form ( "Correlation FE%d; Strip; Strip; Correlation coefficient", cHybridId  ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
+                bookHistogram ( cFe, "module_correlation", c2DHist );
 
-            if ( cObj ) delete cObj;
+                // 1D projection of the combined odccupancy
+                cName =  Form ( "p_module_occupancyprojection_Fe%d", cHybridId );
+                cObj = gROOT->FindObject ( cName );
 
-            TProfile* cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy FE%d;  NNeighbors; Probability", cFeId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-            cProfile->SetLineColor ( 9 );
-            cProfile->SetLineWidth ( 2 );
-            bookHistogram ( cFe, "module_occupancyprojection", cProfile );
+                if ( cObj ) delete cObj;
 
-            // 1D projection of the uncorrelated occupancy
-            cName = Form ( "p_module_uncorr_occupancyprojection_Fe%d", cFeId );
-            cObj = gROOT->FindObject ( cName );
+                TProfile* cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy FE%d;  NNeighbors; Probability", cHybridId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
+                cProfile->SetLineColor ( 9 );
+                cProfile->SetLineWidth ( 2 );
+                bookHistogram ( cFe, "module_occupancyprojection", cProfile );
 
-            if ( cObj ) delete cObj;
+                // 1D projection of the uncorrelated occupancy
+                cName = Form ( "p_module_uncorr_occupancyprojection_Fe%d", cHybridId );
+                cObj = gROOT->FindObject ( cName );
 
-            cProfile = new TProfile ( cName, Form ( "Projection of uncorrelated Occupancy FE%d;  NNeighbors; Probability", cFeId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-            cProfile->SetLineColor ( 2 );
-            cProfile->SetLineWidth ( 2 );
-            bookHistogram ( cFe, "module_uncorr_occupancyprojection", cProfile );
+                if ( cObj ) delete cObj;
 
-            // 1D projection of the correlation
-            cName =  Form ( "p_module_correlationprojection_Fe%d", cFeId );
-            cObj = gROOT->FindObject ( cName );
+                cProfile = new TProfile ( cName, Form ( "Projection of uncorrelated Occupancy FE%d;  NNeighbors; Probability", cHybridId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
+                cProfile->SetLineColor ( 2 );
+                cProfile->SetLineWidth ( 2 );
+                bookHistogram ( cFe, "module_uncorr_occupancyprojection", cProfile );
 
-            if ( cObj ) delete cObj;
+                // 1D projection of the correlation
+                cName =  Form ( "p_module_correlationprojection_Fe%d", cHybridId );
+                cObj = gROOT->FindObject ( cName );
+
+                if ( cObj ) delete cObj;
 
-            cProfile = new TProfile ( cName, Form ( "Projection of Correlation FE%d;  NNeighbors; Correlation", cFeId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-            cProfile->SetLineColor ( 9 );
-            cProfile->SetLineWidth ( 2 );
-            bookHistogram ( cFe, "module_correlationprojection", cProfile );
+                cProfile = new TProfile ( cName, Form ( "Projection of Correlation FE%d;  NNeighbors; Correlation", cHybridId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
+                cProfile->SetLineColor ( 9 );
+                cProfile->SetLineWidth ( 2 );
+                bookHistogram ( cFe, "module_correlationprojection", cProfile );
+            }
         }
     }
 
@@ -210,7 +213,7 @@ void CMTester::ScanNoiseChannels()
     LOG (INFO) << "Scanning for noisy channels! " ;
     uint32_t cTotalEvents = 500;
 
-    for ( BeBoard* pBoard : fBoardVector )
+    for (auto pBoard : *fDetectorContainer )
     {
         uint32_t cN = 1;
         uint32_t cNthAcq = 0;
@@ -219,30 +222,33 @@ void CMTester::ScanNoiseChannels()
 
         //while ( cN <=  cTotalEvents )
         //{
-        ReadNEvents ( pBoard, cTotalEvents );
-        const std::vector<Event*>& events = GetEvents ( pBoard );
+        BeBoard *theBoard = static_cast<BeBoard*>(pBoard);
+        ReadNEvents ( theBoard, cTotalEvents );
+        const std::vector<Event*>& events = GetEvents ( theBoard );
 
         // Loop over Events from this Acquisition
         for ( auto& cEvent : events )
         {
-            for ( auto& cFe : pBoard->fModuleVector )
+            for ( auto cOpticalReadout : *pBoard )
             {
-                for ( auto& cCbc : cFe->fReadoutChipVector )
+                for ( auto cHybrid : *cOpticalReadout )
                 {
-                    // just re-use the hitprobability histogram here?
-                    // this has to go into a dedicated method
-                    TProfile* cNoiseStrips = dynamic_cast<TProfile*> ( getHist ( cCbc, "hitprob" ) );
-
-                    const std::vector<bool>& list = cEvent->DataBitVector ( cFe->getFeId(), cCbc->getChipId() );
-                    int cChan = 0;
-
-                    for ( const auto& b : list )
+                    for ( auto cCbc : *cHybrid )
                     {
-                        int fillvalue = ( b ) ? 1 : 0;
-                        cNoiseStrips->Fill ( cChan++, fillvalue );
+                        // just re-use the hitprobability histogram here?
+                        // this has to go into a dedicated method
+                        TProfile* cNoiseStrips = dynamic_cast<TProfile*> ( getHist ( cCbc, "hitprob" ) );
+
+                        const std::vector<bool>& list = cEvent->DataBitVector ( cHybrid->getId(), cCbc->getId() );
+                        int cChan = 0;
+
+                        for ( const auto& b : list )
+                        {
+                            int fillvalue = ( b ) ? 1 : 0;
+                            cNoiseStrips->Fill ( cChan++, fillvalue );
+                        }
                     }
                 }
-            }
 
             if ( cN % 100 == 0 )
                 // updateHists();
@@ -265,7 +271,7 @@ void CMTester::ScanNoiseChannels()
 
         auto cNoiseSet  =  fNoiseStripMap.find ( cCbc.first );
 
-        if ( cNoiseSet == std::end ( fNoiseStripMap ) ) LOG (ERROR) << " Error: Could not find noisy strip container for CBC " << int ( cCbc.first->getChipId() ) ;
+        if ( cNoiseSet == std::end ( fNoiseStripMap ) ) LOG (ERROR) << " Error: Could not find noisy strip container for CBC " << int ( cCbc.first->getId() ) ;
         else
         {
             double cMean = cNoiseStrips->GetMean ( 2 );
@@ -279,7 +285,7 @@ void CMTester::ScanNoiseChannels()
                 if ( fabs ( cStripOccupancy - cMean ) > cMean / 2 )
                 {
                     cNoiseSet->second.insert ( cNoiseStrips->GetBinCenter ( cBin ) );
-                    LOG (INFO) << "Found noisy Strip on CBC " << int ( cCbc.first->getChipId() ) << " : " << cNoiseStrips->GetBinCenter ( cBin ) ;
+                    LOG (INFO) << "Found noisy Strip on CBC " << int ( cCbc.first->getId() ) << " : " << cNoiseStrips->GetBinCenter ( cBin ) ;
                 }
             }
         }
@@ -307,18 +313,20 @@ void CMTester::TakeData()
     //CbcRegReader cReader ( fReadoutChipInterface, "VCth" );
     // accept( cReader );
 
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard *theBoard = static_cast<BeBoard*>(pBoard);
+
         uint32_t cN = 0;
         uint32_t cNthAcq = 0;
 
-        fBeBoardInterface->Start ( pBoard );
+        fBeBoardInterface->Start ( theBoard );
         //while ( cN <=  fNevents )
         //{
-        // Run( pBoard, cNthAcq );
-        //ReadData (pBoard);
-        ReadNEvents ( pBoard, fNevents );
-        const std::vector<Event*>& events = GetEvents ( pBoard );
+        // Run( theBoard, cNthAcq );
+        //ReadData (theBoard);
+        ReadNEvents ( theBoard, fNevents );
+        const std::vector<Event*>& events = GetEvents ( theBoard );
 
         // Loop over Events from this Acquisition
 
@@ -328,7 +336,7 @@ void CMTester::TakeData()
 
             if (cN > fNevents ) continue; // Needed when using ReadData on CBC3
 
-            analyze ( pBoard, cEvent );
+            analyze ( theBoard, cEvent );
 
             if ( cN % 100 == 0 )
             {
@@ -379,9 +387,9 @@ void CMTester::FinishRun()
 	float CMnoiseFrac = fabs ( cNHitsFit->GetParameter ( 1 ) );
 	float CMnoiseFracErr = fabs ( cNHitsFit->GetParError ( 1 ) );
 	if (fTotalNoise[iCbc]>0) 
-	    LOG (INFO) << BOLDRED << "Average noise on FE " << +cCbc.first->getFeId() << " CBC " << +cCbc.first->getChipId() << " : " << fTotalNoise[iCbc] << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%, so "<<CMnoiseFrac*fTotalNoise[iCbc]<<" VCth." << RESET ;
+	    LOG (INFO) << BOLDRED << "Average noise on FE " << +cCbc.cHybrid->getId() << " CBC " << +cCbc.first->getId() << " : " << fTotalNoise[iCbc] << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%, so "<<CMnoiseFrac*fTotalNoise[iCbc]<<" VCth." << RESET ;
 	else 
-	    LOG (INFO) << BOLDRED << "FE " << +cCbc.first->getFeId() << " CBC " << +cCbc.first->getChipId() << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%" << RESET ;
+	    LOG (INFO) << BOLDRED << "FE " << +cCbc.cHybrid->getId() << " CBC " << +cCbc.first->getId() << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%" << RESET ;
 
 
         // now compute the correlation coefficient and the uncorrelated probability
@@ -420,7 +428,7 @@ void CMTester::FinishRun()
     // now module wise
     for ( auto& cFe : fModuleHistMap )
     {
-        TString cName = Form ( "FE%d", cFe.first->getFeId() );
+        TString cName = Form ( "FE%d", cFe.cHybrid->getId() );
 
         // get histograms
         TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cFe.first, "module_combinedoccupancy" ) );
@@ -464,115 +472,117 @@ void CMTester::FinishRun()
 
 void CMTester::analyze ( BeBoard* pBoard, const Event* pEvent )
 {
-   
-    for ( auto& cFe : pBoard->fModuleVector )
+    for(auto cOpticalGroup : *pBoard)
     {
+        for ( auto cHybrid : *cOpticalGroup )
+        {
 
-        std::vector<bool> cModuleData; // use this to store data for all CBCs....
+            std::vector<bool> cModuleData; // use this to store data for all CBCs....
 
-        for ( auto& cCbc : cFe->fReadoutChipVector )
-        {
+            for ( auto cCbc : *cHybrid )
+            {
 
-            // here loop over the channels and fill the histograms
-            // dont forget to get them first
-            TH1F* cTmpNHits = dynamic_cast<TH1F*> ( getHist ( cCbc, "nhits" ) );
-            TProfile* cTmpHitProb = dynamic_cast<TProfile*> ( getHist ( cCbc, "hitprob" ) );
-            TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cCbc, "combinedoccupancy" ) );
-            TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cCbc, "occupancyprojection" ) );
-            TProfile* cTmpCombinedOccPM = dynamic_cast<TProfile*> ( getHist ( cCbc, "occupancyprojectionplusminus" ) );
+                // here loop over the channels and fill the histograms
+                // dont forget to get them first
+                TH1F* cTmpNHits = dynamic_cast<TH1F*> ( getHist ( cCbc, "nhits" ) );
+                TProfile* cTmpHitProb = dynamic_cast<TProfile*> ( getHist ( cCbc, "hitprob" ) );
+                TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cCbc, "combinedoccupancy" ) );
+                TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cCbc, "occupancyprojection" ) );
+                TProfile* cTmpCombinedOccPM = dynamic_cast<TProfile*> ( getHist ( cCbc, "occupancyprojectionplusminus" ) );
 
-            int cNHits = 0;
-            int cEventHits = pEvent->GetNHits (cCbc->getFeId(), cCbc->getChipId() );
+                int cNHits = 0;
+                int cEventHits = pEvent->GetNHits (cHybrid->getId(), cCbc->getId() );
 
-            if (cEventHits > 250) LOG (INFO) << " Found an event with " << cEventHits << " hits on a CBC! Is this expected?" ;
+                if (cEventHits > 250) LOG (INFO) << " Found an event with " << cEventHits << " hits on a CBC! Is this expected?" ;
 
-            // here add a check if the strip is masked and if I am simulating or not!
-            std::vector<bool> cSimResult;
+                // here add a check if the strip is masked and if I am simulating or not!
+                std::vector<bool> cSimResult;
 
-            if ( fDoSimulate )
-            {
-                for ( int cChan = 0; cChan < 254; cChan++ )
+                if ( fDoSimulate )
                 {
-                    bool cResult = randHit ( fSimOccupancy / float ( 100 ) );
-                    cSimResult.push_back ( cResult );
+                    for ( int cChan = 0; cChan < 254; cChan++ )
+                    {
+                        bool cResult = randHit ( fSimOccupancy / float ( 100 ) );
+                        cSimResult.push_back ( cResult );
+                    }
                 }
-            }
 
-            for ( int cChan = 0; cChan < NCHANNELS; cChan++ )
-            {
-                bool chit;
+                for ( int cChan = 0; cChan < NCHANNELS; cChan++ )
+                {
+                    bool chit;
 
-                if ( fDoSimulate ) chit = cSimResult.at ( cChan );
-                else chit = pEvent->DataBit ( cFe->getFeId(), cCbc->getChipId(), cChan );
+                    if ( fDoSimulate ) chit = cSimResult.at ( cChan );
+                    else chit = pEvent->DataBit ( cHybrid->getId(), cCbc->getId(), cChan );
 
-                // move the CBC data in a vector that has data for the whole module
-                cModuleData.push_back ( chit );
+                    // move the CBC data in a vector that has data for the whole module
+                    cModuleData.push_back ( chit );
 
-                //  count hits/event
-                if ( chit  && !isMasked ( cCbc, cChan ) )
-                    cNHits++;
+                    //  count hits/event
+                    if ( chit  && !isMasked ( cCbc, cChan ) )
+                        cNHits++;
 
-                // Fill Single Strip Efficiency
-                if ( !isMasked ( cCbc, cChan ) ) cTmpHitProb->Fill ( cChan, int ( chit ) );
+                    // Fill Single Strip Efficiency
+                    if ( !isMasked ( cCbc, cChan ) ) cTmpHitProb->Fill ( cChan, int ( chit ) );
 
-                // For combined occupancy 1D projection & 2D profile
-                for ( int cChan2 = 0; cChan2 < 254; cChan2++ )
-                {
-                    bool chit2;
+                    // For combined occupancy 1D projection & 2D profile
+                    for ( int cChan2 = 0; cChan2 < 254; cChan2++ )
+                    {
+                        bool chit2;
 
-                    if ( fDoSimulate ) chit2 = cSimResult.at ( cChan2 );
-                    else chit2 = pEvent->DataBit ( cFe->getFeId(), cCbc->getChipId(), cChan2 );
+                        if ( fDoSimulate ) chit2 = cSimResult.at ( cChan2 );
+                        else chit2 = pEvent->DataBit ( cHybrid->getId(), cCbc->getId(), cChan2 );
 
-                    int cfillValue = 0;
+                        int cfillValue = 0;
 
-                    if ( chit && chit2 ) cfillValue = 1;
+                        if ( chit && chit2 ) cfillValue = 1;
 
-                    if ( !isMasked ( cCbc, cChan ) && !isMasked ( cCbc, cChan2 ) )
-                    {
-                        // Fill 2D occupancy
-                        cTmpOccProfile->Fill ( cChan, cChan2, cfillValue );
+                        if ( !isMasked ( cCbc, cChan ) && !isMasked ( cCbc, cChan2 ) )
+                        {
+                            // Fill 2D occupancy
+                            cTmpOccProfile->Fill ( cChan, cChan2, cfillValue );
 
-                        // Fill projection: this could be done in FinishRun() but then no live updates
-                        if ( cChan - cChan2 >= 0 ) cTmpCombinedOcc->Fill ( cChan - cChan2, cfillValue );
+                            // Fill projection: this could be done in FinishRun() but then no live updates
+                            if ( cChan - cChan2 >= 0 ) cTmpCombinedOcc->Fill ( cChan - cChan2, cfillValue );
 
-                        // Cross-check: what if we also consider the -N neighbors, not just +N ones? Should get the same result...
-                        cTmpCombinedOccPM->Fill ( abs (cChan - cChan2), cfillValue );
+                            // Cross-check: what if we also consider the -N neighbors, not just +N ones? Should get the same result...
+                            cTmpCombinedOccPM->Fill ( abs (cChan - cChan2), cfillValue );
+                        }
                     }
                 }
-            }
 
-            // Fill NHits Histogram
-            cTmpNHits->Fill ( cNHits );
+                // Fill NHits Histogram
+                cTmpNHits->Fill ( cNHits );
 
-        }
-
-        // Here deal with per-module Histograms
-        TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cFe,  "module_combinedoccupancy" ) );
-        TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cFe, "module_occupancyprojection" ) );
+            }
 
-        uint32_t cChanCt1 = 0;
+            // Here deal with per-module Histograms
+            TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cFe,  "module_combinedoccupancy" ) );
+            TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cFe, "module_occupancyprojection" ) );
 
-        // since I use the module bool vector i constructed myself this already includes simulation results if simulation flag is set!
-        for ( auto cChan1 : cModuleData )
-        {
-            uint32_t cChanCt2 = 0;
+            uint32_t cChanCt1 = 0;
 
-            for ( auto cChan2 : cModuleData )
+            // since I use the module bool vector i constructed myself this already includes simulation results if simulation flag is set!
+            for ( auto cChan1 : cModuleData )
             {
-                int fillvalue = 0;
+                uint32_t cChanCt2 = 0;
 
-                if ( cChan1 && cChan2 )  fillvalue = 1;
-
-                if ( !isMasked ( cChanCt1 ) && !isMasked ( cChanCt2 ) )
+                for ( auto cChan2 : cModuleData )
                 {
-                    cTmpOccProfile->Fill ( cChanCt1, cChanCt2, fillvalue );
-                    cTmpCombinedOcc->Fill ( cChanCt1 - cChanCt2, fillvalue );
+                    int fillvalue = 0;
+
+                    if ( cChan1 && cChan2 )  fillvalue = 1;
+
+                    if ( !isMasked ( cChanCt1 ) && !isMasked ( cChanCt2 ) )
+                    {
+                        cTmpOccProfile->Fill ( cChanCt1, cChanCt2, fillvalue );
+                        cTmpCombinedOcc->Fill ( cChanCt1 - cChanCt2, fillvalue );
+                    }
+
+                    cChanCt2++;
                 }
 
-                cChanCt2++;
+                cChanCt1++;
             }
-
-            cChanCt1++;
         }
     }
 }
@@ -585,7 +595,7 @@ void CMTester::updateHists ( bool pFinal )
     {
         auto cCanvas = fCanvasMap.find ( cCbc.first );
 
-        if ( cCanvas == fCanvasMap.end() ) LOG (INFO) << "Error: could not find the canvas for Chip " << int ( cCbc.first->getChipId() ) ;
+        if ( cCanvas == fCanvasMap.end() ) LOG (INFO) << "Error: could not find the canvas for Chip " << int ( cCbc.first->getId() ) ;
         else
         {
             TH1F* cTmpNHits = dynamic_cast<TH1F*> ( getHist ( cCbc.first, "nhits" ) );
@@ -674,7 +684,7 @@ bool CMTester::isMasked ( Chip* pCbc, int pChannel )
 
     if ( cNoiseStripSet == std::end ( fNoiseStripMap ) )
     {
-        LOG (ERROR) << "Error: could not find the set of noisy strips for CBC " << int ( cNoiseStripSet->first->getChipId() ) ;
+        LOG (ERROR) << "Error: could not find the set of noisy strips for CBC " << int ( cNoiseStripSet->first->getId() ) ;
         return false;
     }
     else
@@ -702,7 +712,7 @@ bool CMTester::isMasked ( int pGlobalChannel )
 
     for ( const auto& cNoiseStripSet : fNoiseStripMap )
     {
-        if ( int ( cNoiseStripSet.first->getChipId() ) == cCbcId )
+        if ( int ( cNoiseStripSet.first->getId() ) == cCbcId )
         {
             auto cNoiseStrip = cNoiseStripSet.second.find ( pGlobalChannel - cCbcId * 254 );
 
diff --git a/tools/CalibrationExample.cc b/tools/CalibrationExample.cc
index 23e687f5a..14ad80bb0 100644
--- a/tools/CalibrationExample.cc
+++ b/tools/CalibrationExample.cc
@@ -52,18 +52,21 @@ void CalibrationExample::runCalibrationExample(void)
 
         for ( auto &event : eventVector ) //for on events - begin 
         {
-            for(auto module: *board) // for on module - begin 
+            for(auto opticalGroup: *board)
             {
-                for(auto chip: *module) // for on chip - begin 
+                for(auto hybrid: *opticalGroup) // for on hybrid - begin 
                 {
-                    unsigned int channelNumber = 0;
-                    for(auto &channel : *chip->getChannelContainer<uint32_t>()) // for on channel - begin 
+                    for(auto chip: *hybrid) // for on chip - begin 
                     {
-                        //retreive data in the old way and add to the current number of hits of the corresponding channel
-                        channel += event->DataBit ( module->getId(), chip->getId(), channelNumber++);
-                    } // for on channel - end 
-                } // for on chip - end 
-            } // for on module - end 
+                        unsigned int channelNumber = 0;
+                        for(auto &channel : *chip->getChannelContainer<uint32_t>()) // for on channel - begin 
+                        {
+                            //retreive data in the old way and add to the current number of hits of the corresponding channel
+                            channel += event->DataBit ( hybrid->getId(), chip->getId(), channelNumber++);
+                        } // for on channel - end 
+                    } // for on chip - end 
+                } // for on hybrid - end 
+            } // for on opticalGroup - end 
         } // for on events - end 
     } // for on board - end 
 	
diff --git a/tools/Channel.cc b/tools/Channel.cc
index 93320a168..c419fddec 100644
--- a/tools/Channel.cc
+++ b/tools/Channel.cc
@@ -6,9 +6,10 @@
 
 
 
-Channel::Channel ( uint8_t pBeId, uint8_t pFeId, uint8_t pCbcId, uint8_t pChannelId ) :
+Channel::Channel ( uint8_t pBeId, uint8_t pFeId, uint8_t pOpticalGroup, uint8_t pCbcId, uint8_t pChannelId ) :
     fBeId ( pBeId ),
     fFeId ( pFeId ),
+    fOpticalGroup ( pOpticalGroup ),
     fCbcId ( pCbcId ),
     fChannelId ( pChannelId )
 {
diff --git a/tools/Channel.h b/tools/Channel.h
index a44d48070..88b11e861 100644
--- a/tools/Channel.h
+++ b/tools/Channel.h
@@ -36,13 +36,14 @@
 struct Channel
 {
 
-    Channel ( uint8_t pBeId, uint8_t pFeId, uint8_t pCbcId, uint8_t pChannelId );
+    Channel ( uint8_t pBeId, uint8_t pFeId, uint8_t pOpticalGroup, uint8_t pCbcId, uint8_t pChannelId );
     ~Channel();
 
     // members
     // Ids
     uint8_t fBeId;  /*!< Back End ID */
     uint8_t fFeId;  /*!< Front End ID */
+    uint8_t fOpticalGroup;  /*!< Optical Group ID */
     uint8_t fCbcId;  /*!< CBC ID*/
     uint8_t fChannelId;  /*!< Channel Number */
     bool fFitted; /*!< Flag to select the algroithm*/
diff --git a/tools/CicFEAlignment.cc b/tools/CicFEAlignment.cc
index e11c37585..eda6d33df 100644
--- a/tools/CicFEAlignment.cc
+++ b/tools/CicFEAlignment.cc
@@ -24,27 +24,32 @@ CicFEAlignment::~CicFEAlignment()
 void CicFEAlignment::Reset()
 {
     // set everything back to original values .. like I wasn't here 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Resetting all registers on back-end board " << +cBoard->getBeBoardId() << RESET;
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        LOG (INFO) << BOLDBLUE << "Resetting all registers on back-end board " << +cBoard->getId() << RESET;
         auto& cBeRegMap = fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>();
         std::vector< std::pair<std::string, uint32_t> > cVecBeBoardRegs; cVecBeBoardRegs.clear();
         for(auto cReg : cBeRegMap )
             cVecBeBoardRegs.push_back(make_pair(cReg.first, cReg.second));
-        fBeBoardInterface->WriteBoardMultReg ( cBoard, cVecBeBoardRegs);
+        fBeBoardInterface->WriteBoardMultReg ( theBoard, cVecBeBoardRegs);
 
-        auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        uint16_t boardIndex = cBoard->getIndex();
+        for (auto cOpticalGroup : *cBoard)
         {
-            auto& cRegMapThisHybrid = cRegMapThisBoard->at(cFe->getIndex());
-            LOG (INFO) << BOLDBLUE << "Resetting all registers on readout chips connected to FEhybrid#" << (cFe->getFeId() ) << " back to their original values..." << RESET;
-            for (auto& cChip : cFe->fReadoutChipVector)
+            uint16_t opticalGroupIndex = cOpticalGroup->getIndex();
+            for (auto cHybrid : *cOpticalGroup)
             {
-                auto& cRegMapThisChip = cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>(); 
-                std::vector< std::pair<std::string, uint16_t> > cVecRegisters; cVecRegisters.clear();
-                for(auto cReg : cRegMapThisChip )
-                    cVecRegisters.push_back(make_pair(cReg.first, cReg.second.fValue));
-                fReadoutChipInterface->WriteChipMultReg ( cChip , cVecRegisters );
+                uint16_t hybridIndex = cHybrid->getIndex();
+                LOG (INFO) << BOLDBLUE << "Resetting all registers on readout chips connected to FEhybrid#" << +(cHybrid->getId()) << " back to their original values..." << RESET;
+                for (auto cChip : *cHybrid)
+                {
+                    uint16_t chipIndex = cChip->getIndex();
+                    std::vector< std::pair<std::string, uint16_t> > cVecRegisters;
+                    for(auto cReg : fRegMapContainer.at(boardIndex)->at(opticalGroupIndex)->at(hybridIndex)->at(chipIndex)->getSummary<ChipRegMap>() )
+                        cVecRegisters.push_back(make_pair(cReg.first, cReg.second.fValue));
+                    fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cChip) , cVecRegisters );
+                }
             }
         }
     }
@@ -71,7 +76,7 @@ void CicFEAlignment::Initialise ()
     ContainerFactory::copyAndInitStructure<std::vector<uint8_t>>(*fDetectorContainer, fPhaseAlignmentValues);  
     ContainerFactory::copyAndInitStructure<std::vector<uint8_t>>(*fDetectorContainer, fWordAlignmentValues);  
     
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
@@ -79,52 +84,61 @@ void CicFEAlignment::Initialise ()
         auto& cPtCutThisBoard = fPtCuts.at(cBoard->getIndex());
         auto& cPhaseAlignmentThisBoard = fPhaseAlignmentValues.at(cBoard->getIndex());
         auto& cWordAlignmentThisBoard = fWordAlignmentValues.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+
+        for(auto cHybrid : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
-            auto& cPhaseAlignmentThisHybrid = cPhaseAlignmentThisBoard->at(cFe->getIndex());
-            auto& cWordAlignmentThisHybrid = cWordAlignmentThisBoard->at(cFe->getIndex());
-
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cHybrid)
             {
-                cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "VCth" );
-                cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "Pipe&StubInpSel&Ptwidth" );
-                cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "HIP&TestMode" );
-                cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "PtCut" );
-                // prepare alignment value result 
-                cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().clear();
-                cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().clear();
-                // 5 stub lines + 1 L1 line 
-                for( int cLine=0; cLine < 6; cLine++)
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cHybrid->getIndex());
+                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cHybrid->getIndex());
+                auto& cPhaseAlignmentThisHybrid = cPhaseAlignmentThisBoard->at(cHybrid->getIndex());
+                auto& cWordAlignmentThisHybrid = cWordAlignmentThisBoard->at(cHybrid->getIndex());
+
+                //configure CBCs 
+                for (auto& cChip : *cHybrid)
                 {
-                    cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().push_back(0);
-                    if( cLine < 5 )
-                        cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().push_back(0);
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    CbcInterface* theCbcInterface = static_cast<CbcInterface*>(fReadoutChipInterface);
+                    cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = theCbcInterface->ReadChipReg(theChip, "VCth" );
+                    cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = theCbcInterface->ReadChipReg(theChip, "Pipe&StubInpSel&Ptwidth" );
+                    cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = theCbcInterface->ReadChipReg(theChip, "HIP&TestMode" );
+                    cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = theCbcInterface->ReadChipReg(theChip, "PtCut" );
+                    // prepare alignment value result 
+                    cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().clear();
+                    cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().clear();
+                    // 5 stub lines + 1 L1 line 
+                    for( int cLine=0; cLine < 6; cLine++)
+                    {
+                        cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().push_back(0);
+                        if( cLine < 5 )
+                            cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>().push_back(0);
+                    }
                 }
             }
         }
     }
 
     // retreive original settings for all chips and all back-end boards 
-    ContainerFactory::copyAndInitStructure<ChipRegMap>(*fDetectorContainer, fRegMapContainer);
-    ContainerFactory::copyAndInitStructure<BeBoardRegMap>(*fDetectorContainer, fBoardRegContainer);
-    for (auto cBoard : this->fBoardVector)
+    ContainerFactory::copyAndInitChip<ChipRegMap>(*fDetectorContainer, fRegMapContainer);
+    ContainerFactory::copyAndInitBoard<BeBoardRegMap>(*fDetectorContainer, fBoardRegContainer);
+    for(auto cBoard : *fDetectorContainer)
     {
-        fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>() = cBoard->getBeBoardRegMap();
-        auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        fBoardRegContainer.at(cBoard->getIndex())->getSummary<BeBoardRegMap>() = static_cast<const BeBoard*>(cBoard)->getBeBoardRegMap();
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cRegMapThisHybrid = cRegMapThisBoard->at(cFe->getIndex());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>() = cChip->getRegMap();
+                for(auto cChip : *cHybrid)
+                {
+                    fRegMapContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<ChipRegMap>() = static_cast<ReadoutChip*>(cChip)->getRegMap();
+                }
             }
         }
     }
+
+
 }
 
 void CicFEAlignment::writeObjects()
@@ -165,6 +179,7 @@ void CicFEAlignment::Start(int currentRun)
     LOG (INFO) << BOLDGREEN << "SUCCESSFUL " << BOLDBLUE << " bx0 alignment step in CIC ... " << RESET;
     fSuccess = (cPhaseAligned && cWordAligned && cBxAligned );
 }
+
 std::vector<std::vector<uint8_t>> CicFEAlignment::SortWordAlignmentValues( std::vector<std::vector<uint8_t>> pWordAlignmentValues ) 
 {
     // 8 FEs per CIC .... 6 SLVS lines per FE
@@ -178,6 +193,7 @@ std::vector<std::vector<uint8_t>> CicFEAlignment::SortWordAlignmentValues( std::
     }
     return cValuesFEs;
 }
+
 std::vector<std::vector<uint8_t>> CicFEAlignment::SortOptimalTaps( std::vector<std::vector<uint8_t>> pOptimalTaps ) 
 {
     // 8 FEs per CIC .... 6 SLVS lines per FE
@@ -209,27 +225,33 @@ std::vector<std::vector<uint8_t>> CicFEAlignment::SortOptimalTaps( std::vector<s
     }
     return cPhaseTapsFEs;
 }
+
 void CicFEAlignment::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 {
-    for (auto cBoard : this->fBoardVector)
+
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                // read bend LUT
-                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), pBendCode);
-                if( cIterator != cBendLUT.end() )
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for(auto cChip : *cHybrid)
                 {
-                    int cPosition = std::distance( cBendLUT.begin(), cIterator);
-                    double cBend_strips = -7. + 0.5*cPosition; 
-                    uint8_t cOffsetCode = static_cast<uint8_t>(std::abs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    // set offsets
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (cOffsetCode << 4) | (cOffsetCode << 0) );
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (cOffsetCode << 4) | (cOffsetCode << 0) );
-                    LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( pBendCode ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips [offset code " << std::bitset<4>(cOffsetCode) << "]." <<  RESET;
+                    // read bend LUT
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                    auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), pBendCode);
+                    if( cIterator != cBendLUT.end() )
+                    {
+                        int cPosition = std::distance( cBendLUT.begin(), cIterator);
+                        double cBend_strips = -7. + 0.5*cPosition; 
+                        uint8_t cOffsetCode = static_cast<uint8_t>(std::abs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        // set offsets
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (cOffsetCode << 4) | (cOffsetCode << 0) );
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (cOffsetCode << 4) | (cOffsetCode << 0) );
+                        LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( pBendCode ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips [offset code " << std::bitset<4>(cOffsetCode) << "]." <<  RESET;
+                    }
                 }
             }
         }
@@ -238,26 +260,31 @@ void CicFEAlignment::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 bool CicFEAlignment::SetBx0Delay(uint8_t pDelay, uint8_t pStubPackageDelay)
 {
     // configure Bx0 alignment patterns in CIC  
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for(auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            if( static_cast<OuterTrackerModule*>(cFe)->fCic != NULL ) 
+            for(auto cHybrid : *cOpticalGroup)
             {
-                bool cConfigured = fCicInterface->ManualBx0Alignment(  static_cast<OuterTrackerModule*>(cFe)->fCic , pDelay);
-                if(!cConfigured)
+                OuterTrackerModule* theHybrid = static_cast<OuterTrackerModule*>(cHybrid);
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (theHybrid->getLinkId());
+                if( theHybrid->fCic != NULL ) 
                 {
-                    LOG (INFO) << BOLDRED << "Failed to manually set Bx0 delay in CIC..." << RESET;
-                    exit(0);
+                    bool cConfigured = fCicInterface->ManualBx0Alignment(  theHybrid->fCic , pDelay);
+                    if(!cConfigured)
+                    {
+                        LOG (INFO) << BOLDRED << "Failed to manually set Bx0 delay in CIC..." << RESET;
+                        exit(0);
+                    }
                 }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
     }
     return true;
 }
+
 bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay, uint16_t pWait_ms, int cNtrials )
 { 
 
@@ -282,68 +309,81 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
     SetStubWindowOffsets( cBendCode , cBend);
     bool cSuccess = true; 
     // inject stubs in all FE chips 
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
         // read back register map before you've done anything 
-        auto cBoardRegisterMap = cBoard->getBeBoardRegMap();
-        for (auto& cFe : cBoard->fModuleVector)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        auto cBoardRegisterMap = theBoard->getBeBoardRegMap();
+        for(auto cOpticalGroup : *cBoard)
         {
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
-            {
-                //first pattern - stubs lines 0,1,3
-                static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , cSeeds , cBends, false );
-                // switch off HitOr
-                fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                // set pT cut to maximum 
-                fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip), "PtCut", 14); 
-            }
-            // configure Bx0 alignment patterns in CIC 
-            if( static_cast<OuterTrackerModule*>(cFe)->fCic != NULL ) 
+            for(auto cHybrid : *cOpticalGroup)
             {
-                uint8_t cSLVS3 =(cBendCode << 4) | cBendCode;
-                uint8_t cSLVS4 = (1 << 7) | (0 << 5) | cBendCode;
-                std::vector<uint8_t> cPatterns{ cSeeds[0], cSeeds[1], cSeeds[2], cSLVS3, cSLVS4 };
-                bool cConfigured = fCicInterface->ConfigureBx0Alignment(  static_cast<OuterTrackerModule*>(cFe)->fCic , cPatterns , pFe , pLine );
-                if( !cConfigured)
+                OuterTrackerModule* theOuterTrackerHybrid = static_cast<OuterTrackerModule*>(cHybrid);
+
+                //configure CBCs 
+                for (auto cChip : *cHybrid)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    CbcInterface* theCbcInterface = static_cast<CbcInterface*>(fReadoutChipInterface);
+                    //first pattern - stubs lines 0,1,3
+                    theCbcInterface->injectStubs( theChip , cSeeds , cBends, false );
+                    // switch off HitOr
+                    fReadoutChipInterface->WriteChipReg ( theChip "HitOr", 0);
+                    //enable stub logic
+                    theCbcInterface->selectLogicMode( theChip "Sampled", true, true); 
+                    // set pT cut to maximum 
+                    fReadoutChipInterface->WriteChipReg( theChip "PtCut", 14); 
+                }
+                // configure Bx0 alignment patterns in CIC 
+                if( theOuterTrackerHybrid->fCic != NULL ) 
                 {
-                    LOG (ERROR) << BOLDRED << "Could not set Bx0 alignment pattern on CIC ... " << RESET;
+                    uint8_t cSLVS3 =(cBendCode << 4) | cBendCode;
+                    uint8_t cSLVS4 = (1 << 7) | (0 << 5) | cBendCode;
+                    std::vector<uint8_t> cPatterns{ cSeeds[0], cSeeds[1], cSeeds[2], cSLVS3, cSLVS4 };
+                    bool cConfigured = fCicInterface->ConfigureBx0Alignment(  theOuterTrackerHybrid->fCic , cPatterns , pFe , pLine );
+                    if( !cConfigured)
+                    {
+                        LOG (ERROR) << BOLDRED << "Could not set Bx0 alignment pattern on CIC ... " << RESET;
+                    }
                 }
             }
         }
 
         // make sure you're only sending one trigger at a time here
-        auto cMult = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
-        fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", 0);
+        auto cMult = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
+        fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", 0);
         
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(pDelay,200);
     
         // check status of lock on CIC 
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            if( static_cast<OuterTrackerModule*>(cFe)->fCic != NULL ) 
+            for(auto cHybrid : *cOpticalGroup)
             {
-                //start trigger 
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_ctrl.fast_command_block.control.start_trigger", 0x1);
-                std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );  
-                // stop trigger 
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_ctrl.fast_command_block.control.stop_trigger", 0x1);
-                std::pair<bool,uint8_t> cBx0Status = fCicInterface->CheckBx0Alignment(  static_cast<OuterTrackerModule*>(cFe)->fCic );
-                if( cBx0Status.first ) 
+                OuterTrackerModule* theOuterTrackerHybrid = static_cast<OuterTrackerModule*>(cHybrid);
+
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (theOuterTrackerHybrid->getLinkId());
+                if( theOuterTrackerHybrid->fCic != NULL ) 
                 {
-                    LOG (INFO) << BOLDBLUE << "Automated BX0 alignment on CIC" << +cFe->getFeId() << " : " << BOLDGREEN << " SUCCEEDED ...." << BOLDBLUE << "\t.... Bx0 delay found to be " << +cBx0Status.second << " clocks." <<  RESET;
-                    cSuccess  = fCicInterface->ManualBx0Alignment(  static_cast<OuterTrackerModule*>(cFe)->fCic , cBx0Status.second - pDelay);
+                    //start trigger 
+                    fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_ctrl.fast_command_block.control.start_trigger", 0x1);
+                    std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );  
+                    // stop trigger 
+                    fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_ctrl.fast_command_block.control.stop_trigger", 0x1);
+                    std::pair<bool,uint8_t> cBx0Status = fCicInterface->CheckBx0Alignment(  theOuterTrackerHybrid->fCic );
+                    if( cBx0Status.first ) 
+                    {
+                        LOG (INFO) << BOLDBLUE << "Automated BX0 alignment on CIC" << +cHybrid->getId() << " : " << BOLDGREEN << " SUCCEEDED ...." << BOLDBLUE << "\t.... Bx0 delay found to be " << +cBx0Status.second << " clocks." <<  RESET;
+                        cSuccess  = fCicInterface->ManualBx0Alignment(  theOuterTrackerHybrid->fCic , cBx0Status.second - pDelay);
+                    }
+                    else 
+                        LOG (INFO) << BOLDBLUE << "Automated BX0 alignment on CIC" << +cHybrid->getId() << " : " << BOLDRED << " FAILED!." << RESET;
                 }
-                else 
-                    LOG (INFO) << BOLDBLUE << "Automated BX0 alignment on CIC" << +cFe->getFeId() << " : " << BOLDRED << " FAILED!." << RESET;
             }
         }
 
         // reset original trigger configuration 
-        fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cMult);
+        fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cMult);
         // re-load configuration of fast command block from register map loaded from xml file 
         LOG (INFO) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
         std::vector< std::pair<std::string, uint32_t> > cVecReg;
@@ -356,8 +396,8 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
                 cVecReg.push_back ( {it.first, it.second} );
             }
         }
-        fBeBoardInterface->WriteBoardMultReg ( cBoard, cVecReg);
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->WriteBoardMultReg ( theBoard, cVecReg);
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
     if( !cSuccess ) 
     {
@@ -367,20 +407,27 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
     
     //unmask all channels and reset offsets 
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for(auto cBoard : *fDetectorContainer)
+    {
+        // read back register map before you've done anything 
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for (auto cChip : *cHybrid)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
     // disable TP 
     this->enableTestPulse(false);
@@ -388,55 +435,63 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
     
     // re-configure thresholds + hit/stub detect logic to original values 
     // also re-load configuration of fast command block from register map loaded from xml file 
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
         auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
         auto& cPtCutThisBoard = fPtCuts.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
+                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                //configure CBCs 
+                for (auto cChip : *cHybrid)
+                {
+                    LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    fReadoutChipInterface->WriteChipReg( theChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                }
             }
         }
         LOG (INFO) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
+        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(static_cast<BeBoard*>(cBoard));
     }
     return cSuccess;
 }
+
 bool CicFEAlignment::ManualPhaseAlignment(uint16_t pPhase)
 {
     bool cConfigured = true;
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-            if( cCic != NULL )
+            for (auto cHybrid : *cOpticalGroup)
             {
-                fCicInterface->SetAutomaticPhaseAlignment(cCic, false);
-                for (auto& cChip : cFe->fReadoutChipVector)
+                auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                if( cCic != NULL )
                 {
-                    for( int cLineId=0; cLineId < 6; cLineId++)
+                    fCicInterface->SetAutomaticPhaseAlignment(cCic, false);
+                    for (auto cChip : *cHybrid)
                     {
-                        cConfigured = cConfigured && fCicInterface->SetStaticPhaseAlignment(  cCic , cChip->getChipId() , cLineId , pPhase);
+                        for( int cLineId=0; cLineId < 6; cLineId++)
+                        {
+                            cConfigured = cConfigured && fCicInterface->SetStaticPhaseAlignment(  cCic , cChip->getId() , cLineId , pPhase);
+                        }
                     }
                 }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync (static_cast<BeBoard*>(cBoard));
     }
     return cConfigured;
 }
@@ -444,7 +499,7 @@ bool CicFEAlignment::PhaseAlignment(uint16_t pWait_ms)
 {
     bool cAligned=true;
     LOG (INFO) << BOLDBLUE << "Starting CIC automated phase alignment procedure .... " << RESET;
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
         // original threshold + logic values 
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
@@ -456,122 +511,132 @@ bool CicFEAlignment::PhaseAlignment(uint16_t pWait_ms)
         ChannelGroup<NCHANNELS,1> cChannelMask; cChannelMask.disableAllChannels();
         for( uint8_t cChannel=0; cChannel<NCHANNELS; cChannel+=10) cChannelMask.enableChannel( cChannel);//generate a hit in every Nth channel
         
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            // enable automatic phase aligner 
-            fCicInterface->SetAutomaticPhaseAlignment( static_cast<OuterTrackerModule*>(cFe)->fCic , true);
-            
-            // generate alignment pattern on all stub lines  
-            LOG (INFO) << BOLDBLUE << "Generating STUB patterns needed for phase alignment on FE" << +cFe->getFeId() << RESET;
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                // original mask
-                const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(cChip->getChipOriginalMask());
-                //enable stub logic 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                // switch on HitOr
-                fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 1);
-                // set PtCut to maximum 
-                fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "PtCut", 14);
+                // enable automatic phase aligner 
+                fCicInterface->SetAutomaticPhaseAlignment( static_cast<OuterTrackerModule*>(cHybrid)->fCic , true);
                 
-                // read bend LUT
-                uint8_t cBendCode_phAlign = 0xa;
-                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), cBendCode_phAlign);
-                if( cIterator != cBendLUT.end() )
+                // generate alignment pattern on all stub lines  
+                LOG (INFO) << BOLDBLUE << "Generating STUB patterns needed for phase alignment on FE" << +cHybrid->getId() << RESET;
+                for (auto cChip : *cHybrid)
                 {
-                    int cPosition = std::distance( cBendLUT.begin(), cIterator);
-                    double cBend_strips = -7. + 0.5*cPosition; 
-                    LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( cBendCode_phAlign ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips." << RESET;
+                    ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
+                    // original mask
+                    const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(cChip->getChipOriginalMask());
+                    //enable stub logic 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( theReadoutChip, "Sampled", true, true); 
+                    // switch on HitOr
+                    fReadoutChipInterface->WriteChipReg ( theReadoutChip, "HitOr", 1);
+                    // set PtCut to maximum 
+                    fReadoutChipInterface->WriteChipReg ( theReadoutChip, "PtCut", 14);
                     
-                    // first pattern - stubs lines 0, 1 , 3  
-                    std::vector<uint8_t> cSeeds_ph1{ 0x55 };
-                    std::vector<int>     cBends_ph1( 2, static_cast<int>(cBend_strips*2) ); 
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , cSeeds_ph1 , cBends_ph1,true);
-                    std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );
-           
-                    //econd pattern - 1, 2, 3 , 4 
-                    std::vector<uint8_t> cSeeds_ph3{ 42, 0x55 , 0xAA };
-                    std::vector<int>     cBends_ph3(3, static_cast<int>(cBend_strips*2) ); 
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , cSeeds_ph3 , cBends_ph3,true);
-                    std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );
+                    // read bend LUT
+                    uint8_t cBendCode_phAlign = 0xa;
+                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theReadoutChip );
+                    auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), cBendCode_phAlign);
+                    if( cIterator != cBendLUT.end() )
+                    {
+                        int cPosition = std::distance( cBendLUT.begin(), cIterator);
+                        double cBend_strips = -7. + 0.5*cPosition; 
+                        LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( cBendCode_phAlign ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips." << RESET;
+                        
+                        // first pattern - stubs lines 0, 1 , 3  
+                        std::vector<uint8_t> cSeeds_ph1{ 0x55 };
+                        std::vector<int>     cBends_ph1( 2, static_cast<int>(cBend_strips*2) ); 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theReadoutChip , cSeeds_ph1 , cBends_ph1,true);
+                        std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );
+            
+                        //econd pattern - 1, 2, 3 , 4 
+                        std::vector<uint8_t> cSeeds_ph3{ 42, 0x55 , 0xAA };
+                        std::vector<int>     cBends_ph3(3, static_cast<int>(cBend_strips*2) ); 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theReadoutChip , cSeeds_ph3 , cBends_ph3,true);
+                        std::this_thread::sleep_for (std::chrono::milliseconds (pWait_ms) );
+                    }
+                    fReadoutChipInterface-> maskChannelsGroup (theReadoutChip, cOriginalMask);
                 }
-                fReadoutChipInterface-> maskChannelsGroup (cChip, cOriginalMask);
-            }
-            LOG (INFO) << BOLDBLUE << "Generating HIT patterns needed for phase alignment on FE" << +cFe->getFeId() << RESET;
-            for (auto& cChip : cFe->fReadoutChipVector)
-            {
-                // original mask
-                const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(cChip->getChipOriginalMask());
-                //fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 1);
-                fReadoutChipInterface-> maskChannelsGroup (cChip, &cChannelMask);
-                //send triggers ...
-                for( auto cTrigger=0; cTrigger < 100 ; cTrigger++)
+                LOG (INFO) << BOLDBLUE << "Generating HIT patterns needed for phase alignment on FE" << +cHybrid->getId() << RESET;
+                for (auto& cChip : *cHybrid)
                 {
-                    static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Trigger(0);
-                    std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                    ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
+                    // original mask
+                    const ChannelGroup<NCHANNELS>* cOriginalMask  = static_cast<const ChannelGroup<NCHANNELS>*>(theReadoutChip->getChipOriginalMask());
+                    //fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(theReadoutChip), "EnableSLVS", 1);
+                    fReadoutChipInterface-> maskChannelsGroup (theReadoutChip, &cChannelMask);
+                    //send triggers ...
+                    for( auto cTrigger=0; cTrigger < 100 ; cTrigger++)
+                    {
+                        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Trigger(0);
+                        std::this_thread::sleep_for (std::chrono::microseconds (10) );
+                    }
+                    // make sure you've returned channels to their original masked value 
+                    fReadoutChipInterface->maskChannelsGroup( theReadoutChip ,cOriginalMask );
+                    //fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(theReadoutChip), "EnableSLVS", 0);
                 }
-                // make sure you've returned channels to their original masked value 
-                fReadoutChipInterface->maskChannelsGroup( cChip ,cOriginalMask );
-                //fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 0);
-            }
-            bool cLocked=fCicInterface->CheckPhaseAlignerLock( static_cast<OuterTrackerModule*>(cFe)->fCic);
-            // 4 channels per phyPort ... 12 phyPorts per CIC 
-            std::vector<std::vector<uint8_t>> cPhaseTaps( 4, std::vector<uint8_t> (12, 0));
-            // 8 FEs per CIC .... 6 SLVS lines per FE
-            std::vector<std::vector<uint8_t>> cPhaseTapsFEs( 8, std::vector<uint8_t> (6, 0)) ; 
-            // read back phase aligner values 
-            if( cLocked ) 
-            {
-                auto& cPhaseAlignmentThisHybrid = cPhaseAlignmentThisBoard->at(cFe->getIndex());
-                LOG (INFO) << BOLDBLUE << "Phase aligner on CIC " << BOLDGREEN << " LOCKED " << BOLDBLUE << " ... storing values and swithcing to static phase " << RESET;
-                cPhaseTaps = fCicInterface->GetOptimalTaps( static_cast<OuterTrackerModule*>(cFe)->fCic);
-                cPhaseTapsFEs = this->SortOptimalTaps( cPhaseTaps ); 
-                for (auto& cChip : cFe->fReadoutChipVector)
+                bool cLocked=fCicInterface->CheckPhaseAlignerLock( static_cast<OuterTrackerModule*>(cHybrid)->fCic);
+                // 4 channels per phyPort ... 12 phyPorts per CIC 
+                std::vector<std::vector<uint8_t>> cPhaseTaps( 4, std::vector<uint8_t> (12, 0));
+                // 8 FEs per CIC .... 6 SLVS lines per FE
+                std::vector<std::vector<uint8_t>> cPhaseTapsFEs( 8, std::vector<uint8_t> (6, 0)) ; 
+                // read back phase aligner values 
+                if( cLocked ) 
                 {
-                    std::string cOutput;
-                    for(uint8_t cInput = 0 ; cInput < 6 ; cInput+=1)
+                    auto& cPhaseAlignmentThisHybrid = cPhaseAlignmentThisBoard->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex());
+                    LOG (INFO) << BOLDBLUE << "Phase aligner on CIC " << BOLDGREEN << " LOCKED " << BOLDBLUE << " ... storing values and swithcing to static phase " << RESET;
+                    cPhaseTaps = fCicInterface->GetOptimalTaps( static_cast<OuterTrackerModule*>(cHybrid)->fCic);
+                    cPhaseTapsFEs = this->SortOptimalTaps( cPhaseTaps ); 
+                    for (auto& cChip : *cHybrid)
                     {
-                        char cBuffer[80]; sprintf(cBuffer,"%.2d ", cPhaseTapsFEs[cChip->getChipId()][cInput]);
-                        cOutput += cBuffer;
-                        cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>()[cInput] = cPhaseTapsFEs[cChip->getChipId()][cInput];
+                        ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
+                        std::string cOutput;
+                        for(uint8_t cInput = 0 ; cInput < 6 ; cInput+=1)
+                        {
+                            char cBuffer[80]; sprintf(cBuffer,"%.2d ", cPhaseTapsFEs[cChip->getId()][cInput]);
+                            cOutput += cBuffer;
+                            cPhaseAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>()[cInput] = cPhaseTapsFEs[cChip->getId()][cInput];
+                        }
+                        LOG (INFO) << BOLDBLUE << "Optimal tap found on FE" << +cChip->getId() << " : " << cOutput << RESET;
                     }
-                    LOG (INFO) << BOLDBLUE << "Optimal tap found on FE" << +cChip->getChipId() << " : " << cOutput << RESET;
+                    // put phase aligner in static mode
+                    fCicInterface->SetStaticPhaseAlignment( static_cast<OuterTrackerModule*>(cHybrid)->fCic, cPhaseTaps); 
+                }
+                else
+                {
+                    LOG (INFO) << BOLDBLUE << "Phase aligner on CIC " << BOLDRED << " FAILED to lock " << BOLDBLUE << " ... stopping procedure." << RESET;
+                    exit(1);
                 }
-                // put phase aligner in static mode
-                fCicInterface->SetStaticPhaseAlignment( static_cast<OuterTrackerModule*>(cFe)->fCic, cPhaseTaps); 
-            }
-            else
-            {
-                LOG (INFO) << BOLDBLUE << "Phase aligner on CIC " << BOLDRED << " FAILED to lock " << BOLDBLUE << " ... stopping procedure." << RESET;
-                exit(1);
             }
         }
       
         // check if reset is needed and return everything back to original state 
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
-            
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                fReadoutChipInterface->WriteChipReg( cChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                // enable all output from CBCs 
-                fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 1);
-            }
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cHybrid->getLinkId());
+                
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cHybrid->getIndex());
+                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cHybrid->getIndex());
+                
+                for (auto cChip : *cHybrid)
+                {
+                    ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
+                    LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                    fReadoutChipInterface->WriteChipReg( theReadoutChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theReadoutChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theReadoutChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    fReadoutChipInterface->WriteChipReg( theReadoutChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    // enable all output from CBCs 
+                    fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "EnableSLVS", 1);
+                }
 
-            LOG (INFO) << BOLDBLUE << "Checking Reset/Resync for CIC on hybrid " << +cFe->getFeId() << RESET;
-            // check if a resync is needed
-            fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cFe)->fCic); 
+                LOG (INFO) << BOLDBLUE << "Checking Reset/Resync for CIC on hybrid " << +cHybrid->getId() << RESET;
+                // check if a resync is needed
+                fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cHybrid)->fCic); 
+            }
         }
     }
     return cAligned;
@@ -609,8 +674,9 @@ bool CicFEAlignment::WordAlignment(uint16_t pWait_ms)
     // phase alignment step - first 85 [] , 170 [] 
     bool cAligned=true;
     std::vector<uint8_t> cAlignmentPatterns{ 0x7A, 0xBC, 0xD4, 0x31, 0x81}; 
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
         // original threshold + logic values 
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
@@ -618,60 +684,63 @@ bool CicFEAlignment::WordAlignment(uint16_t pWait_ms)
         auto& cPtCutThisBoard = fPtCuts.at(cBoard->getIndex());
         auto& cWordAlignmentThisBoard = fWordAlignmentValues.at(cBoard->getIndex());
         
-        
-        for (auto& cFe : cBoard->fModuleVector)
+        for (auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
-            auto& cWordAlignmentThisHybrid = cWordAlignmentThisBoard->at(cFe->getIndex());
-
-            if( static_cast<OuterTrackerModule*>(cFe)->fCic != NULL ) 
+            for (auto cHybrid : *cOpticalGroup)
             {
-                // now inject stubs that can generate word alignment pattern 
-                for (auto& cChip : cFe->fReadoutChipVector)
-                {
-                  this->WordAlignmentPattern(cChip, cAlignmentPatterns);
-                }
-                // now send a fast reset 
-                fBeBoardInterface->ChipReSync ( cBoard );
-                
-                // run automated word alignment 
-                cAligned = cAligned && fCicInterface->AutomatedWordAlignment( static_cast<OuterTrackerModule*>(cFe)->fCic ,cAlignmentPatterns, pWait_ms);
-                std::vector<std::vector<uint8_t>> cWordAlignmentValues = fCicInterface->ReadWordAlignmentValues( static_cast<OuterTrackerModule*>(cFe)->fCic);
-                if( cAligned )
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cHybrid->getIndex());
+                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cHybrid->getIndex());
+                auto& cWordAlignmentThisHybrid = cWordAlignmentThisBoard->at(cHybrid->getIndex());
+
+                if( static_cast<OuterTrackerModule*>(cHybrid)->fCic != NULL ) 
                 {
-                    LOG (INFO) << BOLDBLUE << "Automated word alignment procedure " << BOLDGREEN << " SUCCEEDED!" << RESET;
-                    std::vector<std::vector<uint8_t>> cValues = SortWordAlignmentValues( cWordAlignmentValues );
-                    for (auto& cChip : cFe->fReadoutChipVector)
+                    // now inject stubs that can generate word alignment pattern 
+                    for (auto cChip : *cHybrid)
                     {
-                        std::string cOutput;
-                        for(uint8_t cLine = 0 ; cLine < 5 ; cLine+=1)
+                        this->WordAlignmentPattern(static_cast<ReadoutChip*>(cChip), cAlignmentPatterns);
+                    }
+                    // now send a fast reset 
+                    fBeBoardInterface->ChipReSync ( theBoard );
+                    
+                    // run automated word alignment 
+                    cAligned = cAligned && fCicInterface->AutomatedWordAlignment( static_cast<OuterTrackerModule*>(cHybrid)->fCic ,cAlignmentPatterns, pWait_ms);
+                    std::vector<std::vector<uint8_t>> cWordAlignmentValues = fCicInterface->ReadWordAlignmentValues( static_cast<OuterTrackerModule*>(cHybrid)->fCic);
+                    if( cAligned )
+                    {
+                        LOG (INFO) << BOLDBLUE << "Automated word alignment procedure " << BOLDGREEN << " SUCCEEDED!" << RESET;
+                        std::vector<std::vector<uint8_t>> cValues = SortWordAlignmentValues( cWordAlignmentValues );
+                        for (auto cChip : *cHybrid)
                         {
-                            char cBuffer[80]; sprintf(cBuffer,"%.2d ", cValues[cChip->getChipId()][cLine]);
-                            cOutput += cBuffer;
-                            cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>()[cLine] = cValues[cChip->getChipId()][cLine];
+                            std::string cOutput;
+                            for(uint8_t cLine = 0 ; cLine < 5 ; cLine+=1)
+                            {
+                                char cBuffer[80]; sprintf(cBuffer,"%.2d ", cValues[cChip->getId()][cLine]);
+                                cOutput += cBuffer;
+                                cWordAlignmentThisHybrid->at(cChip->getIndex())->getSummary<std::vector<uint8_t>>()[cLine] = cValues[cChip->getId()][cLine];
+                            }
+                            LOG (INFO) << BOLDBLUE << "Word alignment values for FE" << +cChip->getId() << " : " << cOutput << RESET;
                         }
-                        LOG (INFO) << BOLDBLUE << "Word alignment values for FE" << +cChip->getChipId() << " : " << cOutput << RESET;
                     }
-                }
-                else
-                    LOG (INFO) << BOLDBLUE << "Automated word alignment procedure " << BOLDRED << " FAILED!" << RESET;
-                // re-configure thresholds + hit/stub detect logic to original values 
-                LOG (INFO) << BOLDBLUE << "Setting thresholds and logic detect modes back to their original values [Hybrid " << +cFe->getFeId() << " ]." << RESET;
-                for (auto& cChip : cFe->fReadoutChipVector)
-                {
-                    fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                    fReadoutChipInterface->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                    fReadoutChipInterface->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                    fReadoutChipInterface->WriteChipReg( cChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false); 
+                    else
+                        LOG (INFO) << BOLDBLUE << "Automated word alignment procedure " << BOLDRED << " FAILED!" << RESET;
+                    // re-configure thresholds + hit/stub detect logic to original values 
+                    LOG (INFO) << BOLDBLUE << "Setting thresholds and logic detect modes back to their original values [Hybrid " << +cHybrid->getId() << " ]." << RESET;
+                    for (auto cChip : *cHybrid)
+                    {
+                        ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
+                        fReadoutChipInterface->WriteChipReg( theReadoutChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                        fReadoutChipInterface->WriteChipReg( theReadoutChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                        fReadoutChipInterface->WriteChipReg( theReadoutChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                        fReadoutChipInterface->WriteChipReg( theReadoutChip, "PtCut" , cPtCutThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theReadoutChip, false); 
+                    }
                 }
             }
         }
         // now send a fast reset 
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
     return cAligned;
 }
diff --git a/tools/DataChecker.cc b/tools/DataChecker.cc
index e3217b6ef..44d74303d 100644
--- a/tools/DataChecker.cc
+++ b/tools/DataChecker.cc
@@ -43,225 +43,191 @@ void DataChecker::Initialise ()
     #endif
     
     // retreive original settings for all chips 
-    ContainerFactory::copyAndInitStructure<ChipRegMap>(*fDetectorContainer, fRegMapContainer);
-    for (auto cBoard : this->fBoardVector)
+    ContainerFactory::copyAndInitChip<ChipRegMap>(*fDetectorContainer, fRegMapContainer);
+    for(auto cBoard : *fDetectorContainer)
     {
-        auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cRegMapThisHybrid = cRegMapThisBoard->at(cFe->getIndex());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>() = cChip->getRegMap();
+                for(auto cChip : *cHybrid)
+                {
+                    fRegMapContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<ChipRegMap>() = static_cast<ReadoutChip*>(cChip)->getRegMap();
+                }
             }
         }
     }
 
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                // matched hits 
-                TString cName = Form ( "h_Hits_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                TObject* cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                TH2D* cHist2D = new TH2D ( cName, Form("Number of hits - CBC%d; Trigger Number; Pipeline Address",(int)cChip->getChipId()) , 40  , 0 -0.5 , 40 -0.5 , 520 , 0-0.5 , 520-0.5 );
-                bookHistogram ( cChip , "Hits_perFe", cHist2D );
+                for(auto cChip : *cHybrid)
+                {
+                    // matched hits 
+                    TString cName = Form ( "h_Hits_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    TObject* cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TH2D* cHist2D = new TH2D ( cName, Form("Number of hits - CBC%d; Trigger Number; Pipeline Address",(int)cChip->getId()) , 40  , 0 -0.5 , 40 -0.5 , 520 , 0-0.5 , 520-0.5 );
+                    bookHistogram ( cChip , "Hits_perFe", cHist2D );
+
+                    cName = Form ( "h_MatchedHits_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cHist2D = new TH2D ( cName, Form("Number of matched hits - CBC%d; Trigger Number; Pipeline Address",(int)cChip->getId()) ,40  , 0 -0.5 , 40 -0.5 , 520 , 0-0.5 , 520-0.5 );
+                    bookHistogram ( cChip , "MatchedHits_perFe", cHist2D );
+
+                    cName = Form ( "h_EyeL1_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TProfile2D* cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Phase Tap; Trigger Number",(int)cChip->getId()) ,  20 , 0-0.5 , 20-0.5 , 40 , 0-0.5 , 40-0.5);
+                    bookHistogram ( cChip , "MatchedHits_eye", cProfile2D );
+
+                    cName = Form ( "h_TestPulse_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Time [ns]; Test Pulse Amplitude [DAC units]",(int)cChip->getId()) ,  500 , -250 , 250 , cSteps , cInitialTh , cFinalTh);
+                    bookHistogram ( cChip , "MatchedHits_TestPulse", cProfile2D );
+
+                    cName = Form ( "h_StubLatency_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cProfile2D = new TProfile2D ( cName, Form("Number of matched stubs - CBC%d; Latency [40 MHz clock cycles]; Test Pulse Amplitude [DAC units]",(int)cChip->getId()) ,  512, 0 , 512 , cSteps , cInitialTh , cFinalTh);
+                    bookHistogram ( cChip , "StubLatency", cProfile2D );
+                    
 
-                cName = Form ( "h_MatchedHits_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                cHist2D = new TH2D ( cName, Form("Number of matched hits - CBC%d; Trigger Number; Pipeline Address",(int)cChip->getChipId()) ,40  , 0 -0.5 , 40 -0.5 , 520 , 0-0.5 , 520-0.5 );
-                bookHistogram ( cChip , "MatchedHits_perFe", cHist2D );
+                    cName = Form ( "h_HitLatency_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Latency [40 MHz clock cycles]; Test Pulse Amplitude [DAC units]",(int)cChip->getId()) ,  512 , 0 , 512 , cSteps , cInitialTh , cFinalTh);
+                    bookHistogram ( cChip , "HitLatency", cProfile2D );
+                    
 
-                cName = Form ( "h_EyeL1_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                TProfile2D* cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Phase Tap; Trigger Number",(int)cChip->getChipId()) ,  20 , 0-0.5 , 20-0.5 , 40 , 0-0.5 , 40-0.5);
-                bookHistogram ( cChip , "MatchedHits_eye", cProfile2D );
+                    cName = Form ( "h_NoiseHits_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TProfile* cHist = new TProfile ( cName, Form("Number of noise hits - CBC%d; Channelr",(int)cChip->getId()) , NCHANNELS, 0-0.5 , NCHANNELS-0.5);
+                    bookHistogram ( cChip , "NoiseHits", cHist );
 
-                cName = Form ( "h_TestPulse_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Time [ns]; Test Pulse Amplitude [DAC units]",(int)cChip->getChipId()) ,  500 , -250 , 250 , cSteps , cInitialTh , cFinalTh);
-                bookHistogram ( cChip , "MatchedHits_TestPulse", cProfile2D );
+                    cName = Form ( "h_MissedHits_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TH1D* cHist1D = new TH1D ( cName, Form("Events between missed hits - CBC%d; Channelr",(int)cChip->getId()) , 1000, 0-0.5 , 1000-0.5);
+                    bookHistogram ( cChip , "FlaggedEvents", cHist1D );
 
-                cName = Form ( "h_StubLatency_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                cProfile2D = new TProfile2D ( cName, Form("Number of matched stubs - CBC%d; Latency [40 MHz clock cycles]; Test Pulse Amplitude [DAC units]",(int)cChip->getChipId()) ,  512, 0 , 512 , cSteps , cInitialTh , cFinalTh);
-                bookHistogram ( cChip , "StubLatency", cProfile2D );
-                
+                    cName = Form ( "h_ptCut_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cHist = new TProfile ( cName, Form("Fraction of stubs matched to hits - CBC%d; Window Offset [half-strips]",(int)cChip->getId()) , 14, -7-0.5 , 7-0.5);
+                    bookHistogram ( cChip , "PtCut", cHist );
 
-                cName = Form ( "h_HitLatency_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                cProfile2D = new TProfile2D ( cName, Form("Number of matched hits - CBC%d; Latency [40 MHz clock cycles]; Test Pulse Amplitude [DAC units]",(int)cChip->getChipId()) ,  512 , 0 , 512 , cSteps , cInitialTh , cFinalTh);
-                bookHistogram ( cChip , "HitLatency", cProfile2D );
-                
+                    
 
-                cName = Form ( "h_NoiseHits_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
-                cObj = gROOT->FindObject ( cName );
+                }
+
+                // matched stubs 
+                TString cName = Form ( "h_Stubs_Cic%d", cHybrid->getId() );
+                TObject* cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                TProfile* cHist = new TProfile ( cName, Form("Number of noise hits - CBC%d; Channelr",(int)cChip->getChipId()) , NCHANNELS, 0-0.5 , NCHANNELS-0.5);
-                bookHistogram ( cChip , "NoiseHits", cHist );
+                TH2D* cHist2D = new TH2D ( cName, Form("Number of stubs - CIC%d; Trigger Number; Bunch Crossing Id",(int)cHybrid->getId()) , 40  , 0 -0.5 , 40 -0.5 , 4000 , 0-0.5 , 4000-0.5 );
+                bookHistogram ( cHybrid , "Stubs", cHist2D );
 
-                cName = Form ( "h_MissedHits_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                cName = Form ( "h_MatchedStubs_Cic%d", cHybrid->getId() );
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                TH1D* cHist1D = new TH1D ( cName, Form("Events between missed hits - CBC%d; Channelr",(int)cChip->getChipId()) , 1000, 0-0.5 , 1000-0.5);
-                bookHistogram ( cChip , "FlaggedEvents", cHist1D );
+                cHist2D = new TH2D ( cName, Form("Number of matched stubs - CIC%d; Trigger Number; Bunch Crossing Id",(int)cHybrid->getId()) , 40  , 0 -0.5 , 40 -0.5 , 4000 , 0-0.5 , 4000-0.5 );
+                bookHistogram ( cHybrid , "MatchedStubs", cHist2D );
 
-                cName = Form ( "h_ptCut_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                cName = Form ( "h_MissedHits_Cic%d", cHybrid->getId() );
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                cHist = new TProfile ( cName, Form("Fraction of stubs matched to hits - CBC%d; Window Offset [half-strips]",(int)cChip->getChipId()) , 14, -7-0.5 , 7-0.5);
-                bookHistogram ( cChip , "PtCut", cHist );
+                cHist2D = new TH2D ( cName, Form("Number of missed hits - CIC%d; Iteration number; CBC Id",(int)cHybrid->getId()) , 100  , 0 -0.5 , 100 -0.5 , 8 , 0-0.5 , 8-0.5 );
+                bookHistogram ( cHybrid , "MissedHits", cHist2D );
 
+                // TProfile* cProfile = new TProfile ( cName, Form("Number of matched stubs - CIC%d; CBC; Fraction of matched stubs",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                // bookHistogram ( cHybrid , "MatchedStubs", cProfile );
                 
-
+                // matched hits 
+                // cName = Form ( "h_MatchedHits");
+                // cObj = gROOT->FindObject ( cName );
+                // if ( cObj ) delete cObj;
+                // cProfile = new TProfile ( cName, Form("Number of matched hits - CIC%d; CBC; Fraction of matched hits",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                // bookHistogram ( cHybrid , "MatchedHits", cProfile );
+
+                // cName = Form ( "h_L1Status_Fe%d", cHybrid->getId() );
+                // cObj = gROOT->FindObject ( cName );
+                // if ( cObj ) delete cObj;
+                // TH2D* cHist2D = new TH2D ( cName, Form("Error Flag CIC%d; Event Id; Chip Id; Error Bit",(int)cHybrid->getId()) , 1000, 0 , 1000 , 9, 0-0.5 , 9-0.5 );
+                // bookHistogram ( cHybrid, "L1Status", cHist2D ); 
             }
-
-            // matched stubs 
-            TString cName = Form ( "h_Stubs_Cic%d", cFe->getFeId() );
-            TObject* cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TH2D* cHist2D = new TH2D ( cName, Form("Number of stubs - CIC%d; Trigger Number; Bunch Crossing Id",(int)cFe->getFeId()) , 40  , 0 -0.5 , 40 -0.5 , 4000 , 0-0.5 , 4000-0.5 );
-            bookHistogram ( cFe , "Stubs", cHist2D );
-
-            cName = Form ( "h_MatchedStubs_Cic%d", cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("Number of matched stubs - CIC%d; Trigger Number; Bunch Crossing Id",(int)cFe->getFeId()) , 40  , 0 -0.5 , 40 -0.5 , 4000 , 0-0.5 , 4000-0.5 );
-            bookHistogram ( cFe , "MatchedStubs", cHist2D );
-
-            cName = Form ( "h_MissedHits_Cic%d", cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("Number of missed hits - CIC%d; Iteration number; CBC Id",(int)cFe->getFeId()) , 100  , 0 -0.5 , 100 -0.5 , 8 , 0-0.5 , 8-0.5 );
-            bookHistogram ( cFe , "MissedHits", cHist2D );
-
-            // TProfile* cProfile = new TProfile ( cName, Form("Number of matched stubs - CIC%d; CBC; Fraction of matched stubs",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            // bookHistogram ( cFe , "MatchedStubs", cProfile );
-            
-            // matched hits 
-            // cName = Form ( "h_MatchedHits");
-            // cObj = gROOT->FindObject ( cName );
-            // if ( cObj ) delete cObj;
-            // cProfile = new TProfile ( cName, Form("Number of matched hits - CIC%d; CBC; Fraction of matched hits",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            // bookHistogram ( cFe , "MatchedHits", cProfile );
-
-            // cName = Form ( "h_L1Status_Fe%d", cFe->getFeId() );
-            // cObj = gROOT->FindObject ( cName );
-            // if ( cObj ) delete cObj;
-            // TH2D* cHist2D = new TH2D ( cName, Form("Error Flag CIC%d; Event Id; Chip Id; Error Bit",(int)cFe->getFeId()) , 1000, 0 , 1000 , 9, 0-0.5 , 9-0.5 );
-            // bookHistogram ( cFe, "L1Status", cHist2D ); 
         }
     }
 
     // read original thresholds from chips ... 
     fDetectorDataContainer = &fThresholds;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fThresholds);  
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fThresholds);  
     // read original logic configuration from chips .. [Pipe&StubInpSel&Ptwidth , HIP&TestMode]
     fDetectorDataContainer = &fLogic;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fLogic);  
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fLogic);  
     fDetectorDataContainer = &fHIPs;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fHIPs);  
-    for (auto cBoard : this->fBoardVector)
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fHIPs);
+    ContainerFactory::copyAndInitChip<int>(*fDetectorContainer, fHitCheckContainer);
+    ContainerFactory::copyAndInitChip<int>(*fDetectorContainer, fStubCheckContainer);
+    for(auto cBoard : *fDetectorContainer)
     {
-        auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
-        auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
-        auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for(auto cHybrid : *cOpticalGroup)
             {
-                cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "VCth" );
-                cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "Pipe&StubInpSel&Ptwidth" );
-                cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "HIP&TestMode" );
-            }
-        }
-    }
-
-    // for stub + hit data check 
-    ContainerFactory::copyAndInitStructure<int>(*fDetectorContainer, fHitCheckContainer);
-    ContainerFactory::copyAndInitStructure<int>(*fDetectorContainer, fStubCheckContainer);
-    for (auto cBoard : this->fBoardVector)
-    {
-        auto& cHitCheck = fHitCheckContainer.at(cBoard->getIndex());
-        auto& cStubCheck = fStubCheckContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
-        {
-            auto& cHitCheckThisHybrid = cHitCheck->at(cFe->getIndex());
-            auto& cStubCheckThisHybrid = cStubCheck->at(cFe->getIndex());
-            for (auto& cChip : cFe->fReadoutChipVector)
-            {
-                cHitCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
-                cStubCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
+                for(auto cChip : *cHybrid)
+                {
+                    fThresholds        .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "VCth" );
+                    fLogic             .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "Pipe&StubInpSel&Ptwidth" );
+                    fHIPs              .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "HIP&TestMode" );
+                }
             }
         }
     }
 
-
-
+    zeroContainers();
 }
 
 void DataChecker::zeroContainers()
 {
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-        auto& cThisHitCheckContainer = fHitCheckContainer.at(cBoard->getIndex());
-        auto& cThisStubCheckContainer = fStubCheckContainer.at(cBoard->getIndex());
-        // zero container 
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-            auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-            
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for(auto cHybrid : *cOpticalGroup)
             {
-                auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-                auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
-
-                cReadoutChipHitCheck->getSummary<int>() = 0;
-                cReadoutChipStubCheck->getSummary<int>() = 0 ;
+                for(auto cChip : *cHybrid)
+                {
+                    fHitCheckContainer .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = 0;
+                    fStubCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = 0;
+                }
             }
         }
     }
 }
 void DataChecker::print(std::vector<uint8_t> pChipIds )
 {
-    for (auto cBoard : this->fBoardVector)
+    for(auto cBoard : fHitCheckContainer)
     {
-        LOG (DEBUG) << BOLDBLUE << "\t..For BeBoard" << +cBoard->getIndex() << RESET;
-        auto& cThisHitCheckContainer = fHitCheckContainer.at(cBoard->getIndex());
-        auto& cThisStubCheckContainer = fStubCheckContainer.at(cBoard->getIndex());
-
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-            auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-            
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for(auto cHybrid : *cOpticalGroup)
             {
-                auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-                auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
-
-                auto cChipId = cChip->getChipId();
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                for(auto cChip : *cHybrid)
+                {
+                    auto cChipId = cChip->getId();
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
                     continue;
-
-                auto& cHitCheck = cReadoutChipHitCheck->getSummary<int>();
-                auto& cStubCheck = cReadoutChipStubCheck->getSummary<int>();
-                LOG (INFO) << BOLDBLUE << "\t\t...Found " << +cHitCheck << " matched hits and " << +cStubCheck << " matched stubs in readout chip" << +cChipId << RESET;
+                    auto cHitCheck  = cChip->getSummary<uint16_t>();
+                    auto cStubCheck = fStubCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                    LOG (INFO) << BOLDBLUE << "\t\t...Found " << +cHitCheck << " matched hits and " << +cStubCheck << " matched stubs in readout chip" << +cChipId << RESET;
+                }
             }
         }
     }
@@ -286,170 +252,180 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
     
     const std::vector<Event*>& cEvents = this->GetEvents ( pBoard );
     LOG (DEBUG) << BOLDMAGENTA << "Read back " << +cEvents.size() << " events from board." << RESET;
-    for (auto& cFe : pBoard->fModuleVector)
-    {
-        auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-        auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-    
 
-        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-        auto cFeId = cFe->getFeId();
-        TH2D* cMatchedStubs = static_cast<TH2D*> ( getHist ( cFe, "MatchedStubs" ) );
-        TH2D* cAllStubs = static_cast<TH2D*> ( getHist ( cFe, "Stubs" ) );
-        TH2D* cMissedHits = static_cast<TH2D*> ( getHist ( cFe, "MissedHits" ) );
-        
-        // matching 
-        for (auto& cChip : cFe->fReadoutChipVector) 
+    for(auto cOpticalGroup : *pBoard)
+    {
+        for (auto cHybrid : *cOpticalGroup)
         {
-            auto cChipId = cChip->getChipId();
-            if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                continue;
-
-            TH2D* cAllHits = static_cast<TH2D*> ( getHist ( cChip, "Hits_perFe" ) );
-            TH2D* cMatchedHits = static_cast<TH2D*> ( getHist ( cChip, "MatchedHits_perFe" ) );
-            TProfile2D* cMatchedHitsEye = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_eye" ) );
-            TProfile2D* cMatchedHitsTP = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_TestPulse" ) );
-            
-            TH1D* cFlaggedEvents = static_cast<TH1D*> ( getHist ( cChip, "FlaggedEvents" ) );
+            auto& cHybridHitCheck = cThisHitCheckContainer->at(cHybrid->getIndex());
+            auto& cHybridStubCheck = cThisStubCheckContainer->at(cHybrid->getIndex());  
+        
+
+            auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+            auto cHybridId = cHybrid->getId();
+            TH2D* cMatchedStubs = static_cast<TH2D*> ( getHist ( cHybrid, "MatchedStubs" ) );
+            TH2D* cAllStubs = static_cast<TH2D*> ( getHist ( cHybrid, "Stubs" ) );
+            TH2D* cMissedHits = static_cast<TH2D*> ( getHist ( cHybrid, "MissedHits" ) );
             
-            // container for this chip 
-            auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-            auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
-
-            std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-            // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-            uint8_t cBendCode = cBendLUT[ (cBend/2. - (-7.0))/0.5 ]; 
-            std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cSeed, cBend ); 
-            LOG (INFO) << BOLDMAGENTA << "Injected a stub with seed " << +cSeed << " with bend " << +cBend << RESET;
-            for(auto cHitExpected : cExpectedHits )
-                LOG (INFO) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
-            auto cEventIterator = cEvents.begin();
-            size_t cEventCounter=0;
-            LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
-            for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
+            // matching 
+            for (auto cChip : *cHybrid) 
             {
-                uint32_t cPipeline_first=0; 
-                uint32_t cBxId_first=0; 
-                bool cMissedEvent=false;
-                LOG (INFO) << BOLDMAGENTA << "Event " << +cEventIndex << RESET;
-                for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
+                ReadoutChip *theChip = static_cast<ReadoutChip*>(cChip);
+                auto cChipId = cChip->getId();
+                if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                    continue;
+
+                TH2D* cAllHits = static_cast<TH2D*> ( getHist ( cChip, "Hits_perFe" ) );
+                TH2D* cMatchedHits = static_cast<TH2D*> ( getHist ( cChip, "MatchedHits_perFe" ) );
+                TProfile2D* cMatchedHitsEye = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_eye" ) );
+                TProfile2D* cMatchedHitsTP = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_TestPulse" ) );
+                
+                TH1D* cFlaggedEvents = static_cast<TH1D*> ( getHist ( cChip, "FlaggedEvents" ) );
+                
+                // container for this chip 
+                auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
+                auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
+
+                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                uint8_t cBendCode = cBendLUT[ (cBend/2. - (-7.0))/0.5 ]; 
+                std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, cSeed, cBend ); 
+                LOG (INFO) << BOLDMAGENTA << "Injected a stub with seed " << +cSeed << " with bend " << +cBend << RESET;
+                for(auto cHitExpected : cExpectedHits )
+                    LOG (INFO) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
+                auto cEventIterator = cEvents.begin();
+                size_t cEventCounter=0;
+                LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
+                for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
                 {
-                    auto cEvent = *cEventIterator;
-                    auto cBxId = cEvent->BxId(cFe->getFeId());
-                    auto cErrorBit = cEvent->Error( cFeId , cChipId );
-                    uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                    uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
-                    cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
-                    cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
-                    LOG (DEBUG) << BOLDBLUE << "Chip" << +cChipId << " Trigger number " << +cTriggerIndex << " : Pipeline address " << +cPipeline  << " -- bx id is " << +cBxId_first << RESET;
-
-                    //hits
-                    auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
-                    cAllHits->Fill(cTriggerIndex,cPipeline,cHits.size());
-                    for( auto cHit : cHits )
+                    uint32_t cPipeline_first=0; 
+                    uint32_t cBxId_first=0; 
+                    bool cMissedEvent=false;
+                    LOG (INFO) << BOLDMAGENTA << "Event " << +cEventIndex << RESET;
+                    for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
                     {
-                        LOG (INFO) << BOLDMAGENTA << "\t... hit found in channel " << +cHit << " of readout chip" << +cChipId << RESET; 
-                    }
-                    size_t cMatched=0;
-                    for( auto cExpectedHit : cExpectedHits ) 
-                    {
-                        bool cMatchFound = std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end();
-                        cMatched += cMatchFound;
-                        cMatchedHits->Fill(cTriggerIndex,cPipeline, static_cast<int>(cMatchFound) );
-                        cMatchedHitsEye->Fill(fPhaseTap, cTriggerIndex, static_cast<int>(cMatchFound) );
-                    }
-                    cMissedHits->Fill( (int)(fAttempt) ,cChipId,cExpectedHits.size() - cMatched );
-                    if( cMatched == cExpectedHits.size() )
-                    {
-                        auto& cOcc = cReadoutChipHitCheck->getSummary<int>();
-                        cOcc += static_cast<int>(cMatched == cExpectedHits.size());
-                    }
-                    else
-                    {
-                        cMissedEvent = true;
+                        auto cEvent = *cEventIterator;
+                        auto cBxId = cEvent->BxId(cHybrid->getId());
+                        auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+                        uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+                        uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
+                        cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
+                        cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
+                        LOG (DEBUG) << BOLDBLUE << "Chip" << +cChipId << " Trigger number " << +cTriggerIndex << " : Pipeline address " << +cPipeline  << " -- bx id is " << +cBxId_first << RESET;
+
+                        //hits
+                        auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
+                        cAllHits->Fill(cTriggerIndex,cPipeline,cHits.size());
+                        for( auto cHit : cHits )
+                        {
+                            LOG (INFO) << BOLDMAGENTA << "\t... hit found in channel " << +cHit << " of readout chip" << +cChipId << RESET; 
+                        }
+                        size_t cMatched=0;
+                        for( auto cExpectedHit : cExpectedHits ) 
+                        {
+                            bool cMatchFound = std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end();
+                            cMatched += cMatchFound;
+                            cMatchedHits->Fill(cTriggerIndex,cPipeline, static_cast<int>(cMatchFound) );
+                            cMatchedHitsEye->Fill(fPhaseTap, cTriggerIndex, static_cast<int>(cMatchFound) );
+                        }
+                        cMissedHits->Fill( (int)(fAttempt) ,cChipId,cExpectedHits.size() - cMatched );
+                        if( cMatched == cExpectedHits.size() )
+                        {
+                            auto& cOcc = cReadoutChipHitCheck->getSummary<int>();
+                            cOcc += static_cast<int>(cMatched == cExpectedHits.size());
+                        }
+                        else
+                        {
+                            cMissedEvent = true;
+                        }
+                        
+                        //stubs
+                        auto cStubs = cEvent->StubVector( cHybridId, cChipId );
+                        int cNmatchedStubs=0;
+                        for( auto cStub : cStubs ) 
+                        {
+                            LOG (DEBUG) << BOLDMAGENTA << "\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << " expect seed " << +cSeed << " and bend code " << +cBendCode << RESET;
+                            bool cMatchFound = (cStub.getPosition() == cSeed && cStub.getBend() == cBendCode); 
+                            auto& cOcc = cReadoutChipStubCheck->getSummary<int>();
+                            cOcc += static_cast<int>(cMatchFound);
+                            cNmatchedStubs += static_cast<int>(cMatchFound);
+                            cMatchedStubs->Fill( cTriggerIndex , cBxId ,static_cast<int>(cMatchFound) );
+                        }
+                        cAllStubs->Fill( cTriggerIndex , cBxId , cStubs.size() );
+                        LOG (INFO) << BOLDMAGENTA "Chip" << +cChipId << "\t\t...Trigger number " << +cTriggerIndex  << " : Pipeline address " << +cPipeline  <<   " :" << +cMatched << " matched hits found [ " << +cHits.size() << " in total]. " <<  +cNmatchedStubs << " matched stubs." <<RESET; 
+                        cEventIterator++;
                     }
-                    
-                    //stubs
-                    auto cStubs = cEvent->StubVector( cFeId, cChipId );
-                    int cNmatchedStubs=0;
-                    for( auto cStub : cStubs ) 
+                    if(cMissedEvent)
                     {
-                        LOG (DEBUG) << BOLDMAGENTA << "\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << " expect seed " << +cSeed << " and bend code " << +cBendCode << RESET;
-                        bool cMatchFound = (cStub.getPosition() == cSeed && cStub.getBend() == cBendCode); 
-                        auto& cOcc = cReadoutChipStubCheck->getSummary<int>();
-                        cOcc += static_cast<int>(cMatchFound);
-                        cNmatchedStubs += static_cast<int>(cMatchFound);
-                        cMatchedStubs->Fill( cTriggerIndex , cBxId ,static_cast<int>(cMatchFound) );
+                        int cDistanceToLast = fEventCounter-fMissedEvent;
+                        LOG (DEBUG) << BOLDMAGENTA << "Event with a missing hit " << fEventCounter << " -- distance to last missed event is " << cDistanceToLast << RESET;
+                        cFlaggedEvents->Fill(cDistanceToLast);
+                        fMissedEvent = fEventCounter;
                     }
-                    cAllStubs->Fill( cTriggerIndex , cBxId , cStubs.size() );
-                    LOG (INFO) << BOLDMAGENTA "Chip" << +cChipId << "\t\t...Trigger number " << +cTriggerIndex  << " : Pipeline address " << +cPipeline  <<   " :" << +cMatched << " matched hits found [ " << +cHits.size() << " in total]. " <<  +cNmatchedStubs << " matched stubs." <<RESET; 
-                    cEventIterator++;
-                }
-                if(cMissedEvent)
-                {
-                    int cDistanceToLast = fEventCounter-fMissedEvent;
-                    LOG (DEBUG) << BOLDMAGENTA << "Event with a missing hit " << fEventCounter << " -- distance to last missed event is " << cDistanceToLast << RESET;
-                    cFlaggedEvents->Fill(cDistanceToLast);
-                    fMissedEvent = fEventCounter;
+                    fEventCounter++;
                 }
-                fEventCounter++;
             }
         }
 
         // noise hits
-        for (auto& cChip : cFe->fReadoutChipVector) 
+        for (auto cHybrid : *cOpticalGroup)
         {
-            auto cChipId = cChip->getChipId();
-            TProfile* cNoiseHits = static_cast<TProfile*> ( getHist ( cChip, "NoiseHits" ) );  
-    
-            std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-            // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-            uint8_t cBendCode = cBendLUT[ (cBend/2. - (-7.0))/0.5 ]; 
-            std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cSeed, cBend ); 
-            
-            auto cEventIterator = cEvents.begin();
-            size_t cEventCounter=0;
-            LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
-            for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
+            for (auto& cChip : *cHybrid) 
             {
-                uint32_t cPipeline_first=0; 
-                uint32_t cBxId_first=0; 
-                LOG (DEBUG) << BOLDMAGENTA << "\t..Event" << +cEventIndex << RESET;
-            
-                for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
+                ReadoutChip *theChip = static_cast<ReadoutChip*>(cChip);
+                auto cChipId = cChip->getId();
+                TProfile* cNoiseHits = static_cast<TProfile*> ( getHist ( cChip, "NoiseHits" ) );  
+        
+                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                uint8_t cBendCode = cBendLUT[ (cBend/2. - (-7.0))/0.5 ]; 
+                std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, cSeed, cBend ); 
+                auto cHybridId = cHybrid->getId();
+                
+                auto cEventIterator = cEvents.begin();
+                size_t cEventCounter=0;
+                LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
+                for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
                 {
-                    auto cEvent = *cEventIterator;
-                    auto cBxId = cEvent->BxId(cFe->getFeId());
-                    auto cErrorBit = cEvent->Error( cFeId , cChipId );
-                    uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                    uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
-                    cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
-                    cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
-                    
-                    //hits
-                    auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
-                    for( int cChannel=0; cChannel < NCHANNELS; cChannel++)
+                    uint32_t cPipeline_first=0; 
+                    uint32_t cBxId_first=0; 
+                    LOG (DEBUG) << BOLDMAGENTA << "\t..Event" << +cEventIndex << RESET;
+                
+                    for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
                     {
-                        bool cHitFound = std::find(  cHits.begin(), cHits.end(), cChannel) != cHits.end();
-                        //if( cHitFound && std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                        //    LOG (INFO) << BOLDMAGENTA << "\t... noise hit found in channel " << +cChannel << " of readout chip" << +cChipId << RESET; 
-                        cNoiseHits->Fill(cChannel, cHitFound);
+                        auto cEvent = *cEventIterator;
+                        auto cBxId = cEvent->BxId(cHybrid->getId());
+                        auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+                        uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+                        uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
+                        cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
+                        cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
+                        
+                        //hits
+                        auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
+                        for( int cChannel=0; cChannel < NCHANNELS; cChannel++)
+                        {
+                            bool cHitFound = std::find(  cHits.begin(), cHits.end(), cChannel) != cHits.end();
+                            //if( cHitFound && std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                            //    LOG (INFO) << BOLDMAGENTA << "\t... noise hit found in channel " << +cChannel << " of readout chip" << +cChipId << RESET; 
+                            cNoiseHits->Fill(cChannel, cHitFound);
+                        }
+                        // for( auto cHit : cHits )
+                        // {
+                        //     bool cExpected = std::find(  cExpectedHits.begin(), cExpectedHits.end(), cHit) != cExpectedHits.end();
+                        //     if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                        //         cNoiseHits->Fill(cHit);
+                        //     else
+                        //     {
+                        //         if(!cExpected)
+                        //         {
+                        //             // this is not going to work..I've masked out everyhing else!
+                        //             cNoiseHits->Fill(cHit);
+                        //         }
+                        //     }
+                        // }
+                        cEventIterator++;
                     }
-                    // for( auto cHit : cHits )
-                    // {
-                    //     bool cExpected = std::find(  cExpectedHits.begin(), cExpectedHits.end(), cHit) != cExpectedHits.end();
-                    //     if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                    //         cNoiseHits->Fill(cHit);
-                    //     else
-                    //     {
-                    //         if(!cExpected)
-                    //         {
-                    //             // this is not going to work..I've masked out everyhing else!
-                    //             cNoiseHits->Fill(cHit);
-                    //         }
-                    //     }
-                    // }
-                    cEventIterator++;
                 }
             }
         }
@@ -458,34 +434,38 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
 void DataChecker::ReadDataTest()
 {
     std::stringstream outp;
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            // matching 
-            uint16_t cTh1 = (cFe->getFeId()%2==0) ? 900 : 1; 
-            uint16_t cTh2 = (cFe->getFeId()%2==0) ? 1 : 900; 
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cHybrid : *cOpticalGroup)
             {
-                if( cChip->getChipId()%2 == 0 )
-                    fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cTh1);
-                else
-                    fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cTh2);
+                // matching 
+                uint16_t cTh1 = (cHybrid->getId()%2==0) ? 900 : 1; 
+                uint16_t cTh2 = (cHybrid->getId()%2==0) ? 1 : 900; 
+                for (auto cChip : *cHybrid) 
+                {
+                    if( cChip->getId()%2 == 0 )
+                        fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip), "VCth" , cTh1);
+                    else
+                        fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip), "VCth" , cTh2);
+                }
             }
         }
         
         LOG (INFO) << BOLDRED << "Opening shutter ... press any key to close .." << RESET;
-        fBeBoardInterface->Start(cBoard);
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
+        fBeBoardInterface->Start(theBoard);
         do
         {
             std::this_thread::sleep_for (std::chrono::milliseconds (10) );
         }while( std::cin.get()!='\n');
         //std::this_thread::sleep_for (std::chrono::milliseconds (1000) );
-        fBeBoardInterface->Stop(cBoard);
+        fBeBoardInterface->Stop(theBoard);
         
         LOG (INFO) << BOLDBLUE << "Stopping triggers..." << RESET;
-        this->ReadData( cBoard , true);
-        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+        this->ReadData( theBoard , true);
+        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
         LOG (INFO) << BOLDBLUE << +cEvents.size() << " events read back from FC7 with ReadData" << RESET;
         // LOG (INFO) << BOLDRED << "Press any key to to see the event printout .." << RESET;
         // do
@@ -510,24 +490,28 @@ void DataChecker::ReadNeventsTest()
     auto cSetting = fSettingsMap.find ( "Nevents" );
     uint32_t cNevents = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
     std::stringstream outp;
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            // matching 
-            uint16_t cTh1 = (cFe->getFeId()%2==0) ? 900 : 1; 
-            uint16_t cTh2 = (cFe->getFeId()%2==0) ? 1 : 900; 
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cHybrid : *cOpticalGroup)
             {
-                if( cChip->getChipId()%2 == 0 )
-                    fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cTh1);
-                else
-                    fReadoutChipInterface->WriteChipReg( cChip, "VCth" , cTh2);
+                // matching 
+                uint16_t cTh1 = (cHybrid->getId()%2==0) ? 900 : 1; 
+                uint16_t cTh2 = (cHybrid->getId()%2==0) ? 1 : 900; 
+                for (auto cChip : *cHybrid) 
+                {
+                    if( cChip->getId()%2 == 0 )
+                        fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip), "VCth" , cTh1);
+                    else
+                        fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip), "VCth" , cTh2);
+                }
             }
         }
-        
-        this->ReadNEvents( cBoard , cNevents);
-        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
+  
+        this->ReadNEvents( theBoard , cNevents);
+        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
         LOG (INFO) << BOLDBLUE << +cEvents.size() << " events read back from FC7 with ReadData" << RESET;
         uint32_t cN=0;
         for ( auto& cEvent : cEvents )
@@ -556,14 +540,14 @@ void DataChecker::ReadNeventsTest()
 
 //     const std::vector<Event*>& cEvents = this->GetEvents ( pBoard );
 //     LOG (DEBUG) << BOLDMAGENTA << "Read back " << +cEvents.size() << " events from board." << RESET;
-//     for (auto& cFe : pBoard->fModuleVector)
+//     for (auto& cHybrid : pBoard->fModuleVector)
 //     {
-//         auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-//         auto cFeId = cFe->getFeId();
+//         auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+//         auto cHybridId = cHybrid->getId();
             
-//         for (auto& cChip : cFe->fReadoutChipVector) 
+//         for (auto& cChip : cHybrid->fReadoutChipVector) 
 //         {
-//             auto cChipId = cChip->getChipId();
+//             auto cChipId = cChip->getId();
 //             TProfile* cNoiseHits = static_cast<TProfile*> ( getHist ( cChip, "NoiseHits" ) );  
     
 //             std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
@@ -573,7 +557,7 @@ void DataChecker::ReadNeventsTest()
             
 //             auto cEventIterator = cEvents.begin();
 //             size_t cEventCounter=0;
-//             LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
+//             LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
 //             for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
 //             {
 //                 uint32_t cPipeline_first=0; 
@@ -583,15 +567,15 @@ void DataChecker::ReadNeventsTest()
 //                 for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
 //                 {
 //                     auto cEvent = *cEventIterator;
-//                     auto cBxId = cEvent->BxId(cFe->getFeId());
-//                     auto cErrorBit = cEvent->Error( cFeId , cChipId );
-//                     uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-//                     uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
+//                     auto cBxId = cEvent->BxId(cHybrid->getId());
+//                     auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+//                     uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+//                     uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
 //                     cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
 //                     cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
                     
 //                     //hits
-//                     auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
+//                     auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
 //                     for( int cChannel=0; cChannel < NCHANNELS; cChannel++)
 //                     {
 //                         bool cHitFound = std::find(  cHits.begin(), cHits.end(), cChannel) != cHits.end();
@@ -707,79 +691,87 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
    
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
-    for (auto cBoard : this->fBoardVector)
+
+    for(auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                if( cMode == 0 )
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Latched", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                //configure CBCs 
+                for (auto cChip : *cHybrid)
+                {
+                    // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
+                    //enable stub logic
+                    if( cMode == 0 )
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Latched", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 
     // generate stubs in exactly chips with IDs that match pChipIds
     size_t cSeedIndex=0;
     std::vector<int> cExpectedHits(0);
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for(auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) != pChipIds.end()  ) 
+                for (auto& cChip : *cHybrid)
                 {
-                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                    // both stub and bend are in units of half strips 
-                    double cBend_strips = cStub.second/2.;
-                    // if using TP then always inject a stub with bend 0 .. 
-                    // later will use offset window to modify bend [ should probably put this in inject stub ]
-                    uint8_t cBend_halfStrips = cStub.second ; 
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {cStub.first} , {cBend_halfStrips}, false );
-                    // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                    uint8_t cBendCode = cBendLUT[ (cStub.second/2. - (-7.0))/0.5 ]; 
-                    // set offsets
-                    // needs to be fixed 
-                    /*
-                    uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    //uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    // set offsets
-                    uint8_t cOffetReg = (cOffsetCode << 4) | (cOffsetCode << 0);
-                    LOG (INFO) << BOLDBLUE << "\t..--- bend code is 0x" << std::hex << +cBendCode << std::dec << " ..setting offset window to  " << std::bitset<8>(cOffetReg) << RESET;
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", cOffetReg );
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", cOffetReg );
-                    */
-                    fReadoutChipInterface->enableInjection(cChip, true);
-                    //static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cTargetThreshold);
-                }
-                else
-                   static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
-            } 
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
+                    {
+                        std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                        // both stub and bend are in units of half strips 
+                        double cBend_strips = cStub.second/2.;
+                        // if using TP then always inject a stub with bend 0 .. 
+                        // later will use offset window to modify bend [ should probably put this in inject stub ]
+                        uint8_t cBend_halfStrips = cStub.second ; 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {cStub.first} , {cBend_halfStrips}, false );
+                        // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                        uint8_t cBendCode = cBendLUT[ (cStub.second/2. - (-7.0))/0.5 ]; 
+                        // set offsets
+                        // needs to be fixed 
+                        /*
+                        uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        //uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        // set offsets
+                        uint8_t cOffetReg = (cOffsetCode << 4) | (cOffsetCode << 0);
+                        LOG (INFO) << BOLDBLUE << "\t..--- bend code is 0x" << std::hex << +cBendCode << std::dec << " ..setting offset window to  " << std::bitset<8>(cOffetReg) << RESET;
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", cOffetReg );
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", cOffetReg );
+                        */
+                        fReadoutChipInterface->enableInjection(theChip, true);
+                        //static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cTargetThreshold);
+                    }
+                    else
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
+                } 
+            }
         }
     }
 
     
     
-    // measure     
-    for (auto cBoard : this->fBoardVector)
+    // measure         
+    for(auto cBoard : *fDetectorContainer)
     {
-        
-        uint16_t cBoardTriggerMult = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        uint16_t cBoardTriggerMult = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
         LOG (DEBUG) << BOLDBLUE << "Trigger multiplicity is set to " << +cBoardTriggerMult << " consecutive triggers per L1A." << RESET ; 
         if( cConfigureTriggerMult )
         {
             LOG (DEBUG) << BOLDBLUE << "Modifying trigger multiplicity to be " << +(1+cTriggerMult) << " consecutive triggers per L1A for DataTest" << RESET;
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cTriggerMult);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cTriggerMult);
         }
         
         // set TP amplitude 
@@ -792,128 +784,135 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
             //configure TP delay on all chips
             setSameGlobalDac("TestPulseDelay", cDelayDAC);
             // configure hit latency on all chips  
-            setSameDacBeBoard(cBoard, "TriggerLatency", cLatencyDAC);
+            setSameDacBeBoard(theBoard, "TriggerLatency", cLatencyDAC);
             // set stub latency on back-end board 
             uint16_t cStubLatency = cLatencyDAC - 1*cStubDelay ;
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
-            fBeBoardInterface->ChipReSync ( cBoard ); // NEED THIS! ?? 
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
+            fBeBoardInterface->ChipReSync ( theBoard ); // NEED THIS! ?? 
             // loop over threshold here 
             LOG (INFO) <<  BOLDMAGENTA << "Delay is " << -1*cDelay << " TP delay is " << +cDelayDAC << " latency DAC set to " << +cLatencyDAC << RESET;
             for( uint16_t cThreshold = cInitialTh ; cThreshold < cFinalTh ; cThreshold+= cThStep )
             {
                 LOG (DEBUG) <<  BOLDMAGENTA << "\t\t...Threshold is " << +cThreshold << RESET;
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cHybrid : *cOpticalGroup)
                     {
-                        if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) == pChipIds.end() )
-                            continue;
-                        fReadoutChipInterface->WriteChipReg ( cChip, "VCth", cThreshold );
-                    }
-                }   
+                        for (auto cChip : *cHybrid) 
+                        {
+                            if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end() )
+                                continue;
+                            fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", cThreshold );
+                        }
+                    }   
+                }
 
                 // start triggers 
-                fBeBoardInterface->Start(cBoard);
-                auto cNtriggers = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter");
+                fBeBoardInterface->Start(theBoard);
+                auto cNtriggers = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter");
                 do
                 {
                     std::this_thread::sleep_for (std::chrono::milliseconds (10) );
-                    cNtriggers = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter");
+                    cNtriggers = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter");
                 }while( cNtriggers < 100 );
-                fBeBoardInterface->Stop(cBoard);
-                //this->ReadNEvents ( cBoard , cEventsPerPoint);
-                this->ReadData( cBoard , true);
-                const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+                fBeBoardInterface->Stop(theBoard);
+                //this->ReadNEvents ( theBoard , cEventsPerPoint);
+                this->ReadData( theBoard , true);
+                const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
                 // matching 
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    auto cFeId = cFe->getFeId();
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cHybrid : *cOpticalGroup)
                     {
-                        auto cOffset = 0;
-                        auto cThreshold = fReadoutChipInterface->ReadChipReg(cChip, "VCth");
-                        auto cChipId = cChip->getChipId();
-                        if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                            continue;
-
-                        std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                        // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                        uint8_t cBendCode = cBendLUT[ ((cStub.second+cOffset)/2. - (-7.0))/0.5 ]; 
-                        
-                        std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cStub.first, cStub.second  ); 
-                        LOG (DEBUG) << BOLDMAGENTA << "Injected a stub with seed " << +cStub.first << " with bend " << +cStub.second << RESET;
-                        for(auto cHitExpected : cExpectedHits )
-                            LOG (DEBUG) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
-                        
-                        auto cEventIterator = cEvents.begin();
-                        size_t cEventCounter=0;
-                        LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
-                        size_t cMatchedStubs=0;
-                        // vector to keep track of number of matches
-                        std::vector<uint32_t> cHitMatches(cExpectedHits.size(),0); 
-                        for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
+                        auto cHybridId = cHybrid->getId();
+                        for (auto cChip : *cHybrid) 
                         {
-                            uint32_t cPipeline_first=0; 
-                            uint32_t cBxId_first=0; 
-                            bool cMissedEvent=false;
-
-                            if( cEventIndex == 0 )
-                                LOG (DEBUG) << BOLDMAGENTA << "'\tEvent " << +cEventIndex << RESET;
-                            bool cIncorrectPipeline=false;
-                            for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
+                            ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                            auto cOffset = 0;
+                            auto cThreshold = fReadoutChipInterface->ReadChipReg(theChip, "VCth");
+                            auto cChipId = cChip->getId();
+                            if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                                continue;
+
+                            std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                            // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                            uint8_t cBendCode = cBendLUT[ ((cStub.second+cOffset)/2. - (-7.0))/0.5 ]; 
+                            
+                            std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, cStub.first, cStub.second  ); 
+                            LOG (DEBUG) << BOLDMAGENTA << "Injected a stub with seed " << +cStub.first << " with bend " << +cStub.second << RESET;
+                            for(auto cHitExpected : cExpectedHits )
+                                LOG (DEBUG) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
+                            
+                            auto cEventIterator = cEvents.begin();
+                            size_t cEventCounter=0;
+                            LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
+                            size_t cMatchedStubs=0;
+                            // vector to keep track of number of matches
+                            std::vector<uint32_t> cHitMatches(cExpectedHits.size(),0); 
+                            for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
                             {
-                                auto cEvent = *cEventIterator;
-                                auto cBxId = cEvent->BxId(cFe->getFeId());
-                                auto cErrorBit = cEvent->Error( cFeId , cChipId );
-                                uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                                uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
-                                cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
-                                cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
-                                bool cCountEvent = ( static_cast<size_t>(cPipeline - cPipeline_first) == cTriggerIndex );
-                                if(cCountEvent)
+                                uint32_t cPipeline_first=0; 
+                                uint32_t cBxId_first=0; 
+                                bool cMissedEvent=false;
+
+                                if( cEventIndex == 0 )
+                                    LOG (DEBUG) << BOLDMAGENTA << "'\tEvent " << +cEventIndex << RESET;
+                                bool cIncorrectPipeline=false;
+                                for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
                                 {
-                                    //hits
-                                    auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
-                                    size_t cMatched=0;
-                                    int cLatency_eq = cLatencyDAC  - (cPipeline - cPipeline_first);
-                                    double cTime_ns = -1*(cLatency_eq - fTPconfig.tpDelay)*25 + cDelayDAC ;
-                                    auto cIterator =  cExpectedHits.begin(); 
-                                    do
+                                    auto cEvent = *cEventIterator;
+                                    auto cBxId = cEvent->BxId(cHybrid->getId());
+                                    auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+                                    uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+                                    uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
+                                    cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
+                                    cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
+                                    bool cCountEvent = ( static_cast<size_t>(cPipeline - cPipeline_first) == cTriggerIndex );
+                                    if(cCountEvent)
                                     {
-                                        bool cMatchFound = std::find(  cHits.begin(), cHits.end(), *cIterator) != cHits.end();
-                                        cHitMatches[ std::distance( cExpectedHits.begin() , cIterator )] += cMatchFound;
-                                        cMatched += cMatchFound;
-                                        cIterator++;
-                                    }while( cIterator < cExpectedHits.end() );
-                                    
-                                    //stubs
-                                    auto cStubs = cEvent->StubVector( cFeId, cChipId );
-                                    int cNmatchedStubs=0;
-                                    for( auto cFeStub : cStubs ) 
-                                    {
-                                        LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cFeStub.getPosition() << RESET;
-                                        LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cFeStub.getBend() << std::dec << RESET;
-                                        bool cMatchFound = (cFeStub.getPosition() == cStub.first && cFeStub.getBend() == cBendCode); 
-                                        cNmatchedStubs += static_cast<int>(cMatchFound);
+                                        //hits
+                                        auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
+                                        size_t cMatched=0;
+                                        int cLatency_eq = cLatencyDAC  - (cPipeline - cPipeline_first);
+                                        double cTime_ns = -1*(cLatency_eq - fTPconfig.tpDelay)*25 + cDelayDAC ;
+                                        auto cIterator =  cExpectedHits.begin(); 
+                                        do
+                                        {
+                                            bool cMatchFound = std::find(  cHits.begin(), cHits.end(), *cIterator) != cHits.end();
+                                            cHitMatches[ std::distance( cExpectedHits.begin() , cIterator )] += cMatchFound;
+                                            cMatched += cMatchFound;
+                                            cIterator++;
+                                        }while( cIterator < cExpectedHits.end() );
+                                        
+                                        //stubs
+                                        auto cStubs = cEvent->StubVector( cHybridId, cChipId );
+                                        int cNmatchedStubs=0;
+                                        for( auto cHybridStub : cStubs ) 
+                                        {
+                                            LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cHybridStub.getPosition() << RESET;
+                                            LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cHybridStub.getBend() << std::dec << RESET;
+                                            bool cMatchFound = (cHybridStub.getPosition() == cStub.first && cHybridStub.getBend() == cBendCode); 
+                                            cNmatchedStubs += static_cast<int>(cMatchFound);
+                                        }
+                                        if( cNmatchedStubs == 1 )
+                                        {
+                                            cMatchedStubs ++;
+                                        }
+                                        
+                                        if( cEventIndex == 0 )
+                                            LOG (DEBUG) << BOLDMAGENTA << "\t\t.. Threshold of " << +cThreshold << " [Trigger " << +cTriggerIndex << " Pipeline is " << +cPipeline << "] Delay of " << +cTime_ns << " ns [ " << +cDelay << " ] after the TP ... Found " << +cMatched << " matched hits and " <<  +cNmatchedStubs << " matched stubs." <<RESET; 
                                     }
-                                    if( cNmatchedStubs == 1 )
-                                    {
-                                        cMatchedStubs ++;
-                                    }
-                                    
-                                    if( cEventIndex == 0 )
-                                        LOG (DEBUG) << BOLDMAGENTA << "\t\t.. Threshold of " << +cThreshold << " [Trigger " << +cTriggerIndex << " Pipeline is " << +cPipeline << "] Delay of " << +cTime_ns << " ns [ " << +cDelay << " ] after the TP ... Found " << +cMatched << " matched hits and " <<  +cNmatchedStubs << " matched stubs." <<RESET; 
+                                    else
+                                        cIncorrectPipeline = cIncorrectPipeline || true;
+                                    cEventIterator++;
                                 }
-                                else
-                                    cIncorrectPipeline = cIncorrectPipeline || true;
-                                cEventIterator++;
-                            }
-                            // if missed on pipeline .. count this event
+                                // if missed on pipeline .. count this event
 
-                        }
-                        for( auto cIterator = cHitMatches.begin(); cIterator < cHitMatches.end() ; cIterator++)
-                        {
-                            LOG (INFO) << BOLDMAGENTA << "\t.. " << +(*cIterator) << " events out of a possible " << +cEvents.size() << " with a hit in channel " << +cExpectedHits[ std::distance( cHitMatches.begin() , cIterator )] <<  RESET;
+                            }
+                            for( auto cIterator = cHitMatches.begin(); cIterator < cHitMatches.end() ; cIterator++)
+                            {
+                                LOG (INFO) << BOLDMAGENTA << "\t.. " << +(*cIterator) << " events out of a possible " << +cEvents.size() << " with a hit in channel " << +cExpectedHits[ std::distance( cHitMatches.begin() , cIterator )] <<  RESET;
+                            }
                         }
                     }
                 }
@@ -946,11 +945,11 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //             for( int cOffset=cInitialWindowOffset; cOffset <= cFinalWindowOffset; cOffset++)
         //             {
         //                 LOG (INFO) << BOLDMAGENTA << "Correlation window offset set to " << +cOffset << RESET;
-        //                 for (auto& cFe : cBoard->fModuleVector)
+        //                 for (auto& cHybrid : cBoard->fModuleVector)
         //                 {
-        //                     for (auto& cChip : cFe->fReadoutChipVector) 
+        //                     for (auto& cChip : cHybrid->fReadoutChipVector) 
         //                     {
-        //                         if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) == pChipIds.end() )
+        //                         if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end() )
         //                             continue;
 
         //                         if( cOffset < 0)
@@ -982,12 +981,12 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //                     this->ReadNEvents ( cBoard , cEventsPerPoint);
         //                     const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
         //                     // matching 
-        //                     for (auto& cFe : cBoard->fModuleVector)
+        //                     for (auto& cHybrid : cBoard->fModuleVector)
         //                     {
-        //                         auto cFeId = cFe->getFeId();
-        //                         for (auto& cChip : cFe->fReadoutChipVector) 
+        //                         auto cHybridId = cHybrid->getId();
+        //                         for (auto& cChip : cHybrid->fReadoutChipVector) 
         //                         {
-        //                             auto cChipId = cChip->getChipId();
+        //                             auto cChipId = cChip->getId();
         //                             if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
         //                                 continue;
 
@@ -1007,7 +1006,7 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                                     
         //                             auto cEventIterator = cEvents.begin();
         //                             size_t cEventCounter=0;
-        //                             LOG (INFO) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
+        //                             LOG (INFO) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
         //                             size_t cMatchedHits=0;
         //                             size_t cMatchedStubs=0;
         //                             for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
@@ -1022,17 +1021,17 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //                                 for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
         //                                 {
         //                                     auto cEvent = *cEventIterator;
-        //                                     auto cBxId = cEvent->BxId(cFe->getFeId());
-        //                                     auto cErrorBit = cEvent->Error( cFeId , cChipId );
-        //                                     uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-        //                                     uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
+        //                                     auto cBxId = cEvent->BxId(cHybrid->getId());
+        //                                     auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+        //                                     uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+        //                                     uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
         //                                     cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
         //                                     cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
         //                                     bool cCountEvent = ( static_cast<size_t>(cPipeline - cPipeline_first) == cTriggerIndex );
         //                                     if(cCountEvent)
         //                                     {
         //                                         //hits
-        //                                         auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
+        //                                         auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
         //                                         size_t cMatched=0;
         //                                         int cLatency_eq = cLatency  - (cPipeline - cPipeline_first);
         //                                         double cTime_ns = 1*(static_cast<float>(fTPconfig.tpDelay - cLatency_eq)*25. + (25.0 - cTPdelay));
@@ -1055,13 +1054,13 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //                                         //    cMatchedHitsTP->Fill( cTime_ns , cTPamplitude , 0);
         //                                         //}
         //                                         //stubs
-        //                                         auto cStubs = cEvent->StubVector( cFeId, cChipId );
+        //                                         auto cStubs = cEvent->StubVector( cHybridId, cChipId );
         //                                         int cNmatchedStubs=0;
-        //                                         for( auto cFeStub : cStubs ) 
+        //                                         for( auto cHybridStub : cStubs ) 
         //                                         {
-        //                                             LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cFeStub.getPosition() << RESET;
-        //                                             LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cFeStub.getBend() << std::dec << RESET;
-        //                                             bool cMatchFound = (cFeStub.getPosition() == cStub.first && cFeStub.getBend() == cBendCode); 
+        //                                             LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cHybridStub.getPosition() << RESET;
+        //                                             LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cHybridStub.getBend() << std::dec << RESET;
+        //                                             bool cMatchFound = (cHybridStub.getPosition() == cStub.first && cHybridStub.getBend() == cBendCode); 
         //                                             cMatchedStubsHist->Fill( cOffset , cMatchFound);
         //                                             cNmatchedStubs += static_cast<int>(cMatchFound);
         //                                         }
@@ -1098,11 +1097,11 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //         //     for( int cOffset=cInitialWindowOffset; cOffset <= cFinalWindowOffset; cOffset++)
         //         //     {
         //         //         LOG (INFO) << BOLDMAGENTA << "Correlation window offset set to " << +cOffset << RESET;
-        //         //         for (auto& cFe : cBoard->fModuleVector)
+        //         //         for (auto& cHybrid : cBoard->fModuleVector)
         //         //         {
-        //         //             for (auto& cChip : cFe->fReadoutChipVector) 
+        //         //             for (auto& cChip : cHybrid->fReadoutChipVector) 
         //         //             {
-        //         //                 if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) == pChipIds.end() )
+        //         //                 if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end() )
         //         //                     continue;
 
         //         //                 if( cOffset < 0)
@@ -1133,12 +1132,12 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //         //             this->ReadNEvents ( cBoard , cEventsPerPoint);
         //         //             const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
         //         //             // matching 
-        //         //             for (auto& cFe : cBoard->fModuleVector)
+        //         //             for (auto& cHybrid : cBoard->fModuleVector)
         //         //             {
-        //         //                 auto cFeId = cFe->getFeId();
-        //         //                 for (auto& cChip : cFe->fReadoutChipVector) 
+        //         //                 auto cHybridId = cHybrid->getId();
+        //         //                 for (auto& cChip : cHybrid->fReadoutChipVector) 
         //         //                 {
-        //         //                     auto cChipId = cChip->getChipId();
+        //         //                     auto cChipId = cChip->getId();
         //         //                     if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
         //         //                         continue;
 
@@ -1158,7 +1157,7 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                                     
         //         //                     auto cEventIterator = cEvents.begin();
         //         //                     size_t cEventCounter=0;
-        //         //                     LOG (INFO) << BOLDMAGENTA << "CBC" << +cChip->getChipId() << RESET;
+        //         //                     LOG (INFO) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
         //         //                     size_t cMatchedHits=0;
         //         //                     size_t cMatchedStubs=0;
         //         //                     for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
@@ -1173,17 +1172,17 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //         //                         for(size_t cTriggerIndex=0; cTriggerIndex <= cTriggerMult; cTriggerIndex++) // cTriggerMult consecutive triggers were sent 
         //         //                         {
         //         //                             auto cEvent = *cEventIterator;
-        //         //                             auto cBxId = cEvent->BxId(cFe->getFeId());
-        //         //                             auto cErrorBit = cEvent->Error( cFeId , cChipId );
-        //         //                             uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-        //         //                             uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
+        //         //                             auto cBxId = cEvent->BxId(cHybrid->getId());
+        //         //                             auto cErrorBit = cEvent->Error( cHybridId , cChipId );
+        //         //                             uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
+        //         //                             uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
         //         //                             cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
         //         //                             cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
         //         //                             bool cCountEvent = ( static_cast<size_t>(cPipeline - cPipeline_first) == cTriggerIndex );
         //         //                             if(cCountEvent)
         //         //                             {
         //         //                                 //hits
-        //         //                                 auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
+        //         //                                 auto cHits = cEvent->GetHits( cHybridId, cChipId ) ;
         //         //                                 size_t cMatched=0;
         //         //                                 int cLatency_eq = cLatency  - (cPipeline - cPipeline_first);
         //         //                                 double cTime_ns = 1*(static_cast<float>(fTPconfig.tpDelay - cLatency_eq)*25. + (25.0 - cTPdelay));
@@ -1206,13 +1205,13 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //         //                                     cMatchedHitsTP->Fill( cTime_ns , cTPamplitude , 0);
         //         //                                 }
         //         //                                 //stubs
-        //         //                                 auto cStubs = cEvent->StubVector( cFeId, cChipId );
+        //         //                                 auto cStubs = cEvent->StubVector( cHybridId, cChipId );
         //         //                                 int cNmatchedStubs=0;
-        //         //                                 for( auto cFeStub : cStubs ) 
+        //         //                                 for( auto cHybridStub : cStubs ) 
         //         //                                 {
-        //         //                                     LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cFeStub.getPosition() << RESET;
-        //         //                                     LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cFeStub.getBend() << std::dec << RESET;
-        //         //                                     bool cMatchFound = (cFeStub.getPosition() == cStub.first && cFeStub.getBend() == cBendCode); 
+        //         //                                     LOG (DEBUG) << BOLDMAGENTA << "\t.. expected seed is " << +cStub.first << " measured seed is " << +cHybridStub.getPosition() << RESET;
+        //         //                                     LOG (DEBUG) << BOLDMAGENTA << "\t.. expected bend code is 0x" << std::hex << +cBendCode << std::dec << " measured bend code is 0x" << std::hex <<  +cHybridStub.getBend() << std::dec << RESET;
+        //         //                                     bool cMatchFound = (cHybridStub.getPosition() == cStub.first && cHybridStub.getBend() == cBendCode); 
         //         //                                     cMatchedStubsHist->Fill( cOffset , cMatchFound);
         //         //                                     cNmatchedStubs += static_cast<int>(cMatchFound);
         //         //                                 }
@@ -1244,7 +1243,7 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
         //     }
         // }
         if( cConfigureTriggerMult )
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cBoardTriggerMult);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cBoardTriggerMult);
         
     }
         
@@ -1258,33 +1257,41 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
     //unmask all channels and reset offsets 
     // also re-configure thresholds + hit/stub detect logic to original values 
     // and re-load configuration of fast command block from register map loaded from xml file 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {   
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
         auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            auto& cThresholdsThisOpticalGroup = cThresholdsThisBoard->at(cOpticalGroup->getIndex());
+            auto& cLogicThisOpticalGroup = cLogicThisBoard->at(cOpticalGroup->getIndex());
+            auto& cHIPsThisOpticalGroup = cHIPsThisBoard->at(cOpticalGroup->getIndex());
+
+            for (auto cHybrid : *cOpticalGroup)
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                auto& cThresholdsThisHybrid = cThresholdsThisOpticalGroup->at(cHybrid->getIndex());
+                auto& cLogicThisHybrid = cLogicThisOpticalGroup->at(cHybrid->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisOpticalGroup->at(cHybrid->getIndex());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for (auto cChip : *cHybrid)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+
+                    LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                }
             }
         }
         //
         LOG (DEBUG) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
+        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(static_cast<BeBoard*>(cBoard));
     }
 
 }
@@ -1344,20 +1351,23 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     if( ( cSetting != std::end ( fSettingsMap ) ) )
     {
         fPhaseTap = cSetting->second ; 
-        for (auto cBoard : this->fBoardVector)
+        for (auto cBoard : *fDetectorContainer)
         {
-            for (auto& cFe : cBoard->fModuleVector)
+            for(auto cOpticalGroup : *cBoard)
             {
-                auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-                if( cCic != NULL )
+                for (auto cHybrid : *cOpticalGroup)
                 {
-                    for(auto cChipId : pChipIds )
+                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                    if( cCic != NULL )
                     {
-                        bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , fPhaseTap);
+                        for(auto cChipId : pChipIds )
+                        {
+                            bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , fPhaseTap);
+                        }
                     }
                 }
             }
-            fBeBoardInterface->ChipReSync ( cBoard );
+            fBeBoardInterface->ChipReSync (static_cast<BeBoard*>(cBoard));
         }
     }
 
@@ -1397,64 +1407,71 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
 
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                if( cMode == 0 )
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Latched", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                //configure CBCs 
+                for (auto cChip : *cHybrid)
+                {
+                    // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
+                    //enable stub logic
+                    if( cMode == 0 )
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Latched", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync (static_cast<BeBoard*>(cBoard));
     }
 
     // generate stubs in exactly chips with IDs that match pChipIds
     size_t cSeedIndex=0;
     std::vector<int> cExpectedHits(0);
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) != pChipIds.end()  ) 
+                for (auto cChip : *cHybrid)
                 {
-                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                    // both stub and bend are in units of half strips 
-                    double cBend_strips = cStub.second/2.;
-                    // if using TP then always inject a stub with bend 0 .. 
-                    // later will use offset window to modify bend [ should probably put this in inject stub ]
-                    uint8_t cBend_halfStrips = (pWithNoise) ? cStub.second : 0 ; 
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {cStub.first} , {cBend_halfStrips}, pWithNoise );
-                    // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                    uint8_t cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; 
-                    // set offsets
-                    // needs to be fixed 
-                    /*
-                    uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    //uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    // set offsets
-                    uint8_t cOffetReg = (cOffsetCode << 4) | (cOffsetCode << 0);
-                    LOG (INFO) << BOLDBLUE << "\t..--- bend code is 0x" << std::hex << +cBendCode << std::dec << " ..setting offset window to  " << std::bitset<8>(cOffetReg) << RESET;
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", cOffetReg );
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", cOffetReg );
-                    */
-                    if(!pWithNoise)
-                        fReadoutChipInterface->enableInjection(cChip, true);
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
+                    {
+                        std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                        // both stub and bend are in units of half strips 
+                        double cBend_strips = cStub.second/2.;
+                        // if using TP then always inject a stub with bend 0 .. 
+                        // later will use offset window to modify bend [ should probably put this in inject stub ]
+                        uint8_t cBend_halfStrips = (pWithNoise) ? cStub.second : 0 ; 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {cStub.first} , {cBend_halfStrips}, pWithNoise );
+                        // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                        uint8_t cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; 
+                        // set offsets
+                        // needs to be fixed 
+                        /*
+                        uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        //uint8_t cOffsetCode = static_cast<uint8_t>(std::fabs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        // set offsets
+                        uint8_t cOffetReg = (cOffsetCode << 4) | (cOffsetCode << 0);
+                        LOG (INFO) << BOLDBLUE << "\t..--- bend code is 0x" << std::hex << +cBendCode << std::dec << " ..setting offset window to  " << std::bitset<8>(cOffetReg) << RESET;
+                        fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", cOffetReg );
+                        fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", cOffetReg );
+                        */
+                        if(!pWithNoise)
+                            fReadoutChipInterface->enableInjection(theChip, true);
+                    }
+                    else if(!pWithNoise)
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cTargetThreshold);
+                    else
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
                 }
-                else if(!pWithNoise)
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cTargetThreshold);
-                else
-                   static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
             } 
         }
     }
@@ -1464,25 +1481,26 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     //{
         this->zeroContainers();
         // measure     
-        for (auto cBoard : this->fBoardVector)
+        for (auto cBoard : *fDetectorContainer)
         {
+            BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
             //LOG (INFO) << BOLDMAGENTA << "Setting stub package delay to " << +cPackageDelay << RESET;
             //fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.physical_interface_block.cic.stub_package_delay", cPackageDelay);
             //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
 
-            uint16_t cBoardTriggerMult = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
-            uint16_t cBoardTriggerRate = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency");
+            uint16_t cBoardTriggerMult = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
+            uint16_t cBoardTriggerRate = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency");
             LOG (DEBUG) << BOLDBLUE << "Trigger rate is set to " << +cBoardTriggerRate << " kHz" << RESET ; 
             LOG (DEBUG) << BOLDBLUE << "Trigger multiplicity is set to " << +cBoardTriggerMult << " consecutive triggers per L1A." << RESET ; 
             if( cConfigureTrigger && pWithNoise)
             {
                 LOG (DEBUG) << BOLDBLUE << "Modifying trigger rate to be " << +cTriggerRate << " kHz for DataTest" << RESET;
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency", cTriggerRate);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency", cTriggerRate);
             }
             if( cConfigureTriggerMult )
             {
                 LOG (DEBUG) << BOLDBLUE << "Modifying trigger multiplicity to be " << +(1+cTriggerMult) << " consecutive triggers per L1A for DataTest" << RESET;
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cTriggerMult);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cTriggerMult);
             }
             
             // using charge injection 
@@ -1492,12 +1510,12 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
                 static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(fTPconfig.firmwareTPdelay ,fTPconfig.tpDelay ,fTPconfig.tpSequence, fTPconfig.tpFastReset );
                 // set trigger latency 
                 uint16_t cLatency = fTPconfig.tpDelay+cLatencyOffset;//+1;
-                this->setSameDacBeBoard(cBoard, "TriggerLatency", cLatency);
+                this->setSameDacBeBoard(theBoard, "TriggerLatency", cLatency);
                 // set stub latency 
                 uint16_t cStubLatency = cLatency - 1*cStubDelay ;
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
                 LOG (DEBUG) << BOLDBLUE << "Latency set to " << +cLatency << "...\tStub latency set to " << +cStubLatency << RESET;
-                fBeBoardInterface->ChipReSync ( cBoard );
+                fBeBoardInterface->ChipReSync ( theBoard );
             }
             // read N events and compare hits and stubs to injected stub 
             for( size_t cAttempt=0; cAttempt < cAttempts ; cAttempt++)
@@ -1506,18 +1524,18 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
                 LOG (INFO) << BOLDBLUE << "Iteration# " << +fAttempt << RESET;
                 // send a resync
                 if( cResync)
-                    fBeBoardInterface->ChipReSync ( cBoard );
-                this->ReadNEvents ( cBoard , cEventsPerPoint);
-                this->matchEvents( cBoard , pChipIds ,cStub);
+                    fBeBoardInterface->ChipReSync ( theBoard );
+                this->ReadNEvents ( theBoard , cEventsPerPoint);
+                this->matchEvents( theBoard , pChipIds ,cStub);
                 this->print(pChipIds);
             }
             
 
             // and set it back to what it was 
             if( cConfigureTrigger )
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency", cBoardTriggerRate);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.user_trigger_frequency", cBoardTriggerRate);
             if( cConfigureTriggerMult )
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cBoardTriggerMult);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", cBoardTriggerMult);
         }
     //}
 
@@ -1533,33 +1551,40 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     //unmask all channels and reset offsets 
     // also re-configure thresholds + hit/stub detect logic to original values 
     // and re-load configuration of fast command block from register map loaded from xml file 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {   
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
         auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            auto& cThresholdsThisOpticalGroup = cThresholdsThisBoard->at(cOpticalGroup->getIndex());
+            auto& cLogicThisOpticalGroup = cLogicThisBoard->at(cOpticalGroup->getIndex());
+            auto& cHIPsThisOpticalGroup = cHIPsThisBoard->at(cOpticalGroup->getIndex());
+            for (auto cHybrid : *cOpticalGroup)
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                auto& cThresholdsThisHybrid = cThresholdsThisOpticalGroup->at(cOpticalGroup->getIndex());
+                auto& cLogicThisHybrid = cLogicThisOpticalGroup->at(cOpticalGroup->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisOpticalGroup->at(cOpticalGroup->getIndex());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for (auto cChip : *cHybrid)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+
+                    LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                }
             }
         }
         //
         LOG (DEBUG) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
+        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(static_cast<BeBoard*>(cBoard));
         //
         //fBeBoardInterface->ChipReSync ( cBoard );
     }
@@ -1581,21 +1606,24 @@ void DataChecker::L1Eye(std::vector<uint8_t> pChipIds )
         // zero container 
         zeroContainers();
         LOG (INFO) << BOLDBLUE << "Setting optimal phase tap in CIC to " << +cPhase << RESET;
-        for (auto cBoard : this->fBoardVector)
+        for (auto cBoard : *fDetectorContainer)
         {
-            for (auto& cFe : cBoard->fModuleVector)
+            for (auto cOpticalGroup : *cBoard)
             {
-                auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-                //fCicInterface->ResetPhaseAligner(cCic);
-                for(auto cChipId : pChipIds )
+                for (auto& cHybrid : *cOpticalGroup)
                 {
-                    bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
-                    // check if a resync is needed
-                    //fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cFe)->fCic); 
+                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                    //fCicInterface->ResetPhaseAligner(cCic);
+                    for(auto cChipId : pChipIds )
+                    {
+                        bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
+                        // check if a resync is needed
+                        //fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cHybrid)->fCic); 
+                    }
                 }
             }
             // send a resync
-            fBeBoardInterface->ChipReSync ( cBoard );
+            fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
             // re-do back-end alignment
             //cBackEndAligner.L1Alignment2S(cBoard);    
             std::this_thread::sleep_for (std::chrono::milliseconds (100) );
diff --git a/tools/Eudaq2Producer.cc b/tools/Eudaq2Producer.cc
index 2f9f3ba87..3a56037a8 100644
--- a/tools/Eudaq2Producer.cc
+++ b/tools/Eudaq2Producer.cc
@@ -69,15 +69,16 @@ void Eudaq2Producer::DoConfigure ()
   this->InitializeHw( fHWFile, outp);
   this->InitializeSettings( fHWFile, outp);
   LOG(INFO) << outp.str();
+  BeBoard *theFirstBoard = static_cast<BeBoard*>(fDetectorContainer->at(0));
 
   // configure hardware
   this->ConfigureHw();
-  fHandshakeEnabled = (this->fBeBoardInterface->ReadBoardReg(this->fBoardVector.at(0), "fc7_daq_cnfg.readout_block.global.data_handshake_enable") > 0);
-  fTriggerMultiplicity = this->fBeBoardInterface->ReadBoardReg(this->fBoardVector.at(0), "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
+  fHandshakeEnabled = (this->fBeBoardInterface->ReadBoardReg(theFirstBoard, "fc7_daq_cnfg.readout_block.global.data_handshake_enable") > 0);
+  fTriggerMultiplicity = this->fBeBoardInterface->ReadBoardReg(theFirstBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity");
 
   // now do cic alignment if needed
   // udtc does not support different front-end types that is why checking for only board 0 is enough
-  if (this->fBoardVector.at(0)->getFrontEndType() == FrontEndType::CIC) {
+  if (theFirstBoard->getFrontEndType() == FrontEndType::CIC) {
       //CIC FE alignment tool
       CicFEAlignment cCicAligner;
       cCicAligner.Inherit (this);
@@ -149,22 +150,22 @@ void Eudaq2Producer::DoStartRun()
   fRawPh2ACF = conf->Get("RawDataDirectory", "/tmp/" ) + "Run_" + std::to_string(cRunNumber) + ".raw"; 
   LOG (INFO) << BOLDBLUE << "Writing raw ph2_acf data to " << fRawPh2ACF << RESET;
  
-    auto cBoard = this->fBoardVector[0];
-    uint32_t cBeId = cBoard->getBeId();
+    BeBoard *theFirstBoard = static_cast<BeBoard*>(fDetectorContainer->at(0));
+    uint32_t cBeId = theFirstBoard->getId();
     uint32_t cNChip = 0;
     // this is hard coded now .. should figure out how to calculate this
     uint32_t cNEventSize32 = 80;//this->computeEventSize32 (cBoard);
     std::string cBoardTypeString;
-    BoardType cBoardType = cBoard->getBoardType();
-    for (const auto& cFe : cBoard->fModuleVector) cNChip += cFe->getNChip();
+    BoardType cBoardType = theFirstBoard->getBoardType();
+    for (const auto cHybrid : *theFirstBoard) cNChip += cHybrid->size();
       if (cBoardType == BoardType::D19C)
 	 cBoardTypeString = "D19C";
      else if (cBoardType != BoardType::RD53)
 	 cBoardTypeString = "FC7";
-     uint32_t cFWWord = fBeBoardInterface->getBoardInfo (cBoard);
+     uint32_t cFWWord = fBeBoardInterface->getBoardInfo (theFirstBoard);
      uint32_t cFWMajor = (cFWWord & 0xFFFF0000) >> 16;
      uint32_t cFWMinor = (cFWWord & 0x0000FFFF);
-     FileHeader cHeader (cBoardTypeString, cFWMajor, cFWMinor, cBeId, cNChip, cNEventSize32, cBoard->getEventType() );
+     FileHeader cHeader (cBoardTypeString, cFWMajor, cFWMinor, cBeId, cNChip, cNEventSize32, theFirstBoard->getEventType() );
 
  
   fPh2FileHandler = new FileHandler (fRawPh2ACF, 'w', cHeader);
@@ -174,15 +175,15 @@ void Eudaq2Producer::DoStartRun()
   
   // Ph2 object stuff 
   LOG (INFO) << BOLDBLUE << "Opening shutter ...." << RESET;
-  for(auto cBoard : this->fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
     //Start() also does CBC fast reset and readout reset 
-    this->fBeBoardInterface->Start(cBoard);
+    this->fBeBoardInterface->Start(static_cast<BeBoard*>(cBoard));
     LOG (INFO) << BOLDBLUE << "Shutter opened on board " << +cBoard->getId() << RESET;
   }
 
   LOG(INFO) << "Run Started, number of triggers received so far: " 
-    << +this->fBeBoardInterface->ReadBoardReg(this->fBoardVector.at(0), "fc7_daq_stat.fast_command_block.trigger_in_counter");
+    << +this->fBeBoardInterface->ReadBoardReg(theFirstBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter");
 
   // starting readout loop in thread
   fStarted = true, fStopped = false;
@@ -196,14 +197,14 @@ void Eudaq2Producer::DoStopRun()
   
   // Ph2ACF stuff
   LOG (INFO) << BOLDBLUE << "Closing shutter..." << RESET;
-  for(auto cBoard : this->fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
-    this->fBeBoardInterface->Stop(cBoard);
+    this->fBeBoardInterface->Stop(static_cast<BeBoard*>(cBoard));
     LOG (INFO) << BOLDBLUE << "Shutter closed on board " << +cBoard->getId() << RESET;
   }
 
   LOG(INFO) << "Run Stopped, number of triggers received so far: " 
-    << +this->fBeBoardInterface->ReadBoardReg(this->fBoardVector.at(0), "fc7_daq_stat.fast_command_block.trigger_in_counter"); 
+    << +this->fBeBoardInterface->ReadBoardReg(theFirstBoard, "fc7_daq_stat.fast_command_block.trigger_in_counter"); 
 
   fStarted = false, fStopped = true;
   if(fThreadRun.joinable())
@@ -230,9 +231,9 @@ void Eudaq2Producer::DoStopRun()
 void Eudaq2Producer::DoReset()
 {
     // just in case close the shutter
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-      fBeBoardInterface->Stop(cBoard);
+      this->fBeBoardInterface->Stop(static_cast<BeBoard*>(cBoard));
     }
 
     // finish data processing
@@ -267,9 +268,10 @@ void Eudaq2Producer::ReadoutLoop()
     if(!EventsPending()){
       continue;
     } 
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
-    	std::vector<uint32_t> cRawData(0); this->ReadData(cBoard, cRawData);
+      BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    	std::vector<uint32_t> cRawData(0); this->ReadData(theBoard, cRawData);
         // empty data - wait and pass
       	if( cRawData.size() == 0 )
       	{		
@@ -278,7 +280,7 @@ void Eudaq2Producer::ReadoutLoop()
            continue;
       	}
 	fPh2FileHandler->setData(cRawData);
-        std::vector<Event*> cPh2NewEvents = this->GetEvents(cBoard);
+        std::vector<Event*> cPh2NewEvents = this->GetEvents(theBoard);
         if (cPh2NewEvents.size() == 0 ) 
         {
            LOG (INFO) << BOLDBLUE << "Decoded 0 valid events.. not going to send anything ... " << RESET;
@@ -328,171 +330,188 @@ void Eudaq2Producer::ConvertToSubEvent(const BeBoard* pBoard, const Event* pPh2E
   // top bottom sensors
   uint32_t cSensorId = 0;
   // iterator for the module vector
-  std::vector<Module*>::const_iterator cFeIter = pBoard->fModuleVector.begin();
-  while(cFeIter < pBoard->fModuleVector.end()){
-  // make sure that we always start counting from the right hybrid (hybrid0 within the module)
-  uint32_t cFeId0 = (*cFeIter)->getFeId();
-  // build sensor id (one needs divide by two because 2 hybrids per module, but multiply by two because 2 sensors per hybrid)
-  cSensorId = (cFeId0 - (cFeId0 % 2));
-
-  // vectors to srore data
-  std::vector<uint8_t> top_channel_data;
-  std::vector<uint8_t> bottom_channel_data;
-  size_t top_offset = 0, bottom_offset = 0; 
-  std::vector<uint8_t> top_data_final(6);
-  std::vector<uint8_t> bottom_data_final(6);
-
-  // we have two hybrids (FE) per module therefore we iterate a bit here
-  uint32_t cIterRange = ( (cFeId0 % 2) == 0 ) ? 2 : 1; // now we also need to make sure that we starting from the right hybrid (0)
-  for(uint32_t i = 0; i < cIterRange; i++) 
+
+
+  for(auto cOpticalReadout : *pBoard)
   {
-    // get the current iterator
-    std::vector<Module*>::const_iterator cFeIterCurrent = cFeIter + i;
-    // check that we are still not at the end
-    if (cFeIterCurrent >= pBoard->fModuleVector.end()) continue;
-    // get the fe id
-    uint32_t cFeIdCurrent = (*cFeIterCurrent)->getFeId(); 
-
-    // parsing CBC data (CBC2 or CBC3)
-    // !!!!!!!!!!! Two uint8_t words per uint16_t, that is why all values are encoded by two
-    for ( auto cCbc : (*cFeIterCurrent)->fReadoutChipVector ) 
+    std::vector<Module*>::const_iterator cFeIter = cOpticalReadout->begin();
+    while(cFeIter < cOpticalReadout->end())
     {
-      int cChipId = (int)cCbc->getChipId();          
-      // adding this check here [sarah]
-      //std::string cCheck = pPh2Event->DataBitString( cCbc->getFeId() , cCbc->getChipId() );
-      //if( cCheck.empty() ) 
-      //	continue;
- 
-      const std::vector<uint32_t> cHitsVector = pPh2Event->GetHits(cCbc->getFeId(), cCbc->getChipId());
-      fHitsCounter += pPh2Event->GetNHits(cCbc->getFeId(), cCbc->getChipId());
-      for(auto hit : cHitsVector){
-
-        // LOG(INFO) << "FeIdCurrent: " << cFeIdCurrent << ", cbc: " << cChipId << ", hit id: " << hit;
-        if(hit%2 == 1)
+      // make sure that we always start counting from the right hybrid (hybrid0 within the module)
+      uint32_t cFeId0 = (*cFeIter)->getId();
+      // build sensor id (one needs divide by two because 2 hybrids per module, but multiply by two because 2 sensors per hybrid)
+      cSensorId = (cFeId0 - (cFeId0 % 2));
+
+      // vectors to srore data
+      std::vector<uint8_t> top_channel_data;
+      std::vector<uint8_t> bottom_channel_data;
+      size_t top_offset = 0, bottom_offset = 0; 
+      std::vector<uint8_t> top_data_final(6);
+      std::vector<uint8_t> bottom_data_final(6);
+
+      // we have two hybrids (FE) per module therefore we iterate a bit here
+      uint32_t cIterRange = ( (cFeId0 % 2) == 0 ) ? 2 : 1; // now we also need to make sure that we starting from the right hybrid (0)
+      for(uint32_t i = 0; i < cIterRange; i++) 
+      {
+        // get the current iterator
+        std::vector<Module*>::const_iterator cFeIterCurrent = cFeIter + i;
+        // check that we are still not at the end
+        if (cFeIterCurrent >= cOpticalReadout->end()) continue;
+        // get the fe id
+        uint32_t cFeIdCurrent = (*cFeIterCurrent)->getId(); 
+
+        // parsing CBC data (CBC2 or CBC3)
+        // !!!!!!!!!!! Two uint8_t words per uint16_t, that is why all values are encoded by two
+        for ( auto cCbc : *(*cFeIterCurrent) ) 
         {
-          uint32_t hit_pos = (cChipId*NCHANNELS/2) + (hit-1)/2;
-          if(cFeIdCurrent % 2 == 0) hit_pos = 1015 - hit_pos;
-          //top sensor
-          top_channel_data.resize(top_offset+6);
-          // row
-          top_channel_data[top_offset + 0] = (hit_pos >> 0) & 0xFF;
-          top_channel_data[top_offset + 1] = (hit_pos >> 8) & 0xFF;
-          // column
-          top_channel_data[top_offset + 2] = ((1 - (cFeIdCurrent % 2)) >> 0) & 0xFF;
-          top_channel_data[top_offset + 3] = ((1 - (cFeIdCurrent % 2)) >> 8) & 0xFF;
-          // tot (always 1)
-          top_channel_data[top_offset + 4] = 1;
-          top_channel_data[top_offset + 5] = 0;
-          // offset
-          top_offset += 6;
-          }else{
-          uint32_t hit_pos = (cChipId*NCHANNELS/2) + hit/2;
-          if(cFeIdCurrent % 2 == 0) hit_pos = 1015 - hit_pos;
-          //bottom sensor
-          bottom_channel_data.resize(bottom_offset+6);
-          // row
-          bottom_channel_data[bottom_offset + 0] = (hit_pos >> 0) & 0xFF;
-          bottom_channel_data[bottom_offset + 1] = (hit_pos >> 8) & 0xFF;
-          // column
-          bottom_channel_data[bottom_offset + 2] = ((1 - (cFeIdCurrent % 2)) >> 0) & 0xFF;
-          bottom_channel_data[bottom_offset + 3] = ((1 - (cFeIdCurrent % 2)) >> 8) & 0xFF;
-          // tot (always 1)
-          bottom_channel_data[bottom_offset + 4] = 1;
-          bottom_channel_data[bottom_offset + 5] = 0;
-          // offset
-          bottom_offset += 6;
-        }
-      }//end of hit loop
-    }//end of cCbc loop
-
-  } // end fe within a module loop loop
-
-  //// top sensor
-  // number of rows    
-  top_data_final[0] = (cNRows >> 0) & 0xFF;
-  top_data_final[1] = (cNRows >> 8) & 0xFF;
-  // number of rows
-  top_data_final[2] = 2;
-  top_data_final[3] = 0;
-  // number 
-  uint32_t numhits_top = (top_channel_data.size()) / 6;
-  top_data_final[4] = (numhits_top >> 0) & 0xFF;
-  top_data_final[5] = (numhits_top >> 8) & 0xFF;
-  // now append data
-  top_data_final.insert(top_data_final.end(), top_channel_data.begin(), top_channel_data.end());
-  // send
-  pEudaqSubEvent->AddBlock(cSensorId, top_data_final);
-
-  //// bottom sensor
-  // number of rows
-  bottom_data_final[0] = (cNRows >> 0) & 0xFF;
-  bottom_data_final[1] = (cNRows >> 8) & 0xFF;
-  // number of rows
-  bottom_data_final[2] = 2;
-  bottom_data_final[3] = 0;
-  // number 
-  uint32_t numhits_bottom = (bottom_channel_data.size()) / 6;
-  bottom_data_final[4] = (numhits_bottom >> 0) & 0xFF;
-  bottom_data_final[5] = (numhits_bottom >> 8) & 0xFF;
-  // now append data
-  bottom_data_final.insert(bottom_data_final.end(), bottom_channel_data.begin(), bottom_channel_data.end());
-  // send
-  pEudaqSubEvent->AddBlock(cSensorId + 1, bottom_data_final);
-
-  // now go to the next module
-  cFeIter += cIterRange;
-
-  }//end of cFe loop
+          int cChipId = (int)cCbc->getId();          
+          // adding this check here [sarah]
+          //std::string cCheck = pPh2Event->DataBitString( cCbc->getFeId() , cCbc->getChipId() );
+          //if( cCheck.empty() ) 
+          //	continue;
+    
+          const std::vector<uint32_t> cHitsVector = pPh2Event->GetHits((*cFeIterCurrent)->getId(), cCbc->getId());
+          fHitsCounter += pPh2Event->GetNHits((*cFeIterCurrent)->getId(), cCbc->getId());
+          for(auto hit : cHitsVector){
+
+            // LOG(INFO) << "FeIdCurrent: " << cFeIdCurrent << ", cbc: " << cChipId << ", hit id: " << hit;
+            if(hit%2 == 1)
+            {
+              uint32_t hit_pos = (cChipId*NCHANNELS/2) + (hit-1)/2;
+              if(cFeIdCurrent % 2 == 0) hit_pos = 1015 - hit_pos;
+              //top sensor
+              top_channel_data.resize(top_offset+6);
+              // row
+              top_channel_data[top_offset + 0] = (hit_pos >> 0) & 0xFF;
+              top_channel_data[top_offset + 1] = (hit_pos >> 8) & 0xFF;
+              // column
+              top_channel_data[top_offset + 2] = ((1 - (cFeIdCurrent % 2)) >> 0) & 0xFF;
+              top_channel_data[top_offset + 3] = ((1 - (cFeIdCurrent % 2)) >> 8) & 0xFF;
+              // tot (always 1)
+              top_channel_data[top_offset + 4] = 1;
+              top_channel_data[top_offset + 5] = 0;
+              // offset
+              top_offset += 6;
+              }else{
+              uint32_t hit_pos = (cChipId*NCHANNELS/2) + hit/2;
+              if(cFeIdCurrent % 2 == 0) hit_pos = 1015 - hit_pos;
+              //bottom sensor
+              bottom_channel_data.resize(bottom_offset+6);
+              // row
+              bottom_channel_data[bottom_offset + 0] = (hit_pos >> 0) & 0xFF;
+              bottom_channel_data[bottom_offset + 1] = (hit_pos >> 8) & 0xFF;
+              // column
+              bottom_channel_data[bottom_offset + 2] = ((1 - (cFeIdCurrent % 2)) >> 0) & 0xFF;
+              bottom_channel_data[bottom_offset + 3] = ((1 - (cFeIdCurrent % 2)) >> 8) & 0xFF;
+              // tot (always 1)
+              bottom_channel_data[bottom_offset + 4] = 1;
+              bottom_channel_data[bottom_offset + 5] = 0;
+              // offset
+              bottom_offset += 6;
+            }
+          }//end of hit loop
+        }//end of cCbc loop
+
+      } // end fe within a module loop loop
+
+      //// top sensor
+      // number of rows    
+      top_data_final[0] = (cNRows >> 0) & 0xFF;
+      top_data_final[1] = (cNRows >> 8) & 0xFF;
+      // number of rows
+      top_data_final[2] = 2;
+      top_data_final[3] = 0;
+      // number 
+      uint32_t numhits_top = (top_channel_data.size()) / 6;
+      top_data_final[4] = (numhits_top >> 0) & 0xFF;
+      top_data_final[5] = (numhits_top >> 8) & 0xFF;
+      // now append data
+      top_data_final.insert(top_data_final.end(), top_channel_data.begin(), top_channel_data.end());
+      // send
+      pEudaqSubEvent->AddBlock(cSensorId, top_data_final);
+
+      //// bottom sensor
+      // number of rows
+      bottom_data_final[0] = (cNRows >> 0) & 0xFF;
+      bottom_data_final[1] = (cNRows >> 8) & 0xFF;
+      // number of rows
+      bottom_data_final[2] = 2;
+      bottom_data_final[3] = 0;
+      // number 
+      uint32_t numhits_bottom = (bottom_channel_data.size()) / 6;
+      bottom_data_final[4] = (numhits_bottom >> 0) & 0xFF;
+      bottom_data_final[5] = (numhits_bottom >> 8) & 0xFF;
+      // now append data
+      bottom_data_final.insert(bottom_data_final.end(), bottom_channel_data.begin(), bottom_channel_data.end());
+      // send
+      pEudaqSubEvent->AddBlock(cSensorId + 1, bottom_data_final);
+
+      // now go to the next module
+      cFeIter += cIterRange;
+
+    }//end of cFe loop
+  }
   
-  for(auto cFe : pBoard->fModuleVector)
+  for(auto cOpticalReadout : *pBoard)
   {
-      char name[100];
-      auto cBxId = static_cast<const D19cCicEvent*>(pPh2Event)->BxId( cFe->getFeId() );
-      std::sprintf(name, "bx_ID_%02d", cFe->getFeId());
-      pEudaqSubEvent->SetTag(name, (uint32_t)cBxId);
-      auto cStatusBit = static_cast<const D19cCicEvent*>(pPh2Event)->Status( cFe->getFeId() );
-      std::sprintf(name, "status_%02d", cFe->getFeId());
-      pEudaqSubEvent->SetTag(name, (uint32_t)cStatusBit);
-      
-      for(auto cCbc : cFe->fReadoutChipVector)
-      {
-          char name[100];
-          uint32_t cFeId = cCbc->getFeId();
-          uint32_t cCbcId = cCbc->getChipId();
-          //auto cL1Id = static_cast<const D19cCicEvent*>(pPh2Event)->L1Id( cFe->getFeId(), cCbc->getChipId() );
-          std::sprintf(name, "pipeline_address_%02d_%02d", cFeId, cCbcId);
-          pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->PipelineAddress(cFeId, cCbcId));
-          std::sprintf(name, "error_%02d_%02d", cFeId, cCbcId);
-          pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->Error(cFeId, cCbcId));
-          //std::sprintf(name, "stubvec_size_%02d_%02d", cFeId, cCbcId);
-          //pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->StubVector(cFeId, cCbcId).size());
-          //std::sprintf(name, "l1_counter__%02d_%02d", cFeId, cCbcId);
-          //pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->GetEventCount(cFeId, cCbcId));
-          uint8_t cStubId = 0;
-          for(auto cStub : pPh2Event->StubVector(cFeId, cCbcId)){
-            std::sprintf(name, "stub_pos_%02d_%02d_%02d", cFeId, cCbcId, cStubId);
-            pEudaqSubEvent->SetTag(name, (uint32_t)cStub.getPosition());
-            std::sprintf(name, "stub_bend_%02d_%02d_%02d", cFeId, cCbcId, cStubId);
-            pEudaqSubEvent->SetTag(name, (uint32_t)cStub.getBend());
-
-            cStubId++;
-          }//end of cStub loop
-      }//end of cCbc loop
-  }//end of cFe loop
+    for(auto cHybrid : *cOpticalReadout)
+    {
+        char name[100];
+        auto cBxId = static_cast<const D19cCicEvent*>(pPh2Event)->BxId( cHybrid->getId() );
+        std::sprintf(name, "bx_ID_%02d", cHybrid->getId());
+        pEudaqSubEvent->SetTag(name, (uint32_t)cBxId);
+        auto cStatusBit = static_cast<const D19cCicEvent*>(pPh2Event)->Status( cHybrid->getId() );
+        std::sprintf(name, "status_%02d", cHybrid->getId());
+        pEudaqSubEvent->SetTag(name, (uint32_t)cStatusBit);
+        
+        for(auto cCbc : *cHybrid)
+        {
+            char name[100];
+            uint32_t cHybridId = cHybridId->getFeId();
+            uint32_t cCbcId = cCbc->getCId();
+            //auto cL1Id = static_cast<const D19cCicEvent*>(pPh2Event)->L1Id( cHybrid->getId(), cCbc->getCId() );
+            std::sprintf(name, "pipeline_address_%02d_%02d", cHybridId, cCbcId);
+            pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->PipelineAddress(cHybridId, cCbcId));
+            std::sprintf(name, "error_%02d_%02d", cHybridId, cCbcId);
+            pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->Error(cHybridId, cCbcId));
+            //std::sprintf(name, "stubvec_size_%02d_%02d", cHybridId, cCbcId);
+            //pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->StubVector(cHybridId, cCbcId).size());
+            //std::sprintf(name, "l1_counter__%02d_%02d", cHybridId, cCbcId);
+            //pEudaqSubEvent->SetTag(name, (uint32_t)pPh2Event->GetEventCount(cHybridId, cCbcId));
+            uint8_t cStubId = 0;
+            for(auto cStub : pPh2Event->StubVector(cHybridId, cCbcId)){
+              std::sprintf(name, "stub_pos_%02d_%02d_%02d", cHybridId, cCbcId, cStubId);
+              pEudaqSubEvent->SetTag(name, (uint32_t)cStub.getPosition());
+              std::sprintf(name, "stub_bend_%02d_%02d_%02d", cHybridId, cCbcId, cStubId);
+              pEudaqSubEvent->SetTag(name, (uint32_t)cStub.getBend());
+
+              cStubId++;
+            }//end of cStub loop
+        }//end of cCbc loop
+    }//end of cHybrid loop
+  }
 }
 
 bool Eudaq2Producer::EventsPending()
 {
-  if(fConfigured){
-    if(fHandshakeEnabled){
-      for(auto cBoard : this->fBoardVector){
-	if(cBoard->getBoardType() == BoardType::D19C){
-	  if(this->fBeBoardInterface->ReadBoardReg(cBoard, "fc7_daq_stat.readout_block.general.readout_req") > 0){
-	    return true; 
-	  }//end of if ReadBoardReg
-	}// end of if BoardType
-      }//end of cBoard loop
-    } else {
+  if(fConfigured)
+  {
+    if(fHandshakeEnabled)
+    {
+      for(auto cBoard : *fDetectorContainer)
+      {
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
+        if(theBoard->getBoardType() == BoardType::D19C)
+        {
+          if(this->fBeBoardInterface->ReadBoardReg(theBoard, "fc7_daq_stat.readout_block.general.readout_req") > 0)
+          {
+      	    return true; 
+          }//end of if ReadBoardReg
+        }// end of if BoardType
+      }//end of theBoard loop
+    } 
+    else 
+    {
         return true;
     }//end of if fHandshakeEnabled
 
diff --git a/tools/ExtraChecks.cc b/tools/ExtraChecks.cc
index 65ce42b69..5ee6a8eac 100644
--- a/tools/ExtraChecks.cc
+++ b/tools/ExtraChecks.cc
@@ -48,174 +48,177 @@ void ExtraChecks::Initialise ()
     #ifdef __USE_ROOT__
     //    fDQMHistogram.book(fResultFile,*fDetectorContainer);
     #endif
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            // histograms per cbc 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                TString cName = Form ( "h_BendCheck_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                // histograms per cbc 
+                for (auto& cChip : *cHybrid)
+                {
+                    TString cName = Form ( "h_BendCheck_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    TObject* cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj; 
+                    // occupancy
+                    cName = Form ( "h_Occupancy_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TH2D* cHist = new TH2D ( cName, Form("Occupancy CBC%d; Threshold [DAC units]; Number of hits",(int)cChip->getId()) , 1023 , 0-0.5 , 1023.-0.5 , NCHANNELS+10, 0-0.5 , 10+NCHANNELS-0.5 );
+                    bookHistogram ( static_cast<ReadoutChip*>(cChip), "Occupancy", cHist );  
+
+                    // error bits
+                    cName = Form ( "h_ErrorBits_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cHist = new TH2D ( cName, Form("Error Flag CBC%d; Event Id; Threshold [DAC units]; Error Bit",(int)cChip->getId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
+                    bookHistogram ( static_cast<ReadoutChip*>(cChip), "ErrorFlag", cHist );  
+                    
+                    // pipeline addrress
+                    cName = Form ( "h_Pipeline_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cHist = new TH2D ( cName, Form("Pipeline Address CBC%d; Event Id; Threshold [DAC units]; Pipeline Address",(int)cChip->getId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
+                    bookHistogram ( static_cast<ReadoutChip*>(cChip), "Pipeline", cHist );  
+                    // L1Id
+                    cName = Form ( "h_L1Id_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    cHist = new TH2D ( cName, Form("L1 Id CBC%d; Event Id; Threshold [DAC units]; L1 Id",(int)cChip->getId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
+                    bookHistogram ( static_cast<ReadoutChip*>(cChip), "L1", cHist );  
+
+                    cName = Form ( "h_PedeNoise_Fe%dCbc%d", cHybrid->getId() , cChip->getId() );
+                    cObj = gROOT->FindObject ( cName );
+                    if ( cObj ) delete cObj;
+                    TH1D* cHist1D = new TH1D ( cName, Form("Pedestal and noise - CBC%d; Channel; Pedestal and noise [DAC units]",(int)cChip->getId()) , NCHANNELS, 0 -0.5 , NCHANNELS -0.5 );
+                    bookHistogram ( static_cast<ReadoutChip*>(cChip), "PedeNoise", cHist1D );
+
+                }
+                // matched stubs 
+                TString cName = Form ( "h_MatchedStubs");
                 TObject* cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj; 
-                // occupancy
-                cName = Form ( "h_Occupancy_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                if ( cObj ) delete cObj;
+                TProfile* cProfile = new TProfile ( cName, Form("Number of matched stubs - CIC%d; CBC; Fraction of matched stubs",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                bookHistogram ( cHybrid , "MatchedStubs", cProfile );
+                // correct bend 
+                cName = Form ( "h_CorrectBend");
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                TH2D* cHist = new TH2D ( cName, Form("Occupancy CBC%d; Threshold [DAC units]; Number of hits",(int)cChip->getChipId()) , 1023 , 0-0.5 , 1023.-0.5 , NCHANNELS+10, 0-0.5 , 10+NCHANNELS-0.5 );
-                bookHistogram ( static_cast<ReadoutChip*>(cChip), "Occupancy", cHist );  
-
-                // error bits
-                cName = Form ( "h_ErrorBits_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                cProfile = new TProfile ( cName, Form("Fraction of events with correct bend - CIC%d; CBC; Fraction with correct bends",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                bookHistogram ( cHybrid , "CorrectBend", cProfile );
+                // wTP 
+                cName = Form ( "h_CorrectBend_TP");
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                cHist = new TH2D ( cName, Form("Error Flag CBC%d; Event Id; Threshold [DAC units]; Error Bit",(int)cChip->getChipId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
-                bookHistogram ( static_cast<ReadoutChip*>(cChip), "ErrorFlag", cHist );  
-                
-                // pipeline addrress
-                cName = Form ( "h_Pipeline_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                TProfile2D* cProf2D = new TProfile2D ( cName, Form("Fraction of events with correct bend - CIC%d; CBC; Stub Latency",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
+                bookHistogram ( cHybrid , "CorrectBend_TP", cProf2D );
+
+                // correct seed 
+                cName = Form ( "h_CorrectSeed");
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                cHist = new TH2D ( cName, Form("Pipeline Address CBC%d; Event Id; Threshold [DAC units]; Pipeline Address",(int)cChip->getChipId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
-                bookHistogram ( static_cast<ReadoutChip*>(cChip), "Pipeline", cHist );  
-                // L1Id
-                cName = Form ( "h_L1Id_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                cProfile = new TProfile ( cName, Form("Fraction of events with correct seed - CIC%d; CBC; Fraction with correct seed",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                bookHistogram ( cHybrid , "CorrectSeed", cProfile );
+                // wTP 
+                cName = Form ( "h_CorrectSeed_TP");
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                cHist = new TH2D ( cName, Form("L1 Id CBC%d; Event Id; Threshold [DAC units]; L1 Id",(int)cChip->getChipId()) , 200, 0 ,200, 1023 , 0-0.5 , 1023.-0.5 );
-                bookHistogram ( static_cast<ReadoutChip*>(cChip), "L1", cHist );  
+                cProf2D = new TProfile2D ( cName, Form("Fraction of events with correct seed - CIC%d; CBC; Stub Latency",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
+                bookHistogram ( cHybrid , "CorrectSeed_TP", cProf2D );
 
-                cName = Form ( "h_PedeNoise_Fe%dCbc%d", cFe->getFeId() , cChip->getChipId() );
+                // matched hits 
+                cName = Form ( "h_MatchedHits");
                 cObj = gROOT->FindObject ( cName );
                 if ( cObj ) delete cObj;
-                TH1D* cHist1D = new TH1D ( cName, Form("Pedestal and noise - CBC%d; Channel; Pedestal and noise [DAC units]",(int)cChip->getChipId()) , NCHANNELS, 0 -0.5 , NCHANNELS -0.5 );
-                bookHistogram ( static_cast<ReadoutChip*>(cChip), "PedeNoise", cHist1D );
+                cProfile = new TProfile ( cName, Form("Number of matched hits - CIC%d; CBC; Fraction of matched hits",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 );
+                bookHistogram ( cHybrid , "MatchedHits", cProfile );
 
-            }
-            // matched stubs 
-            TString cName = Form ( "h_MatchedStubs");
-            TObject* cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TProfile* cProfile = new TProfile ( cName, Form("Number of matched stubs - CIC%d; CBC; Fraction of matched stubs",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            bookHistogram ( cFe , "MatchedStubs", cProfile );
-            // correct bend 
-            cName = Form ( "h_CorrectBend");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cProfile = new TProfile ( cName, Form("Fraction of events with correct bend - CIC%d; CBC; Fraction with correct bends",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            bookHistogram ( cFe , "CorrectBend", cProfile );
-            // wTP 
-            cName = Form ( "h_CorrectBend_TP");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TProfile2D* cProf2D = new TProfile2D ( cName, Form("Fraction of events with correct bend - CIC%d; CBC; Stub Latency",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
-            bookHistogram ( cFe , "CorrectBend_TP", cProf2D );
+                // bunch crossing counters 
+                cName = Form("h_BunchCrossingCounter");
+                cObj = gROOT->FindObject( cName ) ;
+                if ( cObj ) delete cObj;
+                TH2D* cHist2D = new TH2D ( cName, Form("Number of matched stubs - CIC%d; Event Id; FE ASIC Id [CBC]",(int)cHybrid->getId()) , 1000 , 0 -0.5 , 1000 -0.5 , 8 , 0-0. , 8-0.5 );
+                bookHistogram ( cHybrid , "BxCounter", cHist2D );
+                // number of stubs
+                // wTP 
+                cName = Form ( "h_Nstubs_TP");
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cHist2D = new TProfile2D ( cName, Form("Number of stubs - CIC%d; CBC; Stub Latency",(int)cHybrid->getId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
+                bookHistogram ( cHybrid , "Nstubs_TP", cHist2D );
 
-            // correct seed 
-            cName = Form ( "h_CorrectSeed");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cProfile = new TProfile ( cName, Form("Fraction of events with correct seed - CIC%d; CBC; Fraction with correct seed",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            bookHistogram ( cFe , "CorrectSeed", cProfile );
-            // wTP 
-            cName = Form ( "h_CorrectSeed_TP");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cProf2D = new TProfile2D ( cName, Form("Fraction of events with correct seed - CIC%d; CBC; Stub Latency",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
-            bookHistogram ( cFe , "CorrectSeed_TP", cProf2D );
+                cName = Form ( "h_L1Status_Fe%d", cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cHist2D = new TH2D ( cName, Form("Error Flag CIC%d; Event Id; Chip Id; Error Bit",(int)cHybrid->getId()) , 1000, 0 , 1000 , 9, 0-0.5 , 9-0.5 );
+                bookHistogram ( cHybrid, "L1Status", cHist2D );  
+                
 
-            // matched hits 
-            cName = Form ( "h_MatchedHits");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cProfile = new TProfile ( cName, Form("Number of matched hits - CIC%d; CBC; Fraction of matched hits",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 );
-            bookHistogram ( cFe , "MatchedHits", cProfile );
+                cName = Form ( "h_NominalOccupancy_Fe%d", cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                TH1D* cHist = new TH1D ( cName, Form("Occupancy FE%d at nominal threshold; Number of hits",(int)cHybrid->getId()) , 10 + NCHANNELS*8, 0-0.5 , 10+ NCHANNELS*8-0.5 );
+                bookHistogram (cHybrid, "NominalOccupancy", cHist ); 
 
-            // bunch crossing counters 
-            cName = Form("h_BunchCrossingCounter");
-            cObj = gROOT->FindObject( cName ) ;
-            if ( cObj ) delete cObj;
-            TH2D* cHist2D = new TH2D ( cName, Form("Number of matched stubs - CIC%d; Event Id; FE ASIC Id [CBC]",(int)cFe->getFeId()) , 1000 , 0 -0.5 , 1000 -0.5 , 8 , 0-0. , 8-0.5 );
-            bookHistogram ( cFe , "BxCounter", cHist2D );
-            // number of stubs
-            // wTP 
-            cName = Form ( "h_Nstubs_TP");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TProfile2D ( cName, Form("Number of stubs - CIC%d; CBC; Stub Latency",(int)cFe->getFeId()) ,8  , 0 -0.5 , 8 -0.5 , 512,  0, 512 );
-            bookHistogram ( cFe , "Nstubs_TP", cHist2D );
+                cName = Form ( "h_hitMap_Fe%d",  cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cHist2D = new TH2D ( cName, Form("HitMap [FEH%d]; Strip Number; Number of Hits",(int)cHybrid->getId()) , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 , 2 , 0, 2);
+                cHist2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
+                cHist2D->GetYaxis()->SetBinLabel( 2 , "Top" );
+                bookHistogram ( cHybrid , "HitMap", cHist2D );
 
-            cName = Form ( "h_L1Status_Fe%d", cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("Error Flag CIC%d; Event Id; Chip Id; Error Bit",(int)cFe->getFeId()) , 1000, 0 , 1000 , 9, 0-0.5 , 9-0.5 );
-            bookHistogram ( cFe, "L1Status", cHist2D );  
-            
+                cName = Form ( "h_hitMap_BottomSensor_Fe%d",  cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cHist2D = new TH2D ( cName, Form("Hit Map Bottom Sensor [FEH%d]; Threshold [DAC units]; Strip Number; Number of Hits",(int)cHybrid->getId()) , 1023 , 0-0.5 , 1023.-0.5 , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 );
+                bookHistogram ( cHybrid , "HitMap_BottomSensor", cHist2D );
 
-            cName = Form ( "h_NominalOccupancy_Fe%d", cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TH1D* cHist = new TH1D ( cName, Form("Occupancy FE%d at nominal threshold; Number of hits",(int)cFe->getFeId()) , 10 + NCHANNELS*8, 0-0.5 , 10+ NCHANNELS*8-0.5 );
-            bookHistogram (cFe, "NominalOccupancy", cHist ); 
+                cName = Form ( "h_hitMap_TopSensor_Fe%d",  cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cHist2D = new TH2D ( cName, Form("Hit Map Top Sensor [FEH%d]; Threshold [DAC units]; Strip Number; Number of Hits",(int)cHybrid->getId()) , 1023 , 0-0.5 , 1023.-0.5 , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 );
+                bookHistogram ( cHybrid , "HitMap_TopSensor", cHist2D );
 
-            cName = Form ( "h_hitMap_Fe%d",  cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("HitMap [FEH%d]; Strip Number; Number of Hits",(int)cFe->getFeId()) , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 , 2 , 0, 2);
-            cHist2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
-            cHist2D->GetYaxis()->SetBinLabel( 2 , "Top" );
-            bookHistogram ( cFe , "HitMap", cHist2D );
+                // pedestal and noise
+                cName = Form ( "h_Pedestal_PerSide");
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                TProfile2D* cProfile2D = new TProfile2D ( cName, Form("Pedestal distribution [FEH%d]; Strip Number; Sensor Layer; Pedestal [DAC units]",(int)cHybrid->getId()) , 8*NCHANNELS/2  , 0 -0.5 , 8*NCHANNELS/2 -0.5 , 2 , 0  , 2);
+                cProfile2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
+                cProfile2D->GetYaxis()->SetBinLabel( 2 , "Top" );
+                bookHistogram ( cHybrid , "Pedestal_perSide", cProfile2D );
 
-            cName = Form ( "h_hitMap_BottomSensor_Fe%d",  cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("Hit Map Bottom Sensor [FEH%d]; Threshold [DAC units]; Strip Number; Number of Hits",(int)cFe->getFeId()) , 1023 , 0-0.5 , 1023.-0.5 , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 );
-            bookHistogram ( cFe , "HitMap_BottomSensor", cHist2D );
+                cName = Form ( "h_Noise_PerSide");
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cProfile2D = new TProfile2D ( cName, Form("Noise distribution [FEH%d]; Strip Number; Sensor Layer; Noise [DAC units]",(int)cHybrid->getId()) , 8*NCHANNELS/2  , 0 -0.5 , 8*NCHANNELS/2 -0.5 , 2 , 0  , 2);
+                bookHistogram ( cHybrid , "Noise_perSide", cProfile2D );
 
-            cName = Form ( "h_hitMap_TopSensor_Fe%d",  cFe->getFeId() );
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            cHist2D = new TH2D ( cName, Form("Hit Map Top Sensor [FEH%d]; Threshold [DAC units]; Strip Number; Number of Hits",(int)cFe->getFeId()) , 1023 , 0-0.5 , 1023.-0.5 , 8*NCHANNELS/2.  , 0 -0.5 , 8*NCHANNELS/2. -0.5 );
-            bookHistogram ( cFe , "HitMap_TopSensor", cHist2D );
+                cName = Form ( "h_Occupancy_Fe%d", cHybrid->getId() );
+                cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                cProfile2D = new TProfile2D ( cName, Form("Occupancy FE%d; Threshold [DAC units]; Number of strips with a hit",(int)cHybrid->getId()) , 1023 , 0-0.5 , 1023.-0.5 ,  2 , 0  , 2 , "S");
+                cProfile2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
+                cProfile2D->GetYaxis()->SetBinLabel( 2 , "Top" );
+                bookHistogram (cHybrid, "Occupancy_perSide", cProfile2D );  
 
-            // pedestal and noise
-            cName = Form ( "h_Pedestal_PerSide");
-            cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TProfile2D* cProfile2D = new TProfile2D ( cName, Form("Pedestal distribution [FEH%d]; Strip Number; Sensor Layer; Pedestal [DAC units]",(int)cFe->getFeId()) , 8*NCHANNELS/2  , 0 -0.5 , 8*NCHANNELS/2 -0.5 , 2 , 0  , 2);
-            cProfile2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
-            cProfile2D->GetYaxis()->SetBinLabel( 2 , "Top" );
-            bookHistogram ( cFe , "Pedestal_perSide", cProfile2D );
 
-            cName = Form ( "h_Noise_PerSide");
-            cObj = gROOT->FindObject ( cName );
+            }
+            // event counter
+            TString cName = Form ( "h_EventCount_Be%d", cBoard->getId()  );
+            TObject* cObj = gROOT->FindObject ( cName );
             if ( cObj ) delete cObj;
-            cProfile2D = new TProfile2D ( cName, Form("Noise distribution [FEH%d]; Strip Number; Sensor Layer; Noise [DAC units]",(int)cFe->getFeId()) , 8*NCHANNELS/2  , 0 -0.5 , 8*NCHANNELS/2 -0.5 , 2 , 0  , 2);
-            bookHistogram ( cFe , "Noise_perSide", cProfile2D );
+            TProfile* cProfile = new TProfile ( cName, Form("Received events BE Board%d; Threshold [DAC units]; Number of hits",(int)cBoard->getId()) , 1023 , 0-0.5 , 1023-0.5 );
+            bookHistogram ( cBoard , "ReadoutEvents", cProfile );  
 
-            cName = Form ( "h_Occupancy_Fe%d", cFe->getFeId() );
+            cName = Form ( "h_V1V5");
             cObj = gROOT->FindObject ( cName );
             if ( cObj ) delete cObj;
-            cProfile2D = new TProfile2D ( cName, Form("Occupancy FE%d; Threshold [DAC units]; Number of strips with a hit",(int)cFe->getFeId()) , 1023 , 0-0.5 , 1023.-0.5 ,  2 , 0  , 2 , "S");
-            cProfile2D->GetYaxis()->SetBinLabel( 1 , "Bottom" );
-            cProfile2D->GetYaxis()->SetBinLabel( 2 , "Top" );
-            bookHistogram (cFe, "Occupancy_perSide", cProfile2D );  
-
-
+            cProfile = new TProfile ( cName, Form("Measurement of 1V5 on SEH; Distance from pedestal; Corrected ADC reading [V]") , 100, -50 -0.5 , 50 - 0.5 ,"S");
+            bookHistogram ( cBoard , "Vmonitor1V5", cProfile );
+        
         }
-        // event counter
-        TString cName = Form ( "h_EventCount_Be%d", cBoard->getId()  );
-        TObject* cObj = gROOT->FindObject ( cName );
-        if ( cObj ) delete cObj;
-        TProfile* cProfile = new TProfile ( cName, Form("Received events BE Board%d; Threshold [DAC units]; Number of hits",(int)cBoard->getId()) , 1023 , 0-0.5 , 1023-0.5 );
-        bookHistogram ( cBoard , "ReadoutEvents", cProfile );  
-
-        cName = Form ( "h_V1V5");
-        cObj = gROOT->FindObject ( cName );
-        if ( cObj ) delete cObj;
-        cProfile = new TProfile ( cName, Form("Measurement of 1V5 on SEH; Distance from pedestal; Corrected ADC reading [V]") , 100, -50 -0.5 , 50 - 0.5 ,"S");
-        bookHistogram ( cBoard , "Vmonitor1V5", cProfile );
-    
     }
     //
     DetectorDataContainer         theOccupancyContainer;
@@ -224,29 +227,26 @@ void ExtraChecks::Initialise ()
 
     // read original thresholds from chips ... 
     fDetectorDataContainer = &fThresholds;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fThresholds);  
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fThresholds);  
     // read original logic configuration from chips .. [Pipe&StubInpSel&Ptwidth , HIP&TestMode]
     fDetectorDataContainer = &fLogic;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fLogic);  
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fLogic);  
     fDetectorDataContainer = &fHIPs;
-    ContainerFactory::copyAndInitStructure<uint16_t>(*fDetectorContainer, fHIPs);  
-    for (auto cBoard : this->fBoardVector)
+    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, fHIPs);  
+    for (auto cBoard : *fDetectorContainer)
     {
-        auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
-        auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
-        auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for (auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cHybrid : *cOpticalGroup)
             {
-                cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "VCth" );
-                cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "Pipe&StubInpSel&Ptwidth" );
-                cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "HIP&TestMode" );
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cHybrid->getLinkId());
+                //configure CBCs 
+                for (auto& cChip : *cHybrid)
+                {
+                    fThresholds.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(static_cast<ReadoutChip*>(cChip), "VCth");
+                    fLogic     .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(static_cast<ReadoutChip*>(cChip), "Pipe&StubInpSel&Ptwidth");
+                    fHIPs      .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(static_cast<ReadoutChip*>(cChip), "HIP&TestMode");
+                }
             }
         }
     }
@@ -254,24 +254,29 @@ void ExtraChecks::Initialise ()
     // for stub + hit data check 
     ContainerFactory::copyAndInitStructure<int>(*fDetectorContainer, fHitCheckContainer);
     ContainerFactory::copyAndInitStructure<int>(*fDetectorContainer, fStubCheckContainer);
-    for (auto cBoard : this->fBoardVector)
+    zeroContainers();
+
+}
+
+void ExtraChecks::zeroContainers()
+{
+    for (auto cBoard : *fDetectorContainer)
     {
-        auto& cHitCheck = fHitCheckContainer.at(cBoard->getIndex());
-        auto& cStubCheck = fStubCheckContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cHitCheckThisHybrid = cHitCheck->at(cFe->getIndex());
-            auto& cStubCheckThisHybrid = cStubCheck->at(cFe->getIndex());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                cHitCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
-                cStubCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
+                for ( auto cChip : *cHybrid )
+                {
+                    fHitCheckContainer .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<int>() = 0;
+                    fStubCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<int>() = 0;
+                }
             }
         }
     }
-
 }
 
+
 void ExtraChecks::writeObjects()
 {
     this->SaveResults();
@@ -315,19 +320,23 @@ void ExtraChecks::FindOpens()
         // get list of channels connected to this antenna .. 
         std::vector<uint16_t> cChannels{ 0, 10 , 100 }; // for now.. just make up a list ... 
         // now
+
         for( auto cLatency : cListOfLatencies)
         {
             LOG (INFO) << BOLDBLUE << "Latency value of " << +cLatency << RESET; 
-            for (auto cBoard : this->fBoardVector)
+            for (auto cBoard : *fDetectorContainer)
             {
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for ( auto cHybrid : *cOpticalGroup )
                     {
-                        for( auto cChannel : cChannels ) 
+                        for ( auto cChip : *cHybrid )
                         {
-                            auto& cOcc = cContainerVector.at( cContainerVector.size()-1)->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy;
-                            LOG (INFO) << "Found an occupancy of " << cOcc << " for channel " << +cChannel << " of CBC" << +cChip->getChipId() << " on FE" << +cFe->getFeId() << RESET;
+                            for( auto cChannel : cChannels ) 
+                            {
+                                auto& cOcc = cContainerVector.at( cContainerVector.size()-1)->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy;
+                                LOG (INFO) << "Found an occupancy of " << cOcc << " for channel " << +cChannel << " of CBC" << +cChip->getId() << " on FE" << +cHybrid->getId() << RESET;
+                            }
                         }
                     }
                 }
@@ -335,6 +344,7 @@ void ExtraChecks::FindOpens()
         }
     }
 }
+
 void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs)
 {
     // parse xml file 
@@ -348,23 +358,26 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
 
     LOG (INFO) << BOLDBLUE << "Quick [manual] check of noise and pedetal of the FE ASICs  ..." << RESET;
     uint16_t cDefaultStubLatency=50;
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for (auto cOpticalGroup : *cBoard)
         {
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                //enable stub logic
-                if( pDisableStubs ) 
+                //configure CBCs 
+                for (auto cChip : *cFe)
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, pDisableStubs , 0);
+                    //enable stub logic
+                    if( pDisableStubs ) 
+                    {
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, pDisableStubs , 0);
+                    }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true);
                 }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true);
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 
     // get trigger rate from xml
@@ -381,8 +394,9 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
     // extract pedestal and noise .. store in histogram
     ContainerFactory::copyAndInitChannel<float>(*fDetectorContainer, fNoiseContainer);
     ContainerFactory::copyAndInitChannel<float>(*fDetectorContainer, fPedestalContainer);
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         uint16_t cStart = 450; 
         uint16_t cMaxValue = 675; 
         uint16_t cStep=1; 
@@ -400,78 +414,81 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
             cContainerVector.emplace_back(new DetectorDataContainer());
             ContainerFactory::copyAndInitStructure<Occupancy>(*fDetectorContainer, *cContainerVector.back() ); 
             // set DAC .. read events
-            this->setSameDacBeBoard(cBoard, "VCth", cVcth);
+            this->setSameDacBeBoard(theBoard, "VCth", cVcth);
             for( size_t cIteration = 0 ; cIteration < cAttempts ; cIteration ++)
             {
                 //fBeBoardInterface->ChipReSync ( cBoard );
-                this->ReadNEvents ( cBoard , cNevents );
-                const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+                this->ReadNEvents ( theBoard , cNevents );
+                const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
                 if( cIteration == 0 && cStepCount%10 == 0 )
                 {
                     LOG (INFO) << BOLDBLUE << "Threshold set to " << cVcth << "...\tIteration " << +cIteration << " : " << +cEvents.size() << " events read back from fc7." << RESET;
                 }
                 
                 cEventHist->Fill( cVcth , (int)cEvents.size() );
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    TProfile2D* cHistOcc = static_cast<TProfile2D*> ( getHist ( cFe, "Occupancy_perSide" ) );
-                    TH2D* cHitMapBottom = static_cast<TProfile2D*> ( getHist ( cFe, "HitMap_BottomSensor" ) );
-                    TH2D* cHitMapTop = static_cast<TProfile2D*> ( getHist ( cFe, "HitMap_TopSensor" ) );
-
-                    std::vector<int> cHitCounterBottom(0);
-                    std::vector<int> cHitCounterTop(0);
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        int cNhits=0;
-                        LOG (DEBUG) << BOLDBLUE << "CBC" << +cChip->getChipId() << RESET;
-                        TH2D* cHist = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "Occupancy" ) );
-                        TH2D* cHistPipeline = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "Pipeline" ) );
-                        TH2D* cHistErrors = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "ErrorFlag" ) );
-                        TH2D* cHistL1Id = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "L1" ) );
-                        int cEventCounter=cIteration*cNevents;
-                        for( auto cEvent : cEvents ) 
+                        TProfile2D* cHistOcc = static_cast<TProfile2D*> ( getHist ( cFe, "Occupancy_perSide" ) );
+                        TH2D* cHitMapBottom = static_cast<TProfile2D*> ( getHist ( cFe, "HitMap_BottomSensor" ) );
+                        TH2D* cHitMapTop = static_cast<TProfile2D*> ( getHist ( cFe, "HitMap_TopSensor" ) );
+
+                        std::vector<int> cHitCounterBottom(0);
+                        std::vector<int> cHitCounterTop(0);
+                        for (auto& cChip : *cFe) 
                         {
-                            //debug information
-                            auto cEventCount = cEvent->GetEventCount(); 
-                            uint32_t cL1Id = cEvent->L1Id( cFe->getFeId(), cChip->getChipId() );
-                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
-                            uint32_t cError = cEvent->Error( cFe->getFeId() , cChip->getChipId() );
-                            uint32_t cStatus = static_cast<D19cCic2Event*>(cEvent)->Status( cFe->getFeId() );
-                            if( (cEventCount % 10) == 0 )
-                            {    
-                                LOG (DEBUG) << BOLDBLUE << "\t\t....Event " << +cEventCount << " ----  L1Id " << +cL1Id << " Pipeline address " << +cPipeline << " status bits from " << std::bitset<9>(cStatus) << RESET;
-                            }
-                            cHistPipeline->Fill( cEventCounter, cVcth, cPipeline);
-                            cHistErrors->Fill( cEventCounter, cVcth, 1+ cError);
-                            cHistL1Id->Fill( cEventCounter, cVcth , cL1Id);
-                            if( cError != 0 )
-                                LOG (INFO) << BOLDRED << "Event " << +cEventCounter << " : error in FE" << +cFe->getFeId() << " CBC" << +cChip->getChipId() << RESET;
-                            //hits
-                            std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getFeId(), cChip->getChipId()) ;
-                            cHist->Fill( cVcth , static_cast<int>(cHits.size()));
-                            for(auto cHit : cHits)
+                            int cNhits=0;
+                            LOG (DEBUG) << BOLDBLUE << "CBC" << +cChip->getId() << RESET;
+                            TH2D* cHist = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "Occupancy" ) );
+                            TH2D* cHistPipeline = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "Pipeline" ) );
+                            TH2D* cHistErrors = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "ErrorFlag" ) );
+                            TH2D* cHistL1Id = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "L1" ) );
+                            int cEventCounter=cIteration*cNevents;
+                            for( auto cEvent : cEvents ) 
                             {
-                                int cSensorChannel = std::floor(cHit/2.0) + cChip->getChipId()*127; 
-                                if (cHit%2==0)
-                                {
-                                    cHitCounterBottom.push_back(1);
-                                    cHitMapBottom->Fill( cVcth , cSensorChannel , 1 );
+                                //debug information
+                                auto cEventCount = cEvent->GetEventCount(); 
+                                uint32_t cL1Id = cEvent->L1Id( cFe->getId(), cChip->getId() );
+                                uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
+                                uint32_t cError = cEvent->Error( cFe->getId() , cChip->getId() );
+                                uint32_t cStatus = static_cast<D19cCic2Event*>(cEvent)->Status( cFe->getId() );
+                                if( (cEventCount % 10) == 0 )
+                                {    
+                                    LOG (DEBUG) << BOLDBLUE << "\t\t....Event " << +cEventCount << " ----  L1Id " << +cL1Id << " Pipeline address " << +cPipeline << " status bits from " << std::bitset<9>(cStatus) << RESET;
                                 }
-                                else
+                                cHistPipeline->Fill( cEventCounter, cVcth, cPipeline);
+                                cHistErrors->Fill( cEventCounter, cVcth, 1+ cError);
+                                cHistL1Id->Fill( cEventCounter, cVcth , cL1Id);
+                                if( cError != 0 )
+                                    LOG (INFO) << BOLDRED << "Event " << +cEventCounter << " : error in FE" << +cFe->getId() << " CBC" << +cChip->getId() << RESET;
+                                //hits
+                                std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getId(), cChip->getId()) ;
+                                cHist->Fill( cVcth , static_cast<int>(cHits.size()));
+                                for(auto cHit : cHits)
                                 {
-                                    cHitCounterTop.push_back(1);
-                                    cHitMapTop->Fill( cVcth , cSensorChannel , 1 );
+                                    int cSensorChannel = std::floor(cHit/2.0) + cChip->getId()*127; 
+                                    if (cHit%2==0)
+                                    {
+                                        cHitCounterBottom.push_back(1);
+                                        cHitMapBottom->Fill( cVcth , cSensorChannel , 1 );
+                                    }
+                                    else
+                                    {
+                                        cHitCounterTop.push_back(1);
+                                        cHitMapTop->Fill( cVcth , cSensorChannel , 1 );
+                                    }
+                                    cContainerVector.at( cContainerVector.size()-1)->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1;
+                                    cNhits+=1;
                                 }
-                                cContainerVector.at( cContainerVector.size()-1)->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cHit).fOccupancy += 1;
-                                cNhits+=1;
+                                cEventCounter++;
                             }
-                            cEventCounter++;
                         }
+                        float cMeanHits_Bottom = std::accumulate(cHitCounterBottom.begin(), cHitCounterBottom.end(), 0.)/cEvents.size();
+                        float cMeanHits_Top = std::accumulate(cHitCounterTop.begin(), cHitCounterTop.end(), 0.)/cEvents.size();
+                        cHistOcc->Fill(cVcth, 0. ,  cMeanHits_Bottom);
+                        cHistOcc->Fill(cVcth, 1. ,  cMeanHits_Top);
                     }
-                    float cMeanHits_Bottom = std::accumulate(cHitCounterBottom.begin(), cHitCounterBottom.end(), 0.)/cEvents.size();
-                    float cMeanHits_Top = std::accumulate(cHitCounterTop.begin(), cHitCounterTop.end(), 0.)/cEvents.size();
-                    cHistOcc->Fill(cVcth, 0. ,  cMeanHits_Bottom);
-                    cHistOcc->Fill(cVcth, 1. ,  cMeanHits_Top);
                 }
             }
             cStepCount++;
@@ -480,56 +497,60 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
         // process result of threshold scan to obtain pedestal and noise 
         auto& cThisNoiseContainer = fNoiseContainer.at(cBoard->getIndex());
         auto& cThisPedestalContiner = fPedestalContainer.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            TProfile2D* cPedestalHist = static_cast<TProfile2D*> ( getHist (  static_cast<OuterTrackerModule*>(cFe) , "Pedestal_perSide" ) );  
-            TProfile2D* cNoiseHist = static_cast<TProfile2D*> ( getHist (  static_cast<OuterTrackerModule*>(cFe) , "Noise_perSide" ) );  
-                    
-            LOG (DEBUG) << BOLDBLUE << "FE" << +cFe->getFeId() << RESET;
-            auto& cHybridNoise = cThisNoiseContainer->at(cFe->getIndex());
-            auto& cHybridPedestal = cThisPedestalContiner->at(cFe->getIndex());  
-            size_t cIter=0;
-
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cFe : *cOpticalGroup)
             {
-                auto& cReadoutChipNoise = cHybridNoise->at(cChip->getIndex());
-                auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
-                for(uint8_t cChannel=0; cChannel < NCHANNELS; cChannel++)
+                TProfile2D* cPedestalHist = static_cast<TProfile2D*> ( getHist (  static_cast<OuterTrackerModule*>(cFe) , "Pedestal_perSide" ) );  
+                TProfile2D* cNoiseHist = static_cast<TProfile2D*> ( getHist (  static_cast<OuterTrackerModule*>(cFe) , "Noise_perSide" ) );  
+                        
+                LOG (DEBUG) << BOLDBLUE << "FE" << +cFe->getId() << RESET;
+                auto& cHybridNoise = cThisNoiseContainer->at(cOpticalGroup->getIndex())->at(cFe->getIndex());
+                auto& cHybridPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex());  
+                size_t cIter=0;
+
+                for (auto cChip : *cFe) 
                 {
-                    std::vector<float> cTmp(cListOfThresholds.size(), 0);
-                    cIter=0;
-                    for(auto& cDetectorContainer : cContainerVector ) 
+                    auto& cReadoutChipNoise = cHybridNoise->at(cChip->getIndex());
+                    auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
+                    for(uint8_t cChannel=0; cChannel < NCHANNELS; cChannel++)
                     {
-                        cTmp[cIter] = cDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy; 
-                        cDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy = 0; 
-                        cIter++;
+                        std::vector<float> cTmp(cListOfThresholds.size(), 0);
+                        cIter=0;
+                        for(auto& cDetectorContainer : cContainerVector ) 
+                        {
+                            cTmp[cIter] = cDetectorContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy; 
+                            cDetectorContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy = 0; 
+                            cIter++;
+                        }
+                        std::pair<float,float> cNoiseEval = evalNoise( cTmp, cListOfThresholds);
+                        cReadoutChipPedestal->getChannelContainer<float>()->at(cChannel)=cNoiseEval.first;
+                        cReadoutChipNoise->getChannelContainer<float>()->at(cChannel)=cNoiseEval.second;
+                        LOG (DEBUG) << BOLDBLUE << "\t\t... Channel" << +cChannel << " : pedestal is " << cNoiseEval.first << " and noise is " << cNoiseEval.second << RESET;
+                        TH1D* cHist = static_cast<TH1D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "PedeNoise" ) );
+                        cHist->SetBinContent( cHist->GetXaxis()->FindBin( cChannel) , cNoiseEval.first);
+                        cHist->SetBinError( cHist->GetXaxis()->FindBin( cChannel), cNoiseEval.second );
+                        cTmp.clear();
+
+                        int cSensorChannel = std::floor(cChannel/2.0) + cChip->getId()*127; 
+                        cPedestalHist->Fill( cSensorChannel , (cChannel%2 == 0) ?  0 : 1 ,  cNoiseEval.first);
+                        cNoiseHist->Fill( cSensorChannel , (cChannel%2 == 0) ?  0 : 1 ,  cNoiseEval.second);
                     }
-                    std::pair<float,float> cNoiseEval = evalNoise( cTmp, cListOfThresholds);
-                    cReadoutChipPedestal->getChannelContainer<float>()->at(cChannel)=cNoiseEval.first;
-                    cReadoutChipNoise->getChannelContainer<float>()->at(cChannel)=cNoiseEval.second;
-                    LOG (DEBUG) << BOLDBLUE << "\t\t... Channel" << +cChannel << " : pedestal is " << cNoiseEval.first << " and noise is " << cNoiseEval.second << RESET;
-                    TH1D* cHist = static_cast<TH1D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "PedeNoise" ) );
-                    cHist->SetBinContent( cHist->GetXaxis()->FindBin( cChannel) , cNoiseEval.first);
-                    cHist->SetBinError( cHist->GetXaxis()->FindBin( cChannel), cNoiseEval.second );
-                    cTmp.clear();
-
-                    int cSensorChannel = std::floor(cChannel/2.0) + cChip->getChipId()*127; 
-                    cPedestalHist->Fill( cSensorChannel , (cChannel%2 == 0) ?  0 : 1 ,  cNoiseEval.first);
-                    cNoiseHist->Fill( cSensorChannel , (cChannel%2 == 0) ?  0 : 1 ,  cNoiseEval.second);
+                    auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
+                    auto cNoise = cReadoutChipNoise->getChannelContainer<float>();
+                    float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
+                    float cMeanNoise = std::accumulate( cNoise->begin(), cNoise->end(), 0.)/cNoise->size();
+                    // set noise to 3 sigma away from pedesata; 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", cMeanPedestal - pSigma*cMeanNoise);
+                    LOG (INFO) << BOLDBLUE << "\tCBC" << +cChip->getId() << " : mean pedestal is " << cMeanPedestal << " and mean noise is " << cMeanNoise << " : setting threshold to " << cMeanPedestal - pSigma*cMeanNoise << RESET;
                 }
-                auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
-                auto cNoise = cReadoutChipNoise->getChannelContainer<float>();
-                float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
-                float cMeanNoise = std::accumulate( cNoise->begin(), cNoise->end(), 0.)/cNoise->size();
-                // set noise to 3 sigma away from pedesata; 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", cMeanPedestal - pSigma*cMeanNoise);
-                LOG (INFO) << BOLDBLUE << "\tCBC" << +cChip->getChipId() << " : mean pedestal is " << cMeanPedestal << " and mean noise is " << cMeanNoise << " : setting threshold to " << cMeanPedestal - pSigma*cMeanNoise << RESET;
             }
         }
         cContainerVector.clear();
     }
     // to be included ---- automatic readout of current consumption 
 }
+
 void ExtraChecks::OccupancyCheck(uint16_t pTriggerRate, bool pDisableStubs)
 {
     auto cSetting = fSettingsMap.find ( "Nevents" );
@@ -537,64 +558,71 @@ void ExtraChecks::OccupancyCheck(uint16_t pTriggerRate, bool pDisableStubs)
     
     LOG (INFO) << BOLDBLUE << "Quick [manual] check of noise and pedetal of the FE ASICs  ..." << RESET;
     uint16_t cDefaultStubLatency=50;
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for (auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                //enable stub logic
-                if( pDisableStubs ) 
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                //configure CBCs 
+                for (auto cChip : *cFe)
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, pDisableStubs , 0);
+                    //enable stub logic
+                    if( pDisableStubs ) 
+                    {
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, pDisableStubs , 0);
+                    }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true);
                 }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true);
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 
     //measure hit occupancy - look for correlations
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,pTriggerRate,3,0,cDefaultStubLatency);
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         LOG (INFO) << BOLDBLUE << "Measuring hit correlations..." << RESET;
         for( size_t cIteration = 0 ; cIteration < 100 ; cIteration ++)
         {
             LOG (INFO) << BOLDBLUE << "Iteration : " << +cIteration << RESET;
-            this->ReadNEvents ( cBoard , cNevents );
-            const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
-            for (auto& cFe : cBoard->fModuleVector)
+            this->ReadNEvents ( theBoard , cNevents );
+            const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+            for(auto cOpticalGroup : *cBoard)
             {
-                TH2D* cHitMap = static_cast<TH2D*> ( getHist ( cFe, "HitMap" ) ); 
-                TH1D* cHitOccupancy = static_cast<TH1D*> ( getHist ( cFe, "NominalOccupancy" ) ); 
-                
-                std::vector<int> cModuleOccupancy(0);
-                for( auto cEvent : cEvents ) 
+                for (auto cFe : *cOpticalGroup)
                 {
-                    std::vector<uint32_t> cHitDummy(0);
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    TH2D* cHitMap = static_cast<TH2D*> ( getHist ( cFe, "HitMap" ) ); 
+                    TH1D* cHitOccupancy = static_cast<TH1D*> ( getHist ( cFe, "NominalOccupancy" ) ); 
+                    
+                    std::vector<int> cModuleOccupancy(0);
+                    for( auto cEvent : cEvents ) 
                     {
-                        std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getFeId(), cChip->getChipId()) ;
-                        auto cCbcId = cChip->getChipId();
-                        std::transform(cHits.begin(), cHits.end(), cHits.begin(), [cCbcId](int c){return cCbcId*254 + c;});
-                        cHitDummy.insert( cHitDummy.end(), cHits.begin(), cHits.end() );
-                        for( auto cHit : cHits )
+                        std::vector<uint32_t> cHitDummy(0);
+                        for (auto cChip : *cFe) 
                         {
-                            int cSensorChannel = std::floor(cHit/2.0) + cChip->getChipId()*127; 
-                            cHitMap->Fill( cSensorChannel , (cHit%2 == 0) ?  0 : 1 , 1);
+                            std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getId(), cChip->getId()) ;
+                            auto cCbcId = cChip->getId();
+                            std::transform(cHits.begin(), cHits.end(), cHits.begin(), [cCbcId](int c){return cCbcId*254 + c;});
+                            cHitDummy.insert( cHitDummy.end(), cHits.begin(), cHits.end() );
+                            for( auto cHit : cHits )
+                            {
+                                int cSensorChannel = std::floor(cHit/2.0) + cChip->getId()*127; 
+                                cHitMap->Fill( cSensorChannel , (cHit%2 == 0) ?  0 : 1 , 1);
+                            }
                         }
+                        cModuleOccupancy.push_back( cHitDummy.size() );
+                        cHitOccupancy->Fill(cHitDummy.size());
                     }
-                    cModuleOccupancy.push_back( cHitDummy.size() );
-                    cHitOccupancy->Fill(cHitDummy.size());
+                    float cMeanOccupancy = std::accumulate( cModuleOccupancy.begin(), cModuleOccupancy.end(), 0.)/cModuleOccupancy.size();
+                    char cBuffer[200];
+                    std::sprintf (cBuffer, "\tModule occupancy found to be %.2e for FE%d", cMeanOccupancy/(cFe->size()*NCHANNELS) , cFe->getId() );
+                    LOG (INFO) << BOLDBLUE << cBuffer << RESET;
                 }
-                float cMeanOccupancy = std::accumulate( cModuleOccupancy.begin(), cModuleOccupancy.end(), 0.)/cModuleOccupancy.size();
-                char cBuffer[200];
-                std::sprintf (cBuffer, "\tModule occupancy found to be %.2e for FE%d", cMeanOccupancy/(cFe->fReadoutChipVector.size()*NCHANNELS) , cFe->getFeId() );
-                LOG (INFO) << BOLDBLUE << cBuffer << RESET;
             }
         }
     }
@@ -605,45 +633,49 @@ void ExtraChecks::ExternalTriggers(uint16_t pNconsecutive, const std::string& pS
     uint32_t cNevents = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
     std::stringstream outp;
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,10,4,0);
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // configure trigger 
         if( pSource == "TLU")
         {
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source", 4);
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.tlu_block.tlu_enabled", 1);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source", 4);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.tlu_block.tlu_enabled", 1);
         }
         else
         {
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source", 5);
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.tlu_block.tlu_enabled", 0);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source", 5);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.tlu_block.tlu_enabled", 0);
         }
-        fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", pNconsecutive);
+        fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.misc.trigger_multiplicity", pNconsecutive);
         
         LOG (INFO) << BOLDRED << "Opening shutter ... press any key to close .." << RESET;
-        fBeBoardInterface->Start(cBoard);
+        fBeBoardInterface->Start(theBoard);
         do
         {
             std::this_thread::sleep_for (std::chrono::milliseconds (10) );
         }while( std::cin.get()!='\n');
-        fBeBoardInterface->Stop(cBoard);
+        fBeBoardInterface->Stop(theBoard);
         
         LOG (INFO) << BOLDBLUE << "Stopping triggers..." << RESET;
-        this->ReadData( cBoard , true);
-        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+        this->ReadData( theBoard , true);
+        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
         LOG (INFO) << BOLDBLUE << +cEvents.size() << " events read back from FC7 with ReadData" << RESET;
-        for (auto& cFe : cBoard->fModuleVector)
+        for (auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cFe : *cOpticalGroup)
             {
-                for( auto cEvent : cEvents ) 
+                for (auto& cChip : *cFe) 
                 {
-                    uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
-                    auto cEventCount = cEvent->GetEventCount(); 
-                    //uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getFeId(), cChip->getChipId() );
-                    LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << "\t\t....CBC" << +cChip->getChipId() << " on FE" << +cFe->getFeId() << " ----  Pipeline address " << +cPipeline << RESET;
+                    for( auto cEvent : cEvents ) 
+                    {
+                        uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
+                        auto cEventCount = cEvent->GetEventCount(); 
+                        //uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getId(), cChip->getId() );
+                        LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << "\t\t....CBC" << +cChip->getId() << " on FE" << +cFe->getId() << " ----  Pipeline address " << +cPipeline << RESET;
+                    }
+                    LOG (INFO) << RESET;
                 }
-                LOG (INFO) << RESET;
             }
         }
     }
@@ -658,61 +690,70 @@ void ExtraChecks::ConsecutiveTriggers(uint8_t pNconsecutive)
     //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,10,3,0);
     //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureConsecutiveTriggerFSM( cNevents, 0 , 0 );
     LOG (INFO) << BOLDBLUE << "Going to try and send " << +cNevents << " consecutive triggers to FE" << RESET;
-    for(auto cBoard : this->fBoardVector)
+    for(auto cBoard : *fDetectorContainer)
     {
         // set threshold 
-        this->setSameDacBeBoard(cBoard, "VCth", 582);
-        for (auto& cFe : cBoard->fModuleVector)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        this->setSameDacBeBoard(theBoard, "VCth", 582);
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cFe : *cOpticalGroup)
             {
-                if( cChip->getChipId() == 0 )
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", 100);       
-                static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {100,150} , {0,0}, true );
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                for (auto cChip : *cFe) 
+                {
+                    if( cChip->getId() == 0 )
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", 100);       
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( static_cast<ReadoutChip*>(cChip) , {100,150} , {0,0}, true );
+                }
             }
         }
         //  
-        fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.data_handshake_enable", 0x0);
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.data_handshake_enable", 0x0);
+        fBeBoardInterface->ChipReSync ( theBoard );
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ResetReadout();
         for( size_t cIndex=0; cIndex < cNevents; cIndex++)
         {
             static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Trigger(pNconsecutive);
             std::this_thread::sleep_for (std::chrono::milliseconds (100) );
         }
-        this->ReadData( cBoard , true);
+        this->ReadData( theBoard , true);
         
-        // //fBeBoardInterface->Start(cBoard);
+        // //fBeBoardInterface->Start(theBoard);
         //std::this_thread::sleep_for (std::chrono::seconds (20) );
-        //fBeBoardInterface->Stop(cBoard);
-        //this->ReadData( cBoard , true);
-        //this->ReadNEvents ( cBoard , cNevents );
-        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+        //fBeBoardInterface->Stop(theBoard);
+        //this->ReadData( theBoard , true);
+        //this->ReadNEvents ( theBoard , cNevents );
+        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
         LOG (INFO) << BOLDBLUE << +cEvents.size() << " events read back from FC7 with ReadData" << RESET;
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cFe : *cOpticalGroup)
             {
-                for( auto cEvent : cEvents ) 
+                for (auto cChip : *cFe) 
                 {
-                    uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
-                    auto cEventCount = cEvent->GetEventCount(); 
-                    LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << "\t\t....CBC" << +cChip->getChipId() << " on FE" << +cFe->getFeId() << " ----  Pipeline address " << +cPipeline << RESET;
-                    //uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getFeId(), cChip->getChipId() );
-                    //LOG (INFO) << "Event " << +cEventCount << "\t\t....CBC " << +cChip->getChipId() << "on FE" << +cFe->getFeId() << " ----  Pipeline address " << +cPipeline << RESET;
+                    for( auto cEvent : cEvents ) 
+                    {
+                        uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
+                        auto cEventCount = cEvent->GetEventCount(); 
+                        LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << "\t\t....CBC" << +cChip->getId() << " on FE" << +cFe->getId() << " ----  Pipeline address " << +cPipeline << RESET;
+                        //uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getId(), cChip->getId() );
+                        //LOG (INFO) << "Event " << +cEventCount << "\t\t....CBC " << +cChip->getId() << "on FE" << +cFe->getId() << " ----  Pipeline address " << +cPipeline << RESET;
+                    }
+                    LOG (INFO) << RESET;
                 }
-                LOG (INFO) << RESET;
             }
         }
     }
     LOG (INFO) << BOLDBLUE << "Done!" << RESET;
     
 }
+
 void ExtraChecks::MonitorAmux(bool pAll)
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // get result of pedestal and noise 
         auto& cThisNoiseContainer = fNoiseContainer.at(cBoard->getIndex());
         auto& cThisPedestalContiner = fPedestalContainer.at(cBoard->getIndex());
@@ -728,46 +769,50 @@ void ExtraChecks::MonitorAmux(bool pAll)
             for(auto cThresholdValue : cThresholdValues)
             {
                 // set DAC 
-                this->setSameDacBeBoard(cBoard, "VCth", cThresholdValue);
+                this->setSameDacBeBoard(theBoard, "VCth", cThresholdValue);
                 LOG (INFO) << BOLDBLUE << "Threshold on all chips set to " << +cThresholdValue << " DAC units..." << RESET;
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
-                    TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
-                    TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        std::vector<float> cValues(0);
-                        for( size_t cIter=0; cIter<5; cIter++)
+                        TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
+                        TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
+                        TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
+                        for (auto cChip : *cFe) 
                         {
-                            std::pair<uint16_t,float> cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VCth", cBoard->ifOptical() );
-                            cValues.push_back(cReading.second);
-                            cScan->Fill( cChip->getChipId() , cThresholdValue , cReading.second );
-                            //
-                            // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBGbias", cBoard->ifOptical() );
-                            // cScanVBGbias->Fill( cChip->getChipId() , cThresholdValue , cReading.second );
-                            // //
-                            // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBG_LDO", cBoard->ifOptical() );
-                            // cScanVBGldo->Fill( cChip->getChipId() , cThresholdValue , cReading.second );
-                        }
-                        std::pair<float,float> cStats = getStats(cValues);
-                        LOG (INFO) << BOLDBLUE << "\tFE" << + cFe->getFeId() << "\t...CBC" << +cChip->getChipId() << " : " << cStats.first << " [ " << cStats.second << " ]" << RESET;        
-                    } 
+                            std::vector<float> cValues(0);
+                            for( size_t cIter=0; cIter<5; cIter++)
+                            {
+                                std::pair<uint16_t,float> cReading = ReadAmux(cFe->getId(), cChip->getId() , "VCth", theBoard->ifOptical() );
+                                cValues.push_back(cReading.second);
+                                cScan->Fill( cChip->getId() , cThresholdValue , cReading.second );
+                                //
+                                // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBGbias", theBoard->ifOptical() );
+                                // cScanVBGbias->Fill( cChip->getId() , cThresholdValue , cReading.second );
+                                // //
+                                // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBG_LDO", theBoard->ifOptical() );
+                                // cScanVBGldo->Fill( cChip->getId() , cThresholdValue , cReading.second );
+                            }
+                            std::pair<float,float> cStats = getStats(cValues);
+                            LOG (INFO) << BOLDBLUE << "\tFE" << + cFe->getId() << "\t...CBC" << +cChip->getId() << " : " << cStats.first << " [ " << cStats.second << " ]" << RESET;        
+                        } 
+                    }
                 }
             }
             // fixed distances 
             for( int cDistance = -20 ; cDistance <= 20 ; cDistance++)
             {
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    auto& cHybridPedestal = cThisPedestalContiner->at(cFe->getIndex());  
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
-                        auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
-                        float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
-                        uint16_t cThreshold = static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance));
-                        static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", cThreshold);
+                        for (auto cChip : *cFe) 
+                        {
+                            auto cPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<float>();
+                            float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
+                            uint16_t cThreshold = static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance));
+                            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", cThreshold);
+                        }
                     }
                 }
                 // measure 
@@ -780,34 +825,37 @@ void ExtraChecks::MonitorAmux(bool pAll)
                 }
                 std::pair<float,float> cMonitor = getStats( cMonitorVoltage );
                 LOG (INFO) << BOLDBLUE << "Threshold on all chips set to " << +cDistance << " DAC units away from the pedestal; Vmonitor [1.5V] on SEH reads " <<  cMonitor.first << " V (" << cMonitor.second*1e3 << " mV)" << RESET;
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    auto& cHybridPedestal = cThisPedestalContiner->at(cFe->getIndex());  
-                    TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
-                    TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
-                    TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
-                        auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
-                        float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
-                        uint16_t cThreshold = static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance));
-                        std::vector<float> cValues(0);
-                        for( size_t cIter=0; cIter<5; cIter++)
+                        auto& cHybridPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex());  
+                        TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
+                        TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
+                        TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
+                        for (auto cChip : *cFe) 
                         {
-                            std::pair<uint16_t,float> cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VCth", cBoard->ifOptical() );
-                            cValues.push_back(cReading.second);
-                            cScan->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                            //
-                            // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBGbias", cBoard->ifOptical() );
-                            // cScanVBGbias->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                            // //
-                            // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBG_LDO", cBoard->ifOptical() );
-                            // cScanVBGldo->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                        
-                        }   
-                        std::pair<float,float> cStats = getStats(cValues);
-                        LOG (INFO) << BOLDBLUE << "\tFE" << + cFe->getFeId() << "\t...CBC" << +cChip->getChipId() << " : " << cStats.first << " [ " << cStats.second << " ]" << RESET;        
+                            auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
+                            auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
+                            float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
+                            uint16_t cThreshold = static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance));
+                            std::vector<float> cValues(0);
+                            for( size_t cIter=0; cIter<5; cIter++)
+                            {
+                                std::pair<uint16_t,float> cReading = ReadAmux(cFe->getId(), cChip->getId() , "VCth", theBoard->ifOptical() );
+                                cValues.push_back(cReading.second);
+                                cScan->Fill( cChip->getId() , cThreshold , cReading.second );
+                                //
+                                // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBGbias", theBoard->ifOptical() );
+                                // cScanVBGbias->Fill( cChip->getId() , cThreshold , cReading.second );
+                                // //
+                                // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBG_LDO", theBoard->ifOptical() );
+                                // cScanVBGldo->Fill( cChip->getId() , cThreshold , cReading.second );
+                            
+                            }   
+                            std::pair<float,float> cStats = getStats(cValues);
+                            LOG (INFO) << BOLDBLUE << "\tFE" << + cFe->getId() << "\t...CBC" << +cChip->getId() << " : " << cStats.first << " [ " << cStats.second << " ]" << RESET;        
+                        }
                     }
                 }
             }
@@ -815,71 +863,74 @@ void ExtraChecks::MonitorAmux(bool pAll)
         else
         {
             LOG (INFO) << BOLDBLUE << "Scanning threshold on one chip at a time - and recording AMUX voltages..." << RESET;
-            for (auto& cFe : cBoard->fModuleVector)
+            for (auto cOpticalGroup : *cBoard)
             {
-                LOG (INFO) << BOLDBLUE << "FE" << +cFe->getFeId() << RESET;
-                auto& cHybridPedestal = cThisPedestalContiner->at(cFe->getIndex());  
-                LOG (INFO) << BOLDBLUE << "Scanning threshold on chips [one at a time] - and recording AMUX voltages..." << RESET;
-                TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan_perChip" ) );
-                TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan_perChip" ) );
-                TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan_perChip" ) );
-                for(uint8_t cChipIndex=0; cChipIndex < cFe->fReadoutChipVector.size(); cChipIndex++)
+                for (auto cFe : *cOpticalGroup)
                 {
-                    auto& cReadoutChipPedestal = cHybridPedestal->at(cChipIndex);
-                    auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
-                    float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
-                    LOG (INFO) << BOLDBLUE << "\tCBC" << +cChipIndex << " : mean pedestal is " << cMeanPedestal <<  RESET;
-                    // set threshold on all CBCs except the one being scanned to 0 
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    LOG (INFO) << BOLDBLUE << "FE" << +cFe->getId() << RESET;
+                    auto& cHybridPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex());  
+                    LOG (INFO) << BOLDBLUE << "Scanning threshold on chips [one at a time] - and recording AMUX voltages..." << RESET;
+                    TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan_perChip" ) );
+                    TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan_perChip" ) );
+                    TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan_perChip" ) );
+                    for(uint8_t cChipIndex=0; cChipIndex < cFe->size(); cChipIndex++)
                     {
-                        if( cChip->getIndex() == cChipIndex ) 
-                            continue;
-                        static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(0));
-                    }
-                    
-                    // now scan thereshold on one of the CBCs 
-                    for (auto& cChip : cFe->fReadoutChipVector) 
-                    {
-                        if( cChip->getIndex() != cChipIndex ) 
-                            continue;
-                        // fixed values 
-                        std::vector<float> cThresholdValues{0., 50., 900. , 1000.};
-                        for(auto cThreshold : cThresholdValues)
+                        auto& cReadoutChipPedestal = cHybridPedestal->at(cChipIndex);
+                        auto cPedestal = cReadoutChipPedestal->getChannelContainer<float>();
+                        float cMeanPedestal = std::accumulate( cPedestal->begin(), cPedestal->end(), 0.)/cPedestal->size();
+                        LOG (INFO) << BOLDBLUE << "\tCBC" << +cChipIndex << " : mean pedestal is " << cMeanPedestal <<  RESET;
+                        // set threshold on all CBCs except the one being scanned to 0 
+                        for (auto cChip : *cFe) 
                         {
-                            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(cThreshold));
-                            for( size_t cIter=0; cIter<5; cIter++)
+                            if( cChip->getIndex() == cChipIndex ) 
+                                continue;
+                            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(0));
+                        }
+                        
+                        // now scan thereshold on one of the CBCs 
+                        for (auto cChip : *cFe) 
+                        {
+                            if( cChip->getIndex() != cChipIndex ) 
+                                continue;
+                            // fixed values 
+                            std::vector<float> cThresholdValues{0., 50., 900. , 1000.};
+                            for(auto cThreshold : cThresholdValues)
                             {
+                                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(cThreshold));
+                                for( size_t cIter=0; cIter<5; cIter++)
+                                {
+                                    
+                                    std::pair<uint16_t,float> cReading = ReadAmux(cFe->getId(), cChip->getId() , "VCth", theBoard->ifOptical() );
+                                    cScan->Fill( cChip->getId() , cThreshold , cReading.second );
+                                    if(( cChip->getIndex() == cChipIndex ) && cIter == 0 ) 
+                                        LOG (INFO) << BOLDBLUE << "\t\t.... Setting threshold to " << +static_cast<uint16_t>(cThreshold) << " and recording voltage at output of AMUX : " << cReading.second << RESET;
+                                    
+                                    
+                                    // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBGbias", cBoard->ifOptical() );
+                                    // cScanVBGbias->Fill( cChip->getId() , cThreshold , cReading.second );
+                                    // //
+                                    // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBG_LDO", cBoard->ifOptical() );
+                                    // cScanVBGldo->Fill( cChip->getId() , cThreshold , cReading.second );
                                 
-                                std::pair<uint16_t,float> cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VCth", cBoard->ifOptical() );
-                                cScan->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                                if(( cChip->getIndex() == cChipIndex ) && cIter == 0 ) 
-                                    LOG (INFO) << BOLDBLUE << "\t\t.... Setting threshold to " << +static_cast<uint16_t>(cThreshold) << " and recording voltage at output of AMUX : " << cReading.second << RESET;
-                                
-                                
-                                // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBGbias", cBoard->ifOptical() );
-                                // cScanVBGbias->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                                // //
-                                // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBG_LDO", cBoard->ifOptical() );
-                                // cScanVBGldo->Fill( cChip->getChipId() , cThreshold , cReading.second );
-                            
+                                }
                             }
-                        }
-                        // near the pedestal 
-                        for( int cDistance = -10 ; cDistance <= 10 ; cDistance++)
-                        {
-                            static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance)) );
-                            for( size_t cIter=0; cIter<5; cIter++)
+                            // near the pedestal 
+                            for( int cDistance = -10 ; cDistance <= 10 ; cDistance++)
                             {
-                                std::pair<uint16_t,float> cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VCth", cBoard->ifOptical() );
-                                cScan->Fill( cChip->getChipId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
-                                if(( cChip->getIndex() == cChipIndex ) && cIter == 0 ) 
-                                    LOG (INFO) << BOLDBLUE << "\t\t.... Setting threshold to " << +static_cast<uint16_t>(cMeanPedestal + cDistance) << " and recording voltage at output of AMUX : " << cReading.second << " mV." << RESET;
-                                //bias
-                                // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBGbias", cBoard->ifOptical() );
-                                // cScanVBGbias->Fill( cChip->getChipId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
-                                // //ldo
-                                // cReading = ReadAmux(cFe->getFeId(), cChip->getChipId() , "VBGbias", cBoard->ifOptical() );
-                                // cScanVBGldo->Fill( cChip->getChipId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
+                                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "VCth", static_cast<uint16_t>(std::floor(cMeanPedestal + cDistance)) );
+                                for( size_t cIter=0; cIter<5; cIter++)
+                                {
+                                    std::pair<uint16_t,float> cReading = ReadAmux(cFe->getId(), cChip->getId() , "VCth", theBoard->ifOptical() );
+                                    cScan->Fill( cChip->getId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
+                                    if(( cChip->getIndex() == cChipIndex ) && cIter == 0 ) 
+                                        LOG (INFO) << BOLDBLUE << "\t\t.... Setting threshold to " << +static_cast<uint16_t>(cMeanPedestal + cDistance) << " and recording voltage at output of AMUX : " << cReading.second << " mV." << RESET;
+                                    //bias
+                                    // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBGbias", cBoard->ifOptical() );
+                                    // cScanVBGbias->Fill( cChip->getId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
+                                    // //ldo
+                                    // cReading = ReadAmux(cFe->getId(), cChip->getId() , "VBGbias", cBoard->ifOptical() );
+                                    // cScanVBGldo->Fill( cChip->getId() , std::floor(cMeanPedestal + cDistance) , cReading.second );
+                                }
                             }
                         }
                     }
@@ -929,7 +980,7 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
             static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
             for (auto& cChip : cFe->fReadoutChipVector)
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) != pChipIds.end()  ) 
+                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
                 {
                     static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , cSeeds , cBends, false );
                     for( size_t cIndex=0; cIndex < cSeeds.size(); cIndex++)
@@ -999,14 +1050,14 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
                     //debug information
                     for( auto cEvent : cEvents ) 
                     { 
-                        auto cBxId = cEvent->BxId(cFe->getFeId());
+                        auto cBxId = cEvent->BxId(cFe->getId());
                         auto cEventCount = cEvent->GetEventCount(); 
                         LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << " - BxId - " << +cBxId <<  RESET; 
                     }
                     int cNmatchedHits=0;
                     for (auto& cChip : cFe->fReadoutChipVector) 
                     {
-                        if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) == pChipIds.end()  ) 
+                        if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end()  ) 
                             continue;
                         
                         int cNstubsCBC=0;
@@ -1014,9 +1065,9 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
                         for( auto cEvent : cEvents ) 
                         {
                             //debug information
-                            uint32_t cL1Id =  cEvent->L1Id( cFe->getFeId(), cChip->getChipId() );
-                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
-                            auto cHits = cEvent->GetHits( cFe->getFeId(), cChip->getChipId() ) ;
+                            uint32_t cL1Id =  cEvent->L1Id( cFe->getId(), cChip->getId() );
+                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
+                            auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
                             for( auto cHit : cHits ) 
                             {
                                 if( std::find(  cExpectedHits.begin(), cExpectedHits.end(), cHit) != cExpectedHits.end() ) 
@@ -1025,24 +1076,24 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
                                 }
                             }
 
-                            auto cStubs = cEvent->StubVector( cFe->getFeId(), cChip->getChipId() );
+                            auto cStubs = cEvent->StubVector( cFe->getId(), cChip->getId() );
                             for( auto cStub : cStubs )
                             {
-                                cMatchedSeeds->Fill( cChip->getChipId() , cDelay - cStubLatency, cStub.getPosition() == cSeeds[0] );
-                                cMatchedBends->Fill( cChip->getChipId() , cDelay - cStubLatency , cStub.getBend() == pBendCode );
+                                cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, cStub.getPosition() == cSeeds[0] );
+                                cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency , cStub.getBend() == pBendCode );
                                 LOG (DEBUG) << BOLDMAGENTA << "Stub with seed " << +cStub.getPosition() << " with bend " << +cStub.getBend() << RESET;
                             }
                             if( cStubs.size() == 0 ) 
                             {
-                                cMatchedBends->Fill( cChip->getChipId() , cDelay - cStubLatency, 0 );
-                                cMatchedSeeds->Fill( cChip->getChipId() , cDelay - cStubLatency, 0 );
+                                cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
+                                cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
                             }
                             cNstubs+= cStubs.size();
                             cNstubsCBC += cStubs.size();
                         }
-                        cStubsFound->Fill( cChip->getChipId(), cDelay - cStubLatency, cNstubsCBC );
+                        cStubsFound->Fill( cChip->getId(), cDelay - cStubLatency, cNstubsCBC );
                     }
-                    LOG (INFO) << BOLDBLUE << "Stub latency of " << +cStubLatency << " FE" << +cFe->getFeId() << " : " << cNstubs << " stubs and " << +cNmatchedHits << " matched hits." << RESET;
+                    LOG (INFO) << BOLDBLUE << "Stub latency of " << +cStubLatency << " FE" << +cFe->getId() << " : " << cNstubs << " stubs and " << +cNmatchedHits << " matched hits." << RESET;
                 }
             }
         }
@@ -1073,7 +1124,7 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
                 fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
                 fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
 
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
                 static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
                 static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
                 static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
@@ -1087,6 +1138,7 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
     }
 
 }
+
 void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t pStep)
 {
     // settings for TP trigger
@@ -1110,17 +1162,18 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(cFirmwareTPdelay,cFirmwareTriggerDelay,1000);
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
     // check that the hits are there... so find test pulse
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         //this->setSameDacBeBoard(cBoard, "TestPulseGroup", pGroup);
         uint16_t cMinValue=0;
-        int cDelayAfterTPfastCommand = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
+        int cDelayAfterTPfastCommand = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         for( int cSamplingTime = 50 ; cSamplingTime <= 75 ; cSamplingTime += static_cast<int>(pStep) )
         {
             uint16_t cTriggerLatency = static_cast<uint16_t>(cDelayAfterTPfastCommand - std::floor(cSamplingTime/25.) );
             int cTPdelay = -1*cSamplingTime + 25 - 25*(cTriggerLatency-cDelayAfterTPfastCommand);   
-            this->setSameDacBeBoard(cBoard, "TriggerLatency", cTriggerLatency);
-            this->setSameDacBeBoard(cBoard, "TestPulseDelay", cTPdelay);
+            this->setSameDacBeBoard(theBoard, "TriggerLatency", cTriggerLatency);
+            this->setSameDacBeBoard(theBoard, "TestPulseDelay", cTPdelay);
             LOG (INFO) << BOLDMAGENTA << "Starting threshold scan : Latency set to " << +cTriggerLatency << " TP delay set to " << cTPdelay <<  RESET;
             
             // bitwise scan 
@@ -1133,11 +1186,11 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
             // // now find the pedestal 
             // for (auto& cFe : cBoard->fModuleVector)
             // {
-            //     LOG (INFO) << BOLDBLUE << "FE" << +cFe->getFeId() << RESET;
+            //     LOG (INFO) << BOLDBLUE << "FE" << +cFe->getId() << RESET;
             //     for (auto& cChip : cFe->fReadoutChipVector) 
             //     {
             //         uint16_t cThreshold = cChip->getReg("VCth1") + (  cChip->getReg("VCth2")<<8 );
-            //         LOG (INFO) << BOLDGREEN << "\t...Vcth on CBC" << +cChip->getChipId() << " found to be : " << cThreshold << " Vcth units." << RESET;
+            //         LOG (INFO) << BOLDGREEN << "\t...Vcth on CBC" << +cChip->getId() << " found to be : " << cThreshold << " Vcth units." << RESET;
             //         // for(ChannelDataContainer<Occupancy>::iterator cChannel =  cChip->begin<Occupancy>(); cChannel != cChip->end<Occupancy>(); cChannel++, cIndex++)
             //         // {
             //         //     auto& cOccupancy = cChannel->fOccupancy;
@@ -1161,7 +1214,7 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
                 cContainerVector.emplace_back(new DetectorDataContainer());
                 ContainerFactory::copyAndInitStructure<Occupancy>(*fDetectorContainer, *cContainerVector.back() ); 
                 //do scan 
-                this->setSameDacBeBoard(cBoard , cDacName, cListOfThresholds.at(cIndex));
+                this->setSameDacBeBoard(theBoard , cDacName, cListOfThresholds.at(cIndex));
                 fDetectorDataContainer = cContainerVector.at( cContainerVector.size()-1);
                 measureBeBoardData( cBoard->getIndex(), cEventsPerPoint);
                 // look at result 
@@ -1169,27 +1222,30 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
                 LOG (INFO) << BOLDMAGENTA << "\t\t...Scanning " << cDacName << " to reconstruct TP - threshold now set to " << cListOfThresholds.at(cIndex) << RESET;
                 //" found average occupancy on chip0 to be : " << cExample.fOccupancy << RESET;
             }
-            for (auto& cFe : cBoard->fModuleVector)
+            for(auto cOpticalGroup : *cBoard)
             {
-                LOG (INFO) << BOLDBLUE << "FE" << +cFe->getFeId() << RESET;
-                for (auto& cChip : cFe->fReadoutChipVector) 
+                for (auto cFe : *cOpticalGroup)
                 {
-                    for(uint8_t cChannel=0; cChannel < NCHANNELS; cChannel++)
+                    LOG (INFO) << BOLDBLUE << "FE" << +cFe->getId() << RESET;
+                    for (auto& cChip : *cFe) 
                     {
-                        std::vector<float> cTmp(cListOfThresholds.size(), 0);
-                        std::vector<float> cValues(cListOfThresholds.size(),0);
-                        size_t cIter=0;
-                        for(auto& cDetectorContainer : cContainerVector ) 
+                        for(uint8_t cChannel=0; cChannel < NCHANNELS; cChannel++)
                         {
-                            cTmp[cIter] = cDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy; 
-                            cValues[cIter] = static_cast<float>(cListOfThresholds[cIter]);
-                            cDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy = 0; 
-                            cIter++;
+                            std::vector<float> cTmp(cListOfThresholds.size(), 0);
+                            std::vector<float> cValues(cListOfThresholds.size(),0);
+                            size_t cIter=0;
+                            for(auto& cDetectorContainer : cContainerVector ) 
+                            {
+                                cTmp[cIter] = cDetectorContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy; 
+                                cValues[cIter] = static_cast<float>(cListOfThresholds[cIter]);
+                                cDetectorContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getChannelContainer<Occupancy>()->at(cChannel).fOccupancy = 0; 
+                                cIter++;
+                            }
+                            std::pair<float,float> cNoiseEval = this->evalNoise( cTmp, cValues);
+                            if( cChannel%5 == 0 && cChip->getId() == 0 ) 
+                                LOG (INFO) << BOLDBLUE << "Chip" << +cChip->getId()  << " T = " << 0 << " - Channel" << +cChannel << " : pedestal is " << cNoiseEval.first << " and noise is " << cNoiseEval.second << RESET;
+                            cTmp.clear();
                         }
-                        std::pair<float,float> cNoiseEval = this->evalNoise( cTmp, cValues);
-                        if( cChannel%5 == 0 && cChip->getChipId() == 0 ) 
-                            LOG (INFO) << BOLDBLUE << "Chip" << +cChip->getChipId()  << " T = " << 0 << " - Channel" << +cChannel << " : pedestal is " << cNoiseEval.first << " and noise is " << cNoiseEval.second << RESET;
-                        cTmp.clear();
                     }
                 }
             }
@@ -1211,45 +1267,52 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
 
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for ( auto cChip : *cHybrid )
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( theChip, "HitOr", 0);
+                    //enable stub logic
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( theChip, "Sampled", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( theChip, false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 
     // generate stubs in exactly N chip(s)
     size_t cSeedIndex=0;
     uint8_t cBendCode = 0x00;
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) != pChipIds.end()  ) 
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for (auto& cChip : *cHybrid)
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {pSeed} , {pBend}, true );
-                    // read bend LUT
-                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                    cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                    LOG (INFO ) << BOLDBLUE << "Injecting a stub in position " << +pSeed << " with bend " << pBend << " --- bend code is 0x" << std::hex << +cBendCode << std::dec << RESET;
-                }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
-            } 
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
+                    {
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {pSeed} , {pBend}, true );
+                        // read bend LUT
+                        std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                        cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                        LOG (INFO ) << BOLDBLUE << "Injecting a stub in position " << +pSeed << " with bend " << pBend << " --- bend code is 0x" << std::hex << +cBendCode << std::dec << RESET;
+                    }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
+                } 
+            }
         }
     }
 
@@ -1257,75 +1320,79 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,pTriggerRate,3,0,cDefaultStubLatency);
     // in theory can scan over this .. but 3 is the right number
     
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
 
-        auto cStubPackageDelay = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.physical_interface_block.cic.stub_package_delay") ;
+        auto cStubPackageDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.physical_interface_block.cic.stub_package_delay") ;
         LOG (INFO) << BOLDBLUE << "Stub package delay to " << +cStubPackageDelay << RESET;
     
-        //uint16_t cDelay = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
+        //uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         // why do I need this?
-        //this->setSameDacBeBoard(cBoard, "TriggerLatency", cDelay);
-        this->ReadNEvents ( cBoard , cEventsPerPoint );
-        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
-        for (auto& cFe : cBoard->fModuleVector)
+        //this->setSameDacBeBoard(theBoard, "TriggerLatency", cDelay);
+        this->ReadNEvents ( theBoard , cEventsPerPoint );
+        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto cFeId  = cFe->getFeId();
-            LOG (INFO) << BOLDBLUE << "Link Id : " << +cFe->getLinkId() << RESET;
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            TH2D* cBxCounter = static_cast<TH2D*> ( getHist ( cFe, "BxCounter" ) );
-            TProfile* cMatchedStubs = static_cast<TProfile*> ( getHist ( cFe, "MatchedStubs" ) );
-            TProfile* cMatchedHits = static_cast<TProfile*> ( getHist ( cFe, "MatchedHits" ) );
-            TProfile* cMatchedBends = static_cast<TProfile*> ( getHist ( cFe, "CorrectBend" ) );
-            TProfile* cMatchedSeeds = static_cast<TProfile*> ( getHist ( cFe, "CorrectSeed" ) );
-            for (auto& cChip : cFe->fReadoutChipVector) 
+            for (auto cFe : *cOpticalGroup)
             {
-                auto cChipId  = cChip->getChipId();
-                
-                //if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end()  ) 
-                //    continue;
-                int cNhits=0;
-                LOG (INFO) << BOLDBLUE << "\t.. CBC" << +cChipId << RESET;
-                int cEventCounter=0;
-                for( auto cEvent : cEvents ) 
+                auto cFeId  = cFe->getId();
+                LOG (INFO) << BOLDBLUE << "Link Id : " << +static_cast<OuterTrackerModule*>(cFe)->getLinkId() << RESET;
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                TH2D* cBxCounter = static_cast<TH2D*> ( getHist ( cFe, "BxCounter" ) );
+                TProfile* cMatchedStubs = static_cast<TProfile*> ( getHist ( cFe, "MatchedStubs" ) );
+                TProfile* cMatchedHits = static_cast<TProfile*> ( getHist ( cFe, "MatchedHits" ) );
+                TProfile* cMatchedBends = static_cast<TProfile*> ( getHist ( cFe, "CorrectBend" ) );
+                TProfile* cMatchedSeeds = static_cast<TProfile*> ( getHist ( cFe, "CorrectSeed" ) );
+                for (auto cChip : *cFe) 
                 {
-                    //debug information
-                    auto cBxId = cEvent->BxId(cFeId );
-                    auto cEventCount = cEvent->GetEventCount(); 
-                    uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                    uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
-                    LOG (INFO) << BOLDBLUE << "\t\t... Event " << +cEventCount << " FE" << +cFeId << " - Bx " << +cBxId  << RESET;
-                    
-                    cBxCounter->Fill( static_cast<float>(cEventCount) , cChipId , cBxId );
-                    //hits
-                    auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
-                    for( auto cHit : cHits )
-                    {
-                        LOG (DEBUG) << BOLDMAGENTA << "\t\t... hit found in channel " << +cHit << RESET; 
-                    }
-                    cNhits += cHits.size();
-                    // std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, pSeed, pBend ); 
-                    // for( auto cExpectedHit : cExpectedHits ) 
-                    // {
-                    //     cMatchedHits->Fill( cChipId , std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end() ) ;
-                    // }
-                    // if( cHits.size() == 0 )
-                    //     cMatchedHits->Fill( cChipId , 0);
+                    auto cChipId  = cChip->getId();
                     
-                    auto cStubs = cEvent->StubVector( cFeId, cChipId );
-                    for( auto cStub : cStubs ) 
-                    {
-                        LOG (INFO) << BOLDMAGENTA << "\t\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << RESET; 
-                        cMatchedStubs->Fill(  cChipId , cStub.getPosition() == pSeed && cStub.getBend() == cBendCode );
-                        cMatchedBends->Fill( cChipId , cStub.getBend() == cBendCode  );
-                        cMatchedSeeds->Fill( cChipId , cStub.getPosition() == pSeed );
-                    }
-                    cEventCounter++;
-                    if( cStubs.size() == 0 ) 
+                    //if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end()  ) 
+                    //    continue;
+                    int cNhits=0;
+                    LOG (INFO) << BOLDBLUE << "\t.. CBC" << +cChipId << RESET;
+                    int cEventCounter=0;
+                    for( auto cEvent : cEvents ) 
                     {
-                        cMatchedBends->Fill( cChipId , 0 );
-                        cMatchedSeeds->Fill( cChipId , 0 );
-                        cMatchedStubs->Fill( cChipId , 0 );
+                        //debug information
+                        auto cBxId = cEvent->BxId(cFeId );
+                        auto cEventCount = cEvent->GetEventCount(); 
+                        uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
+                        uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
+                        LOG (INFO) << BOLDBLUE << "\t\t... Event " << +cEventCount << " FE" << +cFeId << " - Bx " << +cBxId  << RESET;
+                        
+                        cBxCounter->Fill( static_cast<float>(cEventCount) , cChipId , cBxId );
+                        //hits
+                        auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
+                        for( auto cHit : cHits )
+                        {
+                            LOG (DEBUG) << BOLDMAGENTA << "\t\t... hit found in channel " << +cHit << RESET; 
+                        }
+                        cNhits += cHits.size();
+                        // std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, pSeed, pBend ); 
+                        // for( auto cExpectedHit : cExpectedHits ) 
+                        // {
+                        //     cMatchedHits->Fill( cChipId , std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end() ) ;
+                        // }
+                        // if( cHits.size() == 0 )
+                        //     cMatchedHits->Fill( cChipId , 0);
+                        
+                        auto cStubs = cEvent->StubVector( cFeId, cChipId );
+                        for( auto cStub : cStubs ) 
+                        {
+                            LOG (INFO) << BOLDMAGENTA << "\t\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << RESET; 
+                            cMatchedStubs->Fill(  cChipId , cStub.getPosition() == pSeed && cStub.getBend() == cBendCode );
+                            cMatchedBends->Fill( cChipId , cStub.getBend() == cBendCode  );
+                            cMatchedSeeds->Fill( cChipId , cStub.getPosition() == pSeed );
+                        }
+                        cEventCounter++;
+                        if( cStubs.size() == 0 ) 
+                        {
+                            cMatchedBends->Fill( cChipId , 0 );
+                            cMatchedSeeds->Fill( cChipId , 0 );
+                            cMatchedStubs->Fill( cChipId , 0 );
+                        }
                     }
                 }
             }
@@ -1333,20 +1400,24 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
     }
     
     //unmask all channels and reset offsets 
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for (auto& cChip : *cHybrid)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 }
 // check hits and stubs using noise
@@ -1358,53 +1429,59 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
 
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                for ( auto cChip : *cHybrid )
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( theChip, "HitOr", 0);
+                    //enable stub logic
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( theChip, "Sampled", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( theChip, false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
     // generate stubs in exactly one chip 
     size_t cSeedIndex=0;
     uint8_t cBendCode = 0x00;
     std::vector<int> cExpectedHits(0);
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getChipId()) != pChipIds.end()  ) 
+
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                for (auto cChip : *cHybrid)
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {pSeed} , {pBend}, true );
-                    // read bend LUT
-                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                    cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                    LOG (DEBUG) << BOLDBLUE << "Injecting a stub in position " << +pSeed << " with bend " << pBend << " --- bend code is 0x" << std::hex << +cBendCode << std::dec << RESET;
-                    std::vector<uint8_t> cHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, pSeed , pBend ); 
-                    for( auto& cHit : cHits )
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
                     {
-                        if( std::find(cExpectedHits.begin(), cExpectedHits.end(), cHit) == cExpectedHits.end() )
-                            cExpectedHits.push_back( cHit );
-                    }  
-                }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
-            } 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {pSeed} , {pBend}, true );
+                        // read bend LUT
+                        std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                        cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
+                        LOG (DEBUG) << BOLDBLUE << "Injecting a stub in position " << +pSeed << " with bend " << pBend << " --- bend code is 0x" << std::hex << +cBendCode << std::dec << RESET;
+                        std::vector<uint8_t> cHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, pSeed , pBend ); 
+                        for( auto& cHit : cHits )
+                        {
+                            if( std::find(cExpectedHits.begin(), cExpectedHits.end(), cHit) == cExpectedHits.end() )
+                                cExpectedHits.push_back( cHit );
+                        }  
+                    }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
+                } 
+            }
         }
     }
 
@@ -1422,161 +1499,131 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
     for( uint8_t cPackageDelay=cStartScanRange ; cPackageDelay < cStopScanRange; cPackageDelay++)
     {
         //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment(cPackageDelay);
-        for (auto cBoard : this->fBoardVector)
+        zeroContainers();
+        for (auto cBoard : *fDetectorContainer)
         {
-            auto& cThisHitCheckContainer = fHitCheckContainer.at(cBoard->getIndex());
-            auto& cThisStubCheckContainer = fStubCheckContainer.at(cBoard->getIndex());
-
-            for (auto& cFe : cBoard->fModuleVector)
-            {
-                auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-                auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-                
-                for (auto& cChip : cFe->fReadoutChipVector) 
-                {
-                    auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-                    auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
-
-                    auto cChipId = cChip->getChipId();
-                    if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                        continue;
-
-                    cReadoutChipHitCheck->getSummary<int>() = 0;
-                    cReadoutChipStubCheck->getSummary<int>() = 0 ;
-                }
-            }
+            BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
             if( pScan ) 
             {
                 LOG (INFO) << BOLDBLUE << "Setting package delay to " << +cPackageDelay << RESET;
-                fBeBoardInterface->WriteBoardReg( cBoard, "fc7_daq_cnfg.physical_interface_block.cic.stub_package_delay",cPackageDelay) ;
+                fBeBoardInterface->WriteBoardReg( theBoard, "fc7_daq_cnfg.physical_interface_block.cic.stub_package_delay",cPackageDelay) ;
                 static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
             }
             // read N events 
-            this->ReadNEvents ( cBoard , cEventsPerPoint);//*(1+cTriggerMultiplicity) );
-            const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+            this->ReadNEvents ( theBoard , cEventsPerPoint);//*(1+cTriggerMultiplicity) );
+            const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
             LOG (INFO) << BOLDMAGENTA << "Read back " << +cEvents.size() << " events from board." << RESET;
             for( auto cEvent : cEvents )
             {
                 auto cEventCount = cEvent->GetEventCount(); 
                 LOG (DEBUG) << BOLDBLUE << "Event " << +cEventCount << RESET;
-                for (auto& cFe : cBoard->fModuleVector)
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-                    auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-                
-
-                    auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-                    auto cFeId = cFe->getFeId();
-                    auto cBxId = cEvent->BxId(cFe->getFeId());
-                    LOG (DEBUG) << BOLDBLUE << "Link Id : " << +cFe->getLinkId() <<  " FE " << +cFeId << " - Bx Id " << +cBxId << RESET;
-                    //cBxCounter->Fill( static_cast<float>(cEventCount) , cFeId , cBxId );
-                    TH2D* cL1Status = static_cast<TH2D*> ( getHist ( cFe, "L1Status" ) );
-                    TH2D* cMatchedStubs  = static_cast<TH2D*> ( getHist ( cFe, "MatchedStubs" ) );
-                    TH2D* cMatchedHits  = static_cast<TH2D*> ( getHist ( cFe, "MatchedHits" ) );
-                                      
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-                        auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
-
-                        auto cChipId = cChip->getChipId();
-                        if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                            continue;
+                        
+                        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
+                        auto cFeId = cFe->getId();
+                        auto cBxId = cEvent->BxId(cFe->getId());
+                        LOG (DEBUG) << BOLDBLUE << "Link Id : " << +static_cast<OuterTrackerModule*>(cFe)->getLinkId() <<  " FE " << +cFeId << " - Bx Id " << +cBxId << RESET;
+                        //cBxCounter->Fill( static_cast<float>(cEventCount) , cFeId , cBxId );
+                        TH2D* cL1Status = static_cast<TH2D*> ( getHist ( cFe, "L1Status" ) );
+                        TH2D* cMatchedStubs  = static_cast<TH2D*> ( getHist ( cFe, "MatchedStubs" ) );
+                        TH2D* cMatchedHits  = static_cast<TH2D*> ( getHist ( cFe, "MatchedHits" ) );
+                                        
+                        for (auto cChip : *cFe) 
+                        {
+                            auto cChipId = cChip->getId();
+                            if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                                continue;
 
-                        auto cErrorBit = cEvent->Error( cFeId , cChipId );
-                        cL1Status->Fill( cEventCount , cChipId, cErrorBit );
+                            auto cErrorBit = cEvent->Error( cFeId , cChipId );
+                            cL1Status->Fill( cEventCount , cChipId, cErrorBit );
 
-                        uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                        uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
-                        LOG (DEBUG) << BOLDBLUE << "Chip" << +cChipId << " : L1 counter " << +cL1Id << " error bits " << +cErrorBit << RESET;
-                        //hits
-                        auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
-                        for( auto cHit : cHits )
-                        {
-                            LOG (DEBUG) << BOLDMAGENTA << "\t... hit found in channel " << +cHit << " of readout chip" << +cChipId << RESET; 
-                        }
-                        std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, pSeed, pBend ); 
-                        size_t cMatched=0;
-                        for( auto cExpectedHit : cExpectedHits ) 
-                        {
-                            bool cMatchFound = std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end();
-                            cMatched += cMatchFound;
-                            cMatchedHits->Fill( cChipId , cMatchFound ) ;
-                        }
-                        if( cMatched == cExpectedHits.size() )
-                        {
-                            auto& cOcc = cReadoutChipHitCheck->getSummary<int>();
-                            cOcc += static_cast<int>(cMatched == cExpectedHits.size());
-                        }
-                        LOG (DEBUG) << BOLDMAGENTA << +cMatched << " matched hits found in readout chip" << +cChipId << " [ " << +cExpectedHits.size() << " expected.]" << RESET; 
-                        auto cStubs = cEvent->StubVector( cFeId, cChipId );
-                        for( auto cStub : cStubs ) 
-                        {
-                            LOG (DEBUG) << BOLDMAGENTA << "\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << " expect seed " << +pSeed << " and bend code " << +cBendCode << RESET;
-                            bool cMatchFound = (cStub.getPosition() == pSeed && cStub.getBend() == cBendCode); 
-                            cMatchedStubs->Fill(  cChipId , cMatchFound);
-                            auto& cOcc = cReadoutChipStubCheck->getSummary<int>();
-                            cOcc += static_cast<int>(cMatchFound);
+                            uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
+                            uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
+                            LOG (DEBUG) << BOLDBLUE << "Chip" << +cChipId << " : L1 counter " << +cL1Id << " error bits " << +cErrorBit << RESET;
+                            //hits
+                            auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
+                            for( auto cHit : cHits )
+                            {
+                                LOG (DEBUG) << BOLDMAGENTA << "\t... hit found in channel " << +cHit << " of readout chip" << +cChipId << RESET; 
+                            }
+                            std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( static_cast<ReadoutChip*>(cChip), pSeed, pBend ); 
+                            size_t cMatched=0;
+                            for( auto cExpectedHit : cExpectedHits ) 
+                            {
+                                bool cMatchFound = std::find(  cHits.begin(), cHits.end(), cExpectedHit) != cHits.end();
+                                cMatched += cMatchFound;
+                                cMatchedHits->Fill( cChipId , cMatchFound ) ;
+                            }
+                            if( cMatched == cExpectedHits.size() )
+                            {
+                                auto& cOcc = fHitCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<int>();
+                                cOcc += static_cast<int>(cMatched == cExpectedHits.size());
+                            }
+                            LOG (DEBUG) << BOLDMAGENTA << +cMatched << " matched hits found in readout chip" << +cChipId << " [ " << +cExpectedHits.size() << " expected.]" << RESET; 
+                            auto cStubs = cEvent->StubVector( cFeId, cChipId );
+                            for( auto cStub : cStubs ) 
+                            {
+                                LOG (DEBUG) << BOLDMAGENTA << "\t... stub seed " << +cStub.getPosition() << " --- bend code of " << +cStub.getBend() << " expect seed " << +pSeed << " and bend code " << +cBendCode << RESET;
+                                bool cMatchFound = (cStub.getPosition() == pSeed && cStub.getBend() == cBendCode); 
+                                cMatchedStubs->Fill(  cChipId , cMatchFound);
+                                auto& cOcc = fStubCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<int>();
+                                cOcc += static_cast<int>(cMatchFound);
+                            }
                         }
                     }
-               }
+                }
             }
 
-            for (auto& cFe : cBoard->fModuleVector)
+
+            for(auto cOpticalGroup : *cBoard)
             {
-                auto& cHybridHitCheck = cThisHitCheckContainer->at(cFe->getIndex());
-                auto& cHybridStubCheck = cThisStubCheckContainer->at(cFe->getIndex());  
-                
-                for (auto& cChip : cFe->fReadoutChipVector) 
+                for ( auto cHybrid : *cOpticalGroup )
                 {
-                    auto& cReadoutChipHitCheck = cHybridHitCheck->at(cChip->getIndex());
-                    auto& cReadoutChipStubCheck = cHybridStubCheck->at(cChip->getIndex());
+                    for ( auto cChip : *cHybrid )
+                    {
+                        auto cChipId = cChip->getId();
+                        if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
+                            continue;
 
-                    auto cChipId = cChip->getChipId();
-                    if( std::find(pChipIds.begin(), pChipIds.end(), cChipId) == pChipIds.end() )
-                        continue;
+                        auto cHitCheck  = fHitCheckContainer .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<int>();
+                        auto cStubCheck = fStubCheckContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<int>();
+                        LOG (INFO) << BOLDBLUE << "Found " << +cHitCheck << " matched hits and " << +cStubCheck << " matched stubs in readout chip" << +cChipId << RESET;
 
-                    auto& cHitCheck = cReadoutChipHitCheck->getSummary<int>();
-                    auto& cStubCheck = cReadoutChipStubCheck->getSummary<int>();
-                    LOG (INFO) << BOLDBLUE << "Found " << +cHitCheck << " matched hits and " << +cStubCheck << " matched stubs in readout chip" << +cChipId << RESET;
+                    }
                 }
-           }
-
+            }
         }
     }
 
     //unmask all channels and reset offsets 
     // also re-configure thresholds + hit/stub detect logic to original values 
     // and re-load configuration of fast command block from register map loaded from xml file 
-    for (auto cBoard : this->fBoardVector)
-    {   
-        auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
-        auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
-        auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getChipId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
+                for ( auto cChip : *cHybrid )
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                    fThresholds
+                    fLogic
+                    fHIPs
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth"                    , fThresholds.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , fLogic     .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "HIP&TestMode"            , fHIPs      .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
+                }
             }
         }
-        //
-        LOG (DEBUG) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
-        //
-        //fBeBoardInterface->ChipReSync ( cBoard );
     }
 
 }
@@ -1586,32 +1633,21 @@ void ExtraChecks::L1Eye()
     for( uint8_t cPhase=0; cPhase < 15; cPhase +=1 )
     {
         LOG (INFO) << BOLDBLUE << "Setting optimal phase tap in CIC to " << +cPhase << RESET;
-        for (auto cBoard : this->fBoardVector)
+        for (auto cBoard : *fDetectorContainer)
         {
-            for (auto& cFe : cBoard->fModuleVector)
+            for(auto cOpticalGroup : *cBoard)
             {
-                auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
-                bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
+                for ( auto cHybrid : *cOpticalGroup )
+                {
+                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+                    bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
+                }
             }
         }
         for( size_t cAttempt=0; cAttempt < 10; cAttempt++)
         {
             // zero container 
-            for (auto cBoard : this->fBoardVector)
-            {
-                auto& cHitCheck = fHitCheckContainer.at(cBoard->getIndex());
-                auto& cStubCheck = fStubCheckContainer.at(cBoard->getIndex());
-                for (auto& cFe : cBoard->fModuleVector)
-                {
-                    auto& cHitCheckThisHybrid = cHitCheck->at(cFe->getIndex());
-                    auto& cStubCheckThisHybrid = cStubCheck->at(cFe->getIndex());
-                    for (auto& cChip : cFe->fReadoutChipVector)
-                    {
-                        cHitCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
-                        cStubCheckThisHybrid->at(cChip->getIndex())->getSummary<int>() = 0;
-                    }
-                }
-            }
+            zeroContainers();
             DataCheck({cChipId}, 10 , 10, 0 ,false);
         }
     }
@@ -1629,21 +1665,23 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
     std::vector<int>     cBends( 3, cBend );
     SetStubWindowOffsets( cBendCode , cBend);
     // inject stubs in all FE chips 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                for ( auto cChip : *cHybrid )
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);                // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(theChip), "HitOr", 0);
+                    //enable stub logic
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(theChip), "Sampled", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(theChip), false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
     if( !pUseNoise ) 
     {
@@ -1657,23 +1695,27 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
     uint8_t cChipId = pChipId;
     size_t cSeedIndex=0;
     uint16_t cThreshold = 550;
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                if( cChip->getChipId() == cChipId ) 
+                for ( auto cChip : *cHybrid )
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , {cSeeds[cSeedIndex]} , {cBends[cSeedIndex]}, pUseNoise );
-                    if( !pUseNoise ) 
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( cChip->getId() == cChipId ) 
                     {
-                        ThresholdVisitor cThresholdVisitor (fReadoutChipInterface, cThreshold);
-                        static_cast<ReadoutChip*>(cChip)->accept (cThresholdVisitor); 
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {cSeeds[cSeedIndex]} , {cBends[cSeedIndex]}, pUseNoise );
+                        if( !pUseNoise ) 
+                        {
+                            ThresholdVisitor cThresholdVisitor (fReadoutChipInterface, cThreshold);
+                            static_cast<ReadoutChip*>(cChip)->accept (cThresholdVisitor); 
+                        }
                     }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
                 }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
             } 
         }
     }
@@ -1683,13 +1725,14 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(cFirmwareTPdelay,cFirmwareTriggerDelay,1000);
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
     // check that the hits are there... so find test pulse
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         //fBeBoardInterface->ChipReSync ( cBoard );
         uint16_t cMinValue=0;
-        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
+        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         uint16_t cStart = std::max(cMinValue, static_cast<uint16_t>(cDelay - 3) );
-        uint8_t cNbits = cBoard->fModuleVector.at(0)->fReadoutChipVector.at(0)->getNumberOfBits("TriggerLatency");
+        uint8_t cNbits = static_cast<ReadoutChip*>(cBoard->at(0)->at(0)->at(0))->getNumberOfBits("TriggerLatency");
         uint16_t cMaxValue = std::min( static_cast<uint16_t>(cDelay+1), static_cast<uint16_t>(std::pow(2, cNbits)-1) );
         uint16_t cStep=1;
         if( pUseNoise ) 
@@ -1699,13 +1742,13 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
         std::generate(cListOfValues.begin(), cListOfValues.end(), [&](){ return cValue+=cStep; });
         for( uint16_t cStubLatency = 137 ; cStubLatency < 138; cStubLatency++ )
         {
-            fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
+            fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
             for( auto cTriggerLatency : cListOfValues )
             {
-                this->setSameDacBeBoard(cBoard, "TriggerLatency", cTriggerLatency);
+                this->setSameDacBeBoard(theBoard, "TriggerLatency", cTriggerLatency);
                 for( uint16_t cTPdelay=0; cTPdelay < 25; cTPdelay+=3 )
                 {
-                    this->setSameDacBeBoard(cBoard, "TestPulseDelay", cTPdelay);
+                    this->setSameDacBeBoard(theBoard, "TestPulseDelay", cTPdelay);
                     float cTime = 25*(cFirmwareTriggerDelay - cTriggerLatency) - cTPdelay; 
                     //25*(cFirmwareTriggerDelay - 1 - cTriggerLatency) - cTPdelay;
                     float cTimeStubs = 25*(cStubLatency - cFirmwareTPdelay) - cTPdelay;//there was a -1 here
@@ -1725,14 +1768,14 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
                         ContainerFactory::copyAndInitStructure<Occupancy>(*fDetectorContainer, *cContainerVector.back() ); 
                         //fDetectorDataContainer = cContainerVector.at( cContainerVector.size()-1);
                         // set DAC .. read events
-                        this->setSameDacBeBoard(cBoard, "VCth", cVcth);
-                        this->ReadNEvents ( cBoard , cEventsPerAttempt );
-                        const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
+                        this->setSameDacBeBoard(theBoard, "VCth", cVcth);
+                        this->ReadNEvents ( theBoard , cEventsPerAttempt );
+                        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
                         /*for (auto& cFe : cBoard->fModuleVector)
                         {
                             for (auto& cChip : cFe->fReadoutChipVector) 
                             {
-                                if( cChip->getChipId() != cChipId )
+                                if( cChip->getId() != cChipId )
                                     continue;
                                 int cNstubs=0;
                                 TH2D* cMatchedStubs  = static_cast<TH2D*> ( getHist ( static_cast<ReadoutChip*>(cChip), "MatchedStubs" ) );
@@ -1745,10 +1788,10 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
                                 {
                                     //debug information
                                     auto cEventCount = cEvent->GetEventCount(); 
-                                    uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getFeId(), cChip->getChipId() );
-                                    uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
+                                    uint32_t cL1Id = static_cast<D19cCicEvent*>(cEvent)->L1Id( cFe->getId(), cChip->getId() );
+                                    uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
                                     //hits
-                                    auto cHits = cEvent->GetHits( cFe->getFeId(), cChip->getChipId() ) ;
+                                    auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
                                     cFoundHits->Fill( cTime , cVcth, cHits.size() );
                                     cNhits += cHits.size();
                                     std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cSeeds[cSeedIndex], cBends[cSeedIndex] ); 
@@ -1759,17 +1802,17 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
                                         if( cHitFound ) 
                                             cMatchedHits->Fill( cTime , cVcth, 1 );
                                     }
-                                    auto cStubs = cEvent->StubVector( cFe->getFeId(), cChip->getChipId() );
+                                    auto cStubs = cEvent->StubVector( cFe->getId(), cChip->getId() );
                                     cFoundStubs->Fill( cTimeStubs , cVcth , cStubs.size() );
                                     for( auto cStub: cStubs ) 
                                     {
                                         if( cStub.getPosition() == cSeeds[cSeedIndex] && cStub.getBend() == cBendCode ) 
                                             cMatchedStubs->Fill( cTimeStubs , cVcth , 1);
                                     }
-                                    cNstubs += cEvent->StubVector( cFe->getFeId(), cChip->getChipId() ).size() ;
+                                    cNstubs += cEvent->StubVector( cFe->getId(), cChip->getId() ).size() ;
                                 }
                                 if( static_cast<int>(cVcth)%10 == 0) 
-                                    LOG (INFO) << BOLDBLUE << "Vcth = " << cVcth << "... FE" << +cFe->getFeId() << " Chip" << +cChip->getChipId() << " --- " << cNstubs << " stubs -- " << cNhits << " hits." << RESET;
+                                    LOG (INFO) << BOLDBLUE << "Vcth = " << cVcth << "... FE" << +cFe->getId() << " Chip" << +cChip->getId() << " --- " << cNstubs << " stubs -- " << cNhits << " hits." << RESET;
                             }
                         }*/
                     }
@@ -1777,7 +1820,7 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
                     {
                         for (auto& cChip : cFe->fReadoutChipVector) 
                         {
-                            if( cChip->getChipId() != cChipId )
+                            if( cChip->getId() != cChipId )
                                 continue;
                             std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cSeeds[cSeedIndex], cBends[cSeedIndex] ); 
                             for(auto cChannel : cExpectedHits) 
@@ -1813,20 +1856,23 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,50,3,0,cDefaultStubLatency);
     }
     //unmask all channels and reset offsets 
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-
+                for ( auto cChip : *cHybrid )
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+                }
             } 
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 }
 void ExtraChecks::Stop()
@@ -1853,15 +1899,17 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
     bool cOptical=false;
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        cOptical = cOptical || cBoard->ifOptical();
-        for (auto& cFe : cBoard->fModuleVector)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        cOptical = cOptical || theBoard->ifOptical();
+        for(auto cOpticalGroup : *cBoard)
+        for (auto& cFe : *cOpticalGroup)
         {
-            if( cBoard->ifOptical() )
-                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
+            if( theBoard->ifOptical() )
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
             //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto& cChip : *cFe)
             {
                 // switch off HitOr
                 static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
@@ -1870,7 +1918,7 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
                 static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
     
     // set-up for TP
@@ -1885,15 +1933,16 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
     if( cOptical ) 
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->Bx0Alignment();
     // check that the hits are there... so find test pulse
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         //first, set VCth to the target value for each CBC
-        this->setSameDacBeBoard(cBoard , "VCth", pThreshold);
+        this->setSameDacBeBoard(theBoard , "VCth", pThreshold);
         auto& cThisShortsContainer = fShortsContainer.at(cBoard->getIndex());
         uint16_t cMinValue=0;
-        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
-        this->setSameDacBeBoard(cBoard, "TriggerLatency", cDelay-1);
-        this->setSameDacBeBoard(cBoard, "TestPulseDelay", cTPdelay);
+        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
+        this->setSameDacBeBoard(theBoard, "TriggerLatency", cDelay-1);
+        this->setSameDacBeBoard(theBoard, "TestPulseDelay", cTPdelay);
         uint8_t cTestGroup=0;
         for(auto cGroup : *fChannelGroupHandler)
         {
@@ -1901,39 +1950,43 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
             // bitset for this group
             std::bitset<NCHANNELS> cBitset = std::bitset<NCHANNELS>( static_cast<const ChannelGroup<NCHANNELS>*>(cGroup)->getBitset() );
             LOG (INFO) << "Injecting charge into front-end object using test capacitor " << +cTestGroup << " : L1A latency set to " << +cDelay << RESET; 
-            this->ReadNEvents ( cBoard , cEventsPerAttempt );
-            const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
-            for (auto& cFe : cBoard->fModuleVector)
+            this->ReadNEvents ( theBoard , cEventsPerAttempt );
+            const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+            for(auto cOpticalGroup : *cBoard )
             {
-                auto& cHybridShorts = cThisShortsContainer->at(cFe->getIndex());
-                for (auto& cChip : cFe->fReadoutChipVector) 
+                auto cOpticalGroupShorts = cThisShortsContainer->at(cOpticalGroup->getIndex());
+                for (auto cFe : *cOpticalGroup)
                 {
-                    auto& cReadoutChipShorts = cHybridShorts->at(cChip->getIndex());
-                    int cNhits=0;
-                    int cEventCounter=0;
-                    for( auto cEvent : cEvents ) 
+                    auto& cHybridShorts = cOpticalGroupShorts->at(cFe->getIndex());
+                    for (auto cChip : *cFe) 
                     {
-                        //debug information
-                        auto cEventCount = cEvent->GetEventCount(); 
-                        uint32_t cL1Id = cEvent->L1Id( cFe->getFeId(), cChip->getChipId() );
-                        uint32_t cPipeline = cEvent->PipelineAddress( cFe->getFeId(), cChip->getChipId() );
-                        //hits
-                        auto cHits = cEvent->GetHits( cFe->getFeId(), cChip->getChipId() ) ;
-                        LOG (INFO) << BOLDBLUE << "\t\tGroup " << +cTestGroup << " FE" << +cFe->getFeId() << " .. CBC" << +cChip->getChipId() << "...Event " << +cEventCount << " FE" << +cFe->getFeId() << " - " << +cHits.size() << " hits found/" << +cBitset.count() << " channels in test group" << RESET;
-                        for( auto cHit : cHits )
+                        auto cReadoutChipShorts = cHybridShorts->at(cChip->getIndex());
+                        int cNhits=0;
+                        int cEventCounter=0;
+                        for( auto cEvent : cEvents ) 
                         {
-                            if( cBitset[cHit] == 0) 
+                            //debug information
+                            auto cEventCount = cEvent->GetEventCount(); 
+                            uint32_t cL1Id = cEvent->L1Id( cFe->getId(), cChip->getId() );
+                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
+                            //hits
+                            auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
+                            LOG (INFO) << BOLDBLUE << "\t\tGroup " << +cTestGroup << " FE" << +cFe->getId() << " .. CBC" << +cChip->getId() << "...Event " << +cEventCount << " FE" << +cFe->getId() << " - " << +cHits.size() << " hits found/" << +cBitset.count() << " channels in test group" << RESET;
+                            for( auto cHit : cHits )
                             {
-                                cReadoutChipShorts->getChannelContainer<int>()->at(cHit)+=1;
+                                if( cBitset[cHit] == 0) 
+                                {
+                                    cReadoutChipShorts->getChannelContainer<int>()->at(cHit)+=1;
+                                }
                             }
+                            cNhits += cHits.size();
                         }
-                        cNhits += cHits.size();
+                        // get list of channels with hits; remember - I've only added a hit if the channel is not in this test group 
+                        auto cShorts = cReadoutChipShorts->getChannelContainer<int>();
+                        float cNshorts = cShorts->size() - std::count (cShorts->begin(), cShorts->end(), 0) ; //
+                        LOG (INFO) << BOLDBLUE << "\t\t\t FE" << +cFe->getId() << " CBC" << +cChip->getId() << " : number of shorts is  " << cNshorts << RESET;
+                
                     }
-                    // get list of channels with hits; remember - I've only added a hit if the channel is not in this test group 
-                    auto cShorts = cReadoutChipShorts->getChannelContainer<int>();
-                    float cNshorts = cShorts->size() - std::count (cShorts->begin(), cShorts->end(), 0) ; //
-                    LOG (INFO) << BOLDBLUE << "\t\t\t FE" << +cFe->getFeId() << " CBC" << +cChip->getChipId() << " : number of shorts is  " << cNshorts << RESET;
-            
                 }
             }
             cTestGroup++;
@@ -1955,24 +2008,29 @@ void ExtraChecks::Resume()
 
 void ExtraChecks::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 {
-    for (auto cBoard : this->fBoardVector)
+    // select AMUX output on one of the CBCs 
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                // read bend LUT
-                std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( cChip );
-                auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), pBendCode);
-                if( cIterator != cBendLUT.end() )
+                for ( auto cChip : *cHybrid )
                 {
-                    int cPosition = std::distance( cBendLUT.begin(), cIterator);
-                    double cBend_strips = -7. + 0.5*cPosition; 
-                    uint8_t cOffsetCode = static_cast<uint8_t>(std::abs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
-                    // set offsets
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (cOffsetCode << 4) | (cOffsetCode << 0) );
-                    fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (cOffsetCode << 4) | (cOffsetCode << 0) );
-                    LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( pBendCode ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips [offset code " << std::bitset<4>(cOffsetCode) << "]." <<  RESET;
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    // read bend LUT
+                    std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
+                    auto cIterator = std::find(cBendLUT.begin(), cBendLUT.end(), pBendCode);
+                    if( cIterator != cBendLUT.end() )
+                    {
+                        int cPosition = std::distance( cBendLUT.begin(), cIterator);
+                        double cBend_strips = -7. + 0.5*cPosition; 
+                        uint8_t cOffsetCode = static_cast<uint8_t>(std::abs(cBend_strips*2)) | (std::signbit(-1*cBend_strips) << 3);
+                        // set offsets
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (cOffsetCode << 4) | (cOffsetCode << 0) );
+                        fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (cOffsetCode << 4) | (cOffsetCode << 0) );
+                        LOG (DEBUG) << BOLDBLUE << "Bend code of " << std::bitset<4>( pBendCode ) << " found for bend reg " << +cPosition << " which means " << cBend_strips << " strips [offset code " << std::bitset<4>(cOffsetCode) << "]." <<  RESET;
+                    }
                 }
             }
         }
@@ -1999,14 +2057,14 @@ void ExtraChecks::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 //             for (auto& cFe : cBoard->fModuleVector)
 //             {
 //                 if(cIndex%10 == 0 )
-//                     LOG (INFO) << BOLDBLUE << "FE" << +cFe->getFeId() << " -- Vcth on all CBCs set to " << cListOfThresholds.at(cIndex) << " DAC units." << RESET; 
+//                     LOG (INFO) << BOLDBLUE << "FE" << +cFe->getId() << " -- Vcth on all CBCs set to " << cListOfThresholds.at(cIndex) << " DAC units." << RESET; 
 //                 TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
 //                 for (auto& cChip : cFe->fReadoutChipVector) 
 //                 {
 //                     for(size_t cIter=0; cIter < 5; cIter++)
 //                     {
-//                         std::pair<uint16_t,float> cReading = this->ReadAmux(cChip->getChipId() , "VCth");
-//                         cScan->Fill( cChip->getChipId(), cListOfThresholds.at(cIndex), cReading.second );
+//                         std::pair<uint16_t,float> cReading = this->ReadAmux(cChip->getId() , "VCth");
+//                         cScan->Fill( cChip->getId(), cListOfThresholds.at(cIndex), cReading.second );
 //                     }
 //                 }
 //             }
@@ -2016,15 +2074,18 @@ void ExtraChecks::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 std::pair<uint16_t,float> ExtraChecks::ReadAmux(uint8_t pFeId , uint8_t pChipId , std::string pValueToRead, bool pOptical )
 {
     // select AMUX output on one of the CBCs 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for ( auto cFe : *cBoard )
+        for(auto cOpticalGroup : *cBoard)
         {
-            for ( auto cChip : *cFe )
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                // select AMUX output 
-                //this->fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip),  "AmuxOutput", ((cChip->getChipId() != pChipId ) ? fAmuxMap["Floating"]: fAmuxMap[pValueToRead]) );
-                // now read voltage from the right source .
+                for ( auto cChip : *cHybrid )
+                {
+                    // select AMUX output 
+                    //this->fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip),  "AmuxOutput", ((cChip->getId() != pChipId ) ? fAmuxMap["Floating"]: fAmuxMap[pValueToRead]) );
+                    // now read voltage from the right source .
+                }
             }
         }
     }
diff --git a/tools/ExtraChecks.h b/tools/ExtraChecks.h
index aeb71079f..8793409d5 100644
--- a/tools/ExtraChecks.h
+++ b/tools/ExtraChecks.h
@@ -54,6 +54,7 @@ class ExtraChecks : public PedeNoise
 
   private:
     // Containers
+    void zeroContainers();
     DetectorDataContainer fNoiseContainer,  fPedestalContainer, fOccupancyContainer, fShortsContainer;
     DetectorDataContainer fHitCheckContainer, fStubCheckContainer;
     DetectorDataContainer  fThresholds, fLogic, fHIPs;
diff --git a/tools/HybridTester.cc b/tools/HybridTester.cc
index e201e389f..54be8203e 100644
--- a/tools/HybridTester.cc
+++ b/tools/HybridTester.cc
@@ -11,15 +11,16 @@ struct HistogramFiller  : public HwDescriptionVisitor
 
     HistogramFiller ( TH1F* pBotHist, TH1F* pTopHist, const Event* pEvent ) : fBotHist ( pBotHist ), fTopHist ( pTopHist ), fEvent ( pEvent ) {}
 
-    void visit ( Chip& pCbc )
+    void visit ( ChipContainer* pCbc )
     {
-        std::vector<bool> cDataBitVector = fEvent->DataBitVector ( pCbc.getFeId(), pCbc.getChipId() );
+        ReadoutChip* theCbc = static_cast<ReadoutChip*>(pCbc);
+        std::vector<bool> cDataBitVector = fEvent->DataBitVector ( theCbc->getFeId(), theCbc->getChipId() );
 
         for ( uint32_t cId = 0; cId < NCHANNELS; cId++ )
         {
             if ( cDataBitVector.at ( cId ) )
             {
-                uint32_t globalChannel = ( pCbc.getChipId() * 254 ) + cId;
+                uint32_t globalChannel = ( theCbc->getChipId() * 254 ) + cId;
 
                 //              LOG(INFO) << "Channel " << globalChannel << " VCth " << int(pCbc.getReg( "VCth" )) ;
                 // find out why histograms are not filling!
@@ -40,40 +41,43 @@ HybridTester::~HybridTester() {}
 
 void HybridTester::ReconfigureCBCRegisters (std::string pDirectoryName )
 {
-    for (auto& cBoard : fBoardVector)
+    for (auto& cBoard : *fDetectorContainer)
     {
-        fBeBoardInterface->ChipReset ( cBoard );
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        fBeBoardInterface->ChipReset ( theBoard );
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
 
 
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
 
-
-
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cCbc : cFe->fReadoutChipVector)
+            for ( auto cFe : *cOpticalGroup )
             {
-                std::string pRegFile ;
-                char buffer[120];
-
-                if ( pDirectoryName.empty() )
-                    sprintf (buffer, "%s/FE%dCBC%d.txt", fDirectoryName.c_str(), cCbc->getFeId(), cCbc->getChipId() );
-                else
-                    sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cCbc->getFeId(), cCbc->getChipId() );
-
-                pRegFile = buffer;
-                cCbc->loadfRegMap (pRegFile);
-                fReadoutChipInterface->ConfigureChip ( cCbc );
-                LOG (INFO) << GREEN << "\t\t Successfully reconfigured CBC" << int ( cCbc->getChipId() ) << "'s regsiters from " << pRegFile << " ." << RESET ;
+                for (auto& cCbc : *cFe)
+                {
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                    std::string pRegFile ;
+                    char buffer[120];
+
+                    if ( pDirectoryName.empty() )
+                        sprintf (buffer, "%s/FE%dCBC%d.txt", fDirectoryName.c_str(), cFe->getId(), cCbc->getId() );
+                    else
+                        sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cFe->getId(), cCbc->getId() );
+
+                    pRegFile = buffer;
+                    theCbc->loadfRegMap (pRegFile);
+                    fReadoutChipInterface->ConfigureChip ( theCbc );
+                    LOG (INFO) << GREEN << "\t\t Successfully reconfigured CBC" << int ( cCbc->getId() ) << "'s regsiters from " << pRegFile << " ." << RESET ;
+                }
             }
         }
 
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
 }
 
@@ -148,39 +152,41 @@ void HybridTester::InitializeHists()
 
 
     // Now the Histograms for SCurves
-    for ( auto cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-
-        for ( auto cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-            uint16_t cMaxRange = 1023;
-            fType = cFe->getFrontEndType();
-
-            for ( auto cCbc : cFe->fReadoutChipVector )
+            for ( auto cFe : *cOpticalGroup )
             {
+                uint32_t cFeId = cFe->getId();
+                uint16_t cMaxRange = 1023;
+                fType = static_cast<OuterTrackerModule*>(cFe)->getFrontEndType();
 
-                uint32_t cCbcId = cCbc->getChipId();
+                for ( auto cCbc : *cFe )
+                {
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                    uint32_t cCbcId = cCbc->getId();
 
-                TString cName = Form ( "SCurve_Fe%d_Cbc%d", cFeId, cCbcId );
-                TObject* cObject = static_cast<TObject*> ( gROOT->FindObject ( cName ) );
+                    TString cName = Form ( "SCurve_Fe%d_Cbc%d", cFeId, cCbcId );
+                    TObject* cObject = static_cast<TObject*> ( gROOT->FindObject ( cName ) );
 
-                if ( cObject ) delete cObject;
+                    if ( cObject ) delete cObject;
 
-                TH1F* cTmpScurve = new TH1F ( cName, Form ( "Noise Occupancy Chip%d; VCth; Counts", cCbcId ), cMaxRange, 0, cMaxRange );
-                cTmpScurve->SetMarkerStyle ( 8 );
-                bookHistogram ( cCbc, "Scurve", cTmpScurve );
-                fSCurveMap[cCbc] = cTmpScurve;
+                    TH1F* cTmpScurve = new TH1F ( cName, Form ( "Noise Occupancy Chip%d; VCth; Counts", cCbcId ), cMaxRange, 0, cMaxRange );
+                    cTmpScurve->SetMarkerStyle ( 8 );
+                    bookHistogram ( cCbc, "Scurve", cTmpScurve );
+                    fSCurveMap[cCbc] = cTmpScurve;
 
-                cName = Form ( "SCurveFit_Fe%d_Cbc%d", cFeId, cCbcId );
-                cObject = static_cast<TObject*> ( gROOT->FindObject ( cName ) );
+                    cName = Form ( "SCurveFit_Fe%d_Cbc%d", cFeId, cCbcId );
+                    cObject = static_cast<TObject*> ( gROOT->FindObject ( cName ) );
 
-                if ( cObject ) delete cObject;
+                    if ( cObject ) delete cObject;
 
-                TF1* cTmpFit = new TF1 ( cName, MyErf, 0, cMaxRange, 2 );
-                bookHistogram ( cCbc, "ScurveFit", cTmpFit );
+                    TF1* cTmpFit = new TF1 ( cName, MyErf, 0, cMaxRange, 2 );
+                    bookHistogram ( cCbc, "ScurveFit", cTmpFit );
 
-                fFitMap[cCbc] = cTmpFit;
+                    fFitMap[cCbc] = cTmpFit;
+                }
             }
         }
     }
@@ -201,10 +207,10 @@ void HybridTester::InitialiseSettings()
         // if ( cSetting != std::end ( fSettingsMap ) ) trigSource = cSetting->second;
         // LOG (INFO)  <<int (trigSource);
 
-    for (auto& cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
 
-        trigSource = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
+        trigSource = fBeBoardInterface->ReadBoardReg (static_cast<BeBoard*>(cBoard), "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
     }
     // LOG(INFO) << "Read the f llowing Settings: " ;
@@ -248,43 +254,46 @@ uint32_t HybridTester::fillSCurves ( BeBoard* pBoard,  const Event* pEvent, uint
 {
     uint32_t cHitCounter = 0;
 
-    for ( auto cFe : pBoard->fModuleVector )
+    for(auto cOpticalGroup : *pBoard)
     {
-        for ( auto cCbc : cFe->fReadoutChipVector )
+        for ( auto cFe : *cOpticalGroup )
         {
-            // SS
-            /*TH1F* sCurveHist = static_cast<TH1F*>( getHist( cCbc, "Scurve" ) );
-            uint32_t cbcEventCounter = 0;
-            for ( uint32_t cId = 0; cId < NCHANNELS; cId++ )
+            for ( auto cCbc : *cFe )
             {
-                if ( pEvent->DataBit( cCbc->getFeId(), cCbc->getChipId(), cId ) )
+                // SS
+                /*TH1F* sCurveHist = static_cast<TH1F*>( getHist( cCbc, "Scurve" ) );
+                uint32_t cbcEventCounter = 0;
+                for ( uint32_t cId = 0; cId < NCHANNELS; cId++ )
                 {
-                    sCurveHist->Fill( pValue );
-                    cHitCounter++;
-                    cbcEventCounter++;
-                }
-            }*/
+                    if ( pEvent->DataBit( cCbc->getFeId(), cCbc->getChipId(), cId ) )
+                    {
+                        sCurveHist->Fill( pValue );
+                        cHitCounter++;
+                        cbcEventCounter++;
+                    }
+                }*/
 
-            auto cScurve = fSCurveMap.find ( cCbc );
+                auto cScurve = fSCurveMap.find ( cCbc );
 
-            if ( cScurve == fSCurveMap.end() ) LOG (INFO) << "Error: could not find an Scurve object for Chip " << int ( cCbc->getChipId() ) ;
-            else
-            {
-                //for ( uint32_t cId = 0; cId < NCHANNELS; cId++ )
-                //{
-                //if ( pEvent->DataBit ( cCbc->getFeId(), cCbc->getChipId(), cId ) )
-                //{
-                //cScurve->second->Fill ( pValue );
-                //cHitCounter++;
-                //}
-                //}
-                //experimental
-
-                std::vector<uint32_t> cHits = pEvent->GetHits (cCbc->getFeId(), cCbc->getChipId() );
-                cHitCounter += cHits.size();
-
-                for (__attribute__((unused)) auto cHit : cHits)
-                    cScurve->second->Fill (pValue);
+                if ( cScurve == fSCurveMap.end() ) LOG (INFO) << "Error: could not find an Scurve object for Chip " << int ( cCbc->getId() ) ;
+                else
+                {
+                    //for ( uint32_t cId = 0; cId < NCHANNELS; cId++ )
+                    //{
+                    //if ( pEvent->DataBit ( cCbc->getFeId(), cCbc->getChipId(), cId ) )
+                    //{
+                    //cScurve->second->Fill ( pValue );
+                    //cHitCounter++;
+                    //}
+                    //}
+                    //experimental
+
+                    std::vector<uint32_t> cHits = pEvent->GetHits (cFe->getId(), cCbc->getId() );
+                    cHitCounter += cHits.size();
+
+                    for (__attribute__((unused)) auto cHit : cHits)
+                        cScurve->second->Fill (pValue);
+                }
             }
         }
     }
@@ -317,30 +326,31 @@ void HybridTester::ScanThresholds()
         fHistTop->GetYaxis()->SetRangeUser ( 0, fTotalEvents );
         fHistBottom->GetYaxis()->SetRangeUser ( 0, fTotalEvents );
 
-        for ( BeBoard* pBoard : fBoardVector )
+        for ( auto pBoard : *fDetectorContainer )
         {
+            BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
             uint32_t cN = 1;
             uint32_t cNthAcq = 0;
 
-            fBeBoardInterface->Start ( pBoard );
+            fBeBoardInterface->Start ( theBoard );
 
             while ( cN <=  fTotalEvents )
             {
-                // Run( pBoard, cNthAcq );
-                ReadData ( pBoard );
-                const std::vector<Event*>& events = GetEvents ( pBoard );
+                // Run( theBoard, cNthAcq );
+                ReadData ( theBoard );
+                const std::vector<Event*>& events = GetEvents ( theBoard );
 
                 // Loop over Events from this Acquisition
                 for ( auto& cEvent : events )
                 {
                     HistogramFiller cFiller ( fHistBottom, fHistTop, cEvent );
-                    pBoard->accept ( cFiller );
+                    theBoard->accept ( cFiller );
 
-                    fillSCurves ( pBoard,  cEvent, cVcth );
+                    fillSCurves ( theBoard,  cEvent, cVcth );
 
                     if ( cN % 100 == 0 )
                     {
-                        updateSCurveCanvas ( pBoard );
+                        updateSCurveCanvas ( theBoard );
                         UpdateHists();
                     }
 
@@ -350,7 +360,7 @@ void HybridTester::ScanThresholds()
                 cNthAcq++;
             }
 
-            fBeBoardInterface->Stop ( pBoard);
+            fBeBoardInterface->Stop ( theBoard);
         }
 
         fHistTop->Scale ( 100 / double_t ( fTotalEvents ) );
@@ -432,31 +442,34 @@ void HybridTester::ScanThreshold()
         // maybe restrict to pBoard? instead of looping?
         if ( cAllOne ) break;
 
-        for ( BeBoard* pBoard : fBoardVector )
+
+        for ( auto pBoard : *fDetectorContainer )
         {
-            fBeBoardInterface->Start ( pBoard );
+            BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
+
+            fBeBoardInterface->Start ( theBoard );
 
             while ( cN <=  cEventsperVcth )
             {
-                // Run( pBoard, cNthAcq );
-                ReadData ( pBoard );
-                const std::vector<Event*>& events = GetEvents ( pBoard );
+                // Run( theBoard, cNthAcq );
+                ReadData ( theBoard );
+                const std::vector<Event*>& events = GetEvents ( theBoard );
 
                 // Loop over Events from this Acquisition
                 for ( auto& cEvent : events )
                 {
                     // loop over Modules & Cbcs and count hits separately
-                    cHitCounter += fillSCurves ( pBoard,  cEvent, cVcth );
+                    cHitCounter += fillSCurves ( theBoard,  cEvent, cVcth );
                     cN++;
                 }
 
                 cNthAcq++;
             }
 
-            fBeBoardInterface->Stop ( pBoard);
+            fBeBoardInterface->Stop ( theBoard);
             // LOG(INFO) << +cVcth << " " << cHitCounter ;
             // Draw the thing after each point
-            updateSCurveCanvas ( pBoard );
+            updateSCurveCanvas ( theBoard );
 
             // check if the hitcounter is all ones
 
@@ -506,7 +519,7 @@ void HybridTester::processSCurves ( uint32_t pEventsperVcth )
 {
     for ( auto cScurve : fSCurveMap )
     {
-        fSCurveCanvas->cd ( cScurve.first->getChipId() + 1 );
+        fSCurveCanvas->cd ( cScurve.first->getId() + 1 );
 
         cScurve.second->Scale ( 1.0 / double_t ( pEventsperVcth * NCHANNELS ) );
         cScurve.second->Draw ( "P" );
@@ -561,7 +574,7 @@ void HybridTester::processSCurves ( uint32_t pEventsperVcth )
         // find the corresponding fit
         auto cFit = fFitMap.find ( cScurve.first );
 
-        if ( cFit == std::end ( fFitMap ) ) LOG (INFO) << "Error: could not find Fit for Chip " << int ( cScurve.first->getChipId() ) ;
+        if ( cFit == std::end ( fFitMap ) ) LOG (INFO) << "Error: could not find Fit for Chip " << int ( cScurve.first->getId() ) ;
         else
         {
             // Fit
@@ -582,7 +595,8 @@ void HybridTester::processSCurves ( uint32_t pEventsperVcth )
 
             uint16_t cThreshold = ceil ( pedestal + fSigmas * fabs ( noise ) );
 
-            LOG (INFO) << "Identified a noise Occupancy of 50% at VCth " << static_cast<int> ( pedestal ) << " -- increasing by " << fSigmas <<  " sigmas (=" << fabs ( noise ) << ") to " << +cThreshold << " for Chip " << int ( cScurve.first->getChipId() ) ;
+            LOG (INFO) << "Identified a noise Occupancy of 50% at VCth " << static_cast<int> ( pedestal ) << " -- increasing by " << fSigmas 
+                <<  " sigmas (=" << fabs ( noise ) << ") to " << +cThreshold << " for Chip " << int ( cScurve.first->getId() ) ;
 
             TLine* cLine = new TLine ( cThreshold, 0, cThreshold, 1 );
             cLine->SetLineWidth ( 3 );
@@ -590,7 +604,7 @@ void HybridTester::processSCurves ( uint32_t pEventsperVcth )
             cLine->Draw ( "same" );
 
             ThresholdVisitor cVisitor (fReadoutChipInterface, cThreshold);
-            cScurve.first->accept (cVisitor);
+            static_cast<ReadoutChip*>(cScurve.first)->accept (cVisitor);
         }
 
     }
@@ -621,18 +635,21 @@ void HybridTester::updateSCurveCanvas ( BeBoard* pBoard )
     // Here iterate over the fScurveMap and update
     fSCurveCanvas->cd();
 
-    for ( auto cFe : pBoard->fModuleVector )
-    {
-        for ( auto cCbc : cFe->fReadoutChipVector )
+    for ( auto cOpticalGroup : *pBoard )
         {
-            uint32_t cCbcId = cCbc->getChipId();
-            auto cScurve = fSCurveMap.find ( cCbc );
-
-            if ( cScurve == fSCurveMap.end() ) LOG (INFO) << "Error: could not find an Scurve object for Chip " << int ( cCbc->getChipId() ) ;
-            else
+        for ( auto cFe : *cOpticalGroup )
+        {
+            for ( auto cCbc : *cFe )
             {
-                fSCurveCanvas->cd ( cCbcId + 1 );
-                cScurve->second->DrawCopy ( "P" );
+                uint32_t cCbcId = cCbc->getId();
+                auto cScurve = fSCurveMap.find ( cCbc );
+
+                if ( cScurve == fSCurveMap.end() ) LOG (INFO) << "Error: could not find an Scurve object for Chip " << int ( cCbc->getId() ) ;
+                else
+                {
+                    fSCurveCanvas->cd ( cCbcId + 1 );
+                    cScurve->second->DrawCopy ( "P" );
+                }
             }
         }
     }
@@ -659,18 +676,20 @@ void HybridTester::TestRegisters()
                 fBadRegisters[cCbcIterator] = tempset;
         }
 
-        void visit ( Chip& pCbc )
+        void visit ( ChipContainer* pCbc )
         {
             uint8_t cFirstBitPattern = 0xAA;
             uint8_t cSecondBitPattern = 0x55;
 
-            ChipRegMap cMap = pCbc.getRegMap();
+            ReadoutChip* theCbc = static_cast<ReadoutChip*>(pCbc);
+
+            ChipRegMap cMap = theCbc->getRegMap();
 
             for ( const auto& cReg : cMap )
             {
-                if ( !fInterface->WriteChipReg ( &pCbc, cReg.first, cFirstBitPattern, true ) ) fBadRegisters[pCbc.getChipId()] .insert ( cReg.first );
+                if ( !fInterface->WriteChipReg ( theCbc, cReg.first, cFirstBitPattern, true ) ) fBadRegisters[pCbc->getId()] .insert ( cReg.first );
 
-                if ( !fInterface->WriteChipReg ( &pCbc, cReg.first, cSecondBitPattern, true ) ) fBadRegisters[pCbc.getChipId()] .insert ( cReg.first );
+                if ( !fInterface->WriteChipReg ( theCbc, cReg.first, cSecondBitPattern, true ) ) fBadRegisters[pCbc->getId()] .insert ( cReg.first );
             }
         }
 
@@ -915,16 +934,19 @@ void HybridTester::SetBeBoardForShortsFinding (BeBoard* pBoard)
 
 void HybridTester::SetTestGroup(BeBoard* pBoard, uint8_t pTestGroup)
 {
-    for (auto cFe : pBoard->fModuleVector)
+    for ( auto cOpticalGroup : *pBoard )
     {
-        for (auto cCbc : cFe->fReadoutChipVector)
+        for (auto cFe : *cOpticalGroup)
         {
-            std::vector<std::pair<std::string, uint16_t>> cRegVec;
-            uint16_t cRegValue = this->to_reg ( 0, pTestGroup );
+            for (auto cCbc : *cFe)
+            {
+                std::vector<std::pair<std::string, uint16_t>> cRegVec;
+                uint16_t cRegValue = this->to_reg ( 0, pTestGroup );
 
-            cRegVec.push_back ( std::make_pair ( "TestPulseDel&ChanGroup",  cRegValue ) );
-            
-            this->fReadoutChipInterface->WriteChipMultReg (cCbc, cRegVec);
+                cRegVec.push_back ( std::make_pair ( "TestPulseDel&ChanGroup",  cRegValue ) );
+                
+                this->fReadoutChipInterface->WriteChipMultReg (static_cast<ReadoutChip*>(cCbc), cRegVec);
+            }
         }
     }
 }
@@ -944,12 +966,13 @@ void HybridTester::FindShorts()
     fHistTop->GetYaxis()->SetRangeUser ( 0, fTotalEvents );
     fHistBottom->GetYaxis()->SetRangeUser ( 0, fTotalEvents );
 
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
         uint32_t cN = 1;
         uint32_t cNthAcq = 0;
 
-        SetBeBoardForShortsFinding (pBoard);
+        SetBeBoardForShortsFinding (theBoard);
 
         ss << "\nShorted channels searching procedure\nSides: Top - 0\tBottom - 1 (Channel numbering starts from 0)\n" << std::endl;
         ss << "      Side\t| Channel_ID\t| Group_ID\t| Shorted_With_Group_ID" << std::endl;
@@ -959,22 +982,22 @@ void HybridTester::FindShorts()
             cN = 1;
             cNthAcq = 0;
 
-            this->SetTestGroup(pBoard,(uint8_t)cTestPulseGroupId);
+            this->SetTestGroup(theBoard,(uint8_t)cTestPulseGroupId);
 
-            fBeBoardInterface->Start ( pBoard );
+            fBeBoardInterface->Start ( theBoard );
 
             while ( cN <=  fTotalEvents )
             {
-                //Run( pBoard, cNthAcq );
-                ReadData ( pBoard );
-                //ReadNEvents ( pBoard, cNthAcq );
-                const std::vector<Event*>& events = GetEvents ( pBoard );
+                //Run( theBoard, cNthAcq );
+                ReadData ( theBoard );
+                //ReadNEvents ( theBoard, cNthAcq );
+                const std::vector<Event*>& events = GetEvents ( theBoard );
 
                 // Loop over Events from this Acquisition
                 for ( auto& cEvent : events )
                 {
                     HistogramFiller cFiller ( fHistBottom, fHistTop, cEvent );
-                    pBoard->accept ( cFiller );
+                    theBoard->accept ( cFiller );
 
                     if ( cN % 100 == 0 )
                         UpdateHists();
@@ -985,7 +1008,7 @@ void HybridTester::FindShorts()
                 cNthAcq++;
             }
 
-            fBeBoardInterface->Stop ( pBoard);
+            fBeBoardInterface->Stop ( theBoard);
 
             std::vector<std::array<int, 5>> cShortedChannelsGroup;
 
@@ -1056,25 +1079,26 @@ void HybridTester::Measure()
 
 
 
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         uint32_t cN = 1;
         uint32_t cNthAcq = 0;
 
-        fBeBoardInterface->Start ( pBoard );
+        fBeBoardInterface->Start ( theBoard );
 
         while ( cN <=  fTotalEvents )
         {
-            //Run( pBoard, cNthAcq );
-            ReadData ( pBoard );
-            //ReadNEvents ( pBoard, cNthAcq );
-            const std::vector<Event*>& events = GetEvents ( pBoard );
+            //Run( theBoard, cNthAcq );
+            ReadData ( theBoard );
+            //ReadNEvents ( theBoard, cNthAcq );
+            const std::vector<Event*>& events = GetEvents ( theBoard );
 
             // Loop over Events from this Acquisition
             for ( auto& cEvent : events )
             {
                 HistogramFiller cFiller ( fHistBottom, fHistTop, cEvent );
-                pBoard->accept ( cFiller );
+                theBoard->accept ( cFiller );
 
                 if ( cN % 100 == 0 )
                     UpdateHists();
@@ -1085,7 +1109,7 @@ void HybridTester::Measure()
             cNthAcq++;
         }
 
-        fBeBoardInterface->Stop ( pBoard);
+        fBeBoardInterface->Stop ( theBoard);
     }
 
     for ( uint8_t i = 1 ; i < (fNCbc * 254u) / 2u ; i++ )
@@ -1211,26 +1235,27 @@ void HybridTester::AntennaScan(uint8_t pDigiPotentiometer)
 
         if (channel_position == 9) break;
 
-        for ( BeBoard* pBoard : this->fBoardVector )
+        for ( auto pBoard : *fDetectorContainer )
         {
+            BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
             uint32_t cN = 1;
             uint32_t cNthAcq = 0;
 
-            this->Start ( pBoard );
+            this->Start ( theBoard );
 
 
             while ( cN <=  fTotalEvents )
             {
-                // Run( pBoard, cNthAcq );
-                ReadData ( pBoard );
+                // Run( theBoard, cNthAcq );
+                ReadData ( theBoard );
 
-                const std::vector<Event*>& events = GetEvents ( pBoard );
+                const std::vector<Event*>& events = GetEvents ( theBoard );
 
                 // Loop over Events from this Acquisition
                 for ( auto& cEvent : events )
                 {
                     HistogramFiller cFiller ( fHistBottom, fHistTop, cEvent );
-                    pBoard->accept ( cFiller );
+                    theBoard->accept ( cFiller );
 
                     if ( cN % 100 == 0 ) UpdateHists();
 
@@ -1240,7 +1265,7 @@ void HybridTester::AntennaScan(uint8_t pDigiPotentiometer)
                 cNthAcq++;
             }
 
-            this->Stop ( pBoard);
+            this->Stop ( theBoard);
 
             /*Here the reconstruction of histograms happens*/
             for ( uint16_t channel_id = 1; channel_id < fNCbc * 127 + 1; channel_id++ )
diff --git a/tools/HybridTester.h b/tools/HybridTester.h
index 883a8a4f4..372fae13d 100644
--- a/tools/HybridTester.h
+++ b/tools/HybridTester.h
@@ -152,8 +152,8 @@ class HybridTester : public Tool
     bool fThresholdScan; /*!< Flag for SCurve Canvas */
     TCanvas* fSCurveCanvas;   /*!< Canvas for threshold scan */
 
-    std::map<Ph2_HwDescription::Chip*, TH1F*> fSCurveMap;  /*!< Histograms for SCurve */
-    std::map<Ph2_HwDescription::Chip*, TF1*> fFitMap;   /*!< fits for SCurve*/
+    std::map<ChipContainer*, TH1F*> fSCurveMap;  /*!< Histograms for SCurve */
+    std::map<ChipContainer*, TF1*> fFitMap;   /*!< fits for SCurve*/
 
     // noisy and dead channels on top/bottom sensors
     std::vector<int> fNoisyChannelsTop;
diff --git a/tools/LatencyScan.cc b/tools/LatencyScan.cc
index 938936575..7ff652eee 100644
--- a/tools/LatencyScan.cc
+++ b/tools/LatencyScan.cc
@@ -14,9 +14,9 @@ void LatencyScan::Initialize (uint32_t pStartLatency, uint32_t pLatencyRange)
         fDQMHistogramLatencyScan.book(fResultFile, *fDetectorContainer, fSettingsMap);
     #endif
 
-    for ( auto& cBoard : fBoardVector )
+    for ( auto& cBoard : *fDetectorContainer )
     {
-        uint32_t cBoardId = cBoard->getBeId();
+        uint32_t cBoardId = cBoard->getId();
 
         TH1F* cTriggerTDC = new TH1F ( Form ( "h_BeBoard_triggerTDC_Be%d", cBoardId ), Form ( "Trigger TDC BE%d; Trigger TDC; # of Hits", cBoardId ), fTDCBins, -0.5, fTDCBins-0.5);
 
@@ -24,45 +24,47 @@ void LatencyScan::Initialize (uint32_t pStartLatency, uint32_t pLatencyRange)
         cTriggerTDC->SetFillStyle ( 3001 );
         bookHistogram ( cBoard, "triggerTDC", cTriggerTDC );
 
-
-        for ( auto& cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
+            for ( auto cFe : *cOpticalGroup )
+            {
+                uint32_t cFeId = cFe->getId();
 
-            TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) );
-            // ctmpCanvas->Divide( 2, 2 );
-            fCanvasMap[cFe] = ctmpCanvas;
+                TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) );
+                // ctmpCanvas->Divide( 2, 2 );
+                fCanvasMap[cFe] = ctmpCanvas;
 
-            fNCbc = cFe->getNChip();
+                fNCbc = cFe->size();
 
-            // 1D Hist forlatency scan
-            TString cName =  Form ( "h_module_latency_Fe%d", cFeId );
-            TObject* cObj = gROOT->FindObject ( cName );
+                // 1D Hist forlatency scan
+                TString cName =  Form ( "h_module_latency_Fe%d", cFeId );
+                TObject* cObj = gROOT->FindObject ( cName );
 
-            if ( cObj ) delete cObj;
+                if ( cObj ) delete cObj;
 
-            TH1F* cLatHist = nullptr;
-            
-            cLatHist = new TH1F ( cName, Form ( "Latency FE%d; Latency; # of Hits", cFeId ), (pLatencyRange ) , pStartLatency - 0.5,  pStartLatency + (pLatencyRange ) - 0.5 );
+                TH1F* cLatHist = nullptr;
+                
+                cLatHist = new TH1F ( cName, Form ( "Latency FE%d; Latency; # of Hits", cFeId ), (pLatencyRange ) , pStartLatency - 0.5,  pStartLatency + (pLatencyRange ) - 0.5 );
 
-            cLatHist->GetXaxis()->SetTitle ("Trigger Latency");
-            cLatHist->SetFillColor ( 4 );
-            cLatHist->SetFillStyle ( 3001 );
-            bookHistogram ( cFe, "module_latency", cLatHist );
+                cLatHist->GetXaxis()->SetTitle ("Trigger Latency");
+                cLatHist->SetFillColor ( 4 );
+                cLatHist->SetFillStyle ( 3001 );
+                bookHistogram ( cFe, "module_latency", cLatHist );
 
-            cName =  Form ( "h_module_stub_latency_Fe%d", cFeId );
-            cObj = gROOT->FindObject ( cName );
+                cName =  Form ( "h_module_stub_latency_Fe%d", cFeId );
+                cObj = gROOT->FindObject ( cName );
 
-            if ( cObj ) delete cObj;
+                if ( cObj ) delete cObj;
 
-            TH1F* cStubHist = new TH1F ( cName, Form ( "Stub Lateny FE%d; Stub Lateny; # of Stubs", cFeId ), pLatencyRange, pStartLatency, pStartLatency + pLatencyRange);
-            cStubHist->SetMarkerStyle ( 2 );
-            bookHistogram ( cFe, "module_stub_latency", cStubHist );
+                TH1F* cStubHist = new TH1F ( cName, Form ( "Stub Lateny FE%d; Stub Lateny; # of Stubs", cFeId ), pLatencyRange, pStartLatency, pStartLatency + pLatencyRange);
+                cStubHist->SetMarkerStyle ( 2 );
+                bookHistogram ( cFe, "module_stub_latency", cStubHist );
 
-            cName =  Form ( "h_module_latency_2D_Fe%d", cFeId );
-            TH2D* cLatencyScan2D =  new TH2D ( cName, Form ( "Latency FE%d; Stub Latency; L1 Latency; # of Events w/ no Hits and no Stubs", cFeId ), pLatencyRange  , pStartLatency - 0.5 ,  pStartLatency + (pLatencyRange ) - 0.5 , pLatencyRange  , pStartLatency - 0.5 ,  pStartLatency + (pLatencyRange ) - 0.5 );
-            bookHistogram ( cFe, "module_latency_2D", cLatencyScan2D );
-            
+                cName =  Form ( "h_module_latency_2D_Fe%d", cFeId );
+                TH2D* cLatencyScan2D =  new TH2D ( cName, Form ( "Latency FE%d; Stub Latency; L1 Latency; # of Events w/ no Hits and no Stubs", cFeId ), pLatencyRange  , pStartLatency - 0.5 ,  pStartLatency + (pLatencyRange ) - 0.5 , pLatencyRange  , pStartLatency - 0.5 ,  pStartLatency + (pLatencyRange ) - 0.5 );
+                bookHistogram ( cFe, "module_latency_2D", cLatencyScan2D );
+                
+            }
         }
     }
 
@@ -76,21 +78,22 @@ void LatencyScan::MeasureTriggerTDC()
 
     std::map<uint16_t, std::vector<uint16_t> > BeBoardTriggerTDCMap;
     // Take Data for all Modules
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
         // I need this to normalize the TDC values I get from the Strasbourg FW
-        BeBoardTriggerTDCMap[pBoard->getBeId()] = std::vector<uint16_t>(fTDCBins,0);
+        BeBoardTriggerTDCMap[pBoard->getId()] = std::vector<uint16_t>(fTDCBins,0);
 
-        ReadNEvents ( pBoard, fNevents );
+        ReadNEvents ( theBoard, fNevents );
 
-        const std::vector<Event*>& events = GetEvents ( pBoard );
+        const std::vector<Event*>& events = GetEvents ( theBoard );
 
         for (auto& cEvent : events)
         {
 
             uint8_t cTDCVal = cEvent->GetTDC();
 
-            if (pBoard->getBoardType() == BoardType::D19C) {
+            if (theBoard->getBoardType() == BoardType::D19C) {
                 // Fix from Mykyta, ONLY the value of the cTDCShiftValue variable have to be changed, NEVER change the formula
                 uint8_t cTDCShiftValue = 1;
                 // don't touch next two lines (!!!)
@@ -100,16 +103,17 @@ void LatencyScan::MeasureTriggerTDC()
             if (cTDCVal >= fTDCBins ) LOG (INFO) << "ERROR, TDC value not within expected range - normalized value is " << +cTDCVal << " - original Value was " << +cEvent->GetTDC() << "; not considering this Event!" <<  std::endl;
             else
             {
-                ++BeBoardTriggerTDCMap[pBoard->getBeId()][cTDCVal];
+                ++BeBoardTriggerTDCMap[pBoard->getId()][cTDCVal];
             }
         }
     }
 
-    for ( BeBoard* pBoard : fBoardVector ){
+    for ( auto pBoard : *fDetectorContainer )
+    {
         TH1F* cTmpHist = dynamic_cast<TH1F*> ( getHist ( pBoard, "triggerTDC" ) );
         for(size_t tdcValue = 0; tdcValue<fTDCBins; ++tdcValue)
         {
-            cTmpHist->SetBinContent(tdcValue+1, BeBoardTriggerTDCMap[pBoard->getBeId()][tdcValue]);
+            cTmpHist->SetBinContent(tdcValue+1, BeBoardTriggerTDCMap[pBoard->getId()][tdcValue]);
         }
     }
 
@@ -128,19 +132,20 @@ std::map<Module*, uint8_t> LatencyScan::ScanLatency ( uint8_t pStartLatency, uin
     // //Fabio - clean END
 
     LatencyVisitor cVisitor (fReadoutChipInterface, 0);
- 
-    for ( BeBoard* pBoard : fBoardVector )
+
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
         for ( uint16_t cLat = pStartLatency; cLat < pStartLatency + pLatencyRange; cLat++ )
         {
             //  Set a Latency Value on all FEs
             cVisitor.setLatency (  cLat );
             this->accept ( cVisitor );
 
-            ReadNEvents ( pBoard, fNevents );
+            ReadNEvents ( theBoard, fNevents );
 
-            const std::vector<Event*>& events = GetEvents ( pBoard );
-            countHitsLat ( pBoard, events, "module_latency", cLat, pStartLatency);
+            const std::vector<Event*>& events = GetEvents ( theBoard );
+            countHitsLat ( theBoard, events, "module_latency", cLat, pStartLatency);
             // done counting hits for all FE's, now update the Histograms
             updateHists ( "module_latency", false );
 
@@ -185,8 +190,9 @@ std::map<Module*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency,
     // Now the actual scan
     LOG (INFO) << "Scanning Stub Latency ... " ;
 
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
         for ( uint8_t cLat = pStartLatency; cLat < pStartLatency + pLatencyRange; cLat++ )
         {
             uint32_t cN = 0;
@@ -194,42 +200,43 @@ std::map<Module*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency,
             uint32_t cNevents = 0 ;
         // Take Data for all Modules
             //here set the stub latency
-            for (auto cReg : getStubLatencyName (pBoard->getBoardType() ) )
-                fBeBoardInterface->WriteBoardReg (pBoard, cReg, cLat);
+            for (auto cReg : getStubLatencyName (theBoard->getBoardType() ) )
+                fBeBoardInterface->WriteBoardReg (theBoard, cReg, cLat);
 
-            fBeBoardInterface->Start(pBoard);
+            fBeBoardInterface->Start(theBoard);
             do
             {
-                uint32_t cNeventsReadBack = ReadData( pBoard );
+                uint32_t cNeventsReadBack = ReadData( theBoard );
                 if( cNeventsReadBack == 0 )
                 {
                     LOG (INFO) << BOLDRED << "..... Read back " << +cNeventsReadBack << " events!! Why?!" << RESET ;
                     continue;
                 }
 
-                const std::vector<Event*>& events = GetEvents ( pBoard );
+                const std::vector<Event*>& events = GetEvents ( theBoard );
                 cNevents += events.size(); 
 
                 // Loop over Events from this Acquisition
                 for ( auto& cEvent : events )
                 {
-                    for ( auto cFe : pBoard->fModuleVector )
-                        cNStubs += countStubs ( cFe, cEvent, "module_stub_latency", cLat );
+                    for(auto cOpticalGroup : *pBoard)
+                        for ( auto cFe : *cOpticalGroup )
+                            cNStubs += countStubs ( static_cast<OuterTrackerModule*>(cFe), cEvent, "module_stub_latency", cLat );
                 }
 
             }while( cNevents < fNevents );
-            fBeBoardInterface->Stop(pBoard);
+            fBeBoardInterface->Stop(theBoard);
             LOG (INFO) << "Stub Latency " << +cLat << " Stubs " << cNStubs  << " Events " << cN ;
 
-            //ReadNEvents ( pBoard, fNevents );
-            //const std::vector<Event*>& events = GetEvents ( pBoard );
+            //ReadNEvents ( theBoard, fNevents );
+            //const std::vector<Event*>& events = GetEvents ( theBoard );
 
             // if(cN <3 ) LOG(INFO) << *cEvent ;
 
             // Loop over Events from this Acquisition
             //for ( auto& cEvent : events )
             //{
-            //    for ( auto cFe : pBoard->fModuleVector )
+            //    for ( auto cFe : theBoard->fModuleVector )
             //        cNStubs += countStubs ( cFe, cEvent, "module_stub_latency", cLat );
             //
             //    cN++;
@@ -281,66 +288,69 @@ void LatencyScan::ScanLatency2D(uint8_t pStartLatency, uint8_t pLatencyRange)
         for ( uint8_t cStubLatency = 0; cStubLatency < cLatency ; cStubLatency++ )
         {
             // Take Data for all Modules
-            for ( BeBoard* pBoard : fBoardVector )
+            for ( auto pBoard : *fDetectorContainer )
             {
+                BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
                 // set a stub latency value on all FEs 
-                for (auto cReg : getStubLatencyName (pBoard->getBoardType() ) )
-                    fBeBoardInterface->WriteBoardReg (pBoard, cReg, cStubLatency);
+                for (auto cReg : getStubLatencyName (theBoard->getBoardType() ) )
+                    fBeBoardInterface->WriteBoardReg (theBoard, cReg, cStubLatency);
 
                 // I need this to normalize the TDC values I get from the Strasbourg FW
                 uint32_t cNevents = 0 ;  
                 uint32_t cNEvents_wHit = 0 ; 
                 uint32_t cNEvents_wStub = 0 ; 
                 uint32_t cNEvents_wBoth = 0; 
-                fBeBoardInterface->Start(pBoard);
+                fBeBoardInterface->Start(theBoard);
                 do
                 {
-                    uint32_t cNeventsReadBack = ReadData( pBoard );
+                    uint32_t cNeventsReadBack = ReadData( theBoard );
                     if( cNeventsReadBack == 0 )
                     {
                         LOG (INFO) << BOLDRED << "..... Read back " << +cNeventsReadBack << " events!! Why?!" << RESET ;
                         continue;
                     }
 
-                    const std::vector<Event*>& events = GetEvents ( pBoard );
+                    const std::vector<Event*>& events = GetEvents ( theBoard );
                     cNevents += events.size(); 
-
-                    for ( auto cFe : pBoard->fModuleVector )
+                    for(auto cOpticalGroup : *pBoard)
                     {
-                        for( auto cEvent : events )
+                        for ( auto cFe : *cOpticalGroup )
                         {
-                            bool cHitFound = false; 
-                            bool cStubFound = false; 
-                            //now loop the channels for this particular event and increment a counter
-                            for ( auto cCbc : cFe->fReadoutChipVector )
+                            for( auto cEvent : events )
                             {
-                                int cHitCounter = cEvent->GetNHits (cCbc->getFeId(), cCbc->getChipId() );
-                                std::vector<Stub> cStubs = cEvent->StubVector (cCbc->getFeId(), cCbc->getChipId());
-                                int cStubCounter = cStubs.size(); 
-
-                                if( cHitCounter == 0 )
+                                bool cHitFound = false; 
+                                bool cStubFound = false; 
+                                //now loop the channels for this particular event and increment a counter
+                                for ( auto cCbc : *cFe )
                                 {
-                                
-                                }
+                                    int cHitCounter = cEvent->GetNHits (cFe->getId(), cCbc->getId() );
+                                    std::vector<Stub> cStubs = cEvent->StubVector (cFe->getId(), cCbc->getId());
+                                    int cStubCounter = cStubs.size(); 
+
+                                    if( cHitCounter == 0 )
+                                    {
+                                    
+                                    }
 
-                                if( cHitCounter > 0 )
-                                    cHitFound = true;
+                                    if( cHitCounter > 0 )
+                                        cHitFound = true;
 
-                                if( cStubCounter > 0 )
-                                    cStubFound = true;
+                                    if( cStubCounter > 0 )
+                                        cStubFound = true;
+                                }
+                                cNEvents_wHit += cHitFound ? 1 : 0 ; 
+                                cNEvents_wStub += cStubFound ? 1 : 0 ; 
+                                cNEvents_wBoth += ( cHitFound && cStubFound ) ? 1 : 0 ; 
                             }
-                            cNEvents_wHit += cHitFound ? 1 : 0 ; 
-                            cNEvents_wStub += cStubFound ? 1 : 0 ; 
-                            cNEvents_wBoth += ( cHitFound && cStubFound ) ? 1 : 0 ; 
+                            TH2D* cTmpHist2D = dynamic_cast<TH2D*> ( getHist ( cFe, "module_latency_2D" ) );
+                            cTmpHist2D->Fill( cStubLatency , cLatency , cNEvents_wBoth ); 
+                            cTmpHist2D->GetZaxis()->SetRangeUser(1,cNevents);
+                            updateHists("module_latency_2D", false );
                         }
-                        TH2D* cTmpHist2D = dynamic_cast<TH2D*> ( getHist ( cFe, "module_latency_2D" ) );
-                        cTmpHist2D->Fill( cStubLatency , cLatency , cNEvents_wBoth ); 
-                        cTmpHist2D->GetZaxis()->SetRangeUser(1,cNevents);
-                        updateHists("module_latency_2D", false );
                     }
                     
                 }while( cNevents < fNevents );
-                fBeBoardInterface->Stop(pBoard);
+                fBeBoardInterface->Stop(theBoard);
 
                 if( cNSteps % 10 == 0 )
                 {
@@ -356,65 +366,68 @@ void LatencyScan::ScanLatency2D(uint8_t pStartLatency, uint8_t pLatencyRange)
     }
 
     // now display a message to the user to let them know what the optimal latencies are for each FE
-    for ( BeBoard* pBoard : fBoardVector )
+    for ( auto pBoard : *fDetectorContainer )
     {
-        for ( auto cFe : pBoard->fModuleVector )
+        for(auto cOpticalGroup : *pBoard)
         {
-            std::pair<uint8_t, uint16_t> cOptimalLatencies;
-            cOptimalLatencies.first = 0 ;
-            cOptimalLatencies.second = 0; 
-            int cMaxNEvents_wBoth = 0 ; 
-     
-            TH2D* cTmpHist2D = dynamic_cast<TH2D*> ( getHist ( cFe, "module_latency_2D" ) );
-
-            for( int cBinX = 1 ; cBinX < cTmpHist2D->GetXaxis()->GetNbins() ; cBinX ++ )
+            for ( auto cFe : *cOpticalGroup )
             {
-                for( int cBinY = 1 ; cBinY < cTmpHist2D->GetYaxis()->GetNbins() ; cBinY ++ )
+                std::pair<uint8_t, uint16_t> cOptimalLatencies;
+                cOptimalLatencies.first = 0 ;
+                cOptimalLatencies.second = 0; 
+                int cMaxNEvents_wBoth = 0 ; 
+        
+                TH2D* cTmpHist2D = dynamic_cast<TH2D*> ( getHist ( cFe, "module_latency_2D" ) );
+
+                for( int cBinX = 1 ; cBinX < cTmpHist2D->GetXaxis()->GetNbins() ; cBinX ++ )
                 {
-                    int cBinContent = cTmpHist2D->GetBinContent( cBinX , cBinY ); 
-                    if( cBinContent >= cMaxNEvents_wBoth )
+                    for( int cBinY = 1 ; cBinY < cTmpHist2D->GetYaxis()->GetNbins() ; cBinY ++ )
                     {
-                        cOptimalLatencies.first = (uint8_t)cTmpHist2D->GetXaxis()->GetBinCenter(cBinX);
-                        cOptimalLatencies.second = (uint16_t)cTmpHist2D->GetYaxis()->GetBinCenter(cBinY);
-                        cMaxNEvents_wBoth = cBinContent;
+                        int cBinContent = cTmpHist2D->GetBinContent( cBinX , cBinY ); 
+                        if( cBinContent >= cMaxNEvents_wBoth )
+                        {
+                            cOptimalLatencies.first = (uint8_t)cTmpHist2D->GetXaxis()->GetBinCenter(cBinX);
+                            cOptimalLatencies.second = (uint16_t)cTmpHist2D->GetYaxis()->GetBinCenter(cBinY);
+                            cMaxNEvents_wBoth = cBinContent;
+                        }
                     }
                 }
-            }
-            
-            // if interested in the tdc phase then do the latency scan (trigger only) with TDC on
-            // scan 4 clock cycles around optimal latency
-            // something fishy here ... needs to be fixed (binning on TDC histogram is weird)
-            // if( !pNoTdc )
-            // {
-            //     // I think I need to re-configure the histogram w/ TDC
-            //     TString cName =  Form ( "h_module_latency_Fe%d", cFe->getFeId() );
-            //     TObject* cObj = gROOT->FindObject ( cName );
-            //     if ( cObj ) delete cObj;
-
-            //     int cLatencyStart = std::max( 0, (int)cOptimalLatencies.second - 2 );
-            //     int cLatencyRange = 4 ; 
-            //     TH1F* cLatHist = new TH1F ( cName, Form ( "Latency FE%d; Latency; # of Hits", cFe->getFeId() ), (cLatencyRange) * fTDCBins, cLatencyStart,  cLatencyStart + (cLatencyRange )  * fTDCBins );
-            //     //modify the axis labels
-            //     uint32_t pLabel = cLatencyStart ;
-
-            //     for (uint32_t cLatency = cLatencyStart; cLatency < cLatencyStart + cLatencyRange; ++cLatency)
-            //     {
-            //         for (uint32_t cPhase = 0; cPhase < fTDCBins; ++cPhase)
-            //         {
-            //             int cBin = 1 + cLatHist->GetXaxis()->FindBin( convertLatencyPhase (cLatencyStart, cLatency, cPhase) );
-            //             if( cBin == 0 )
-            //                 LOG(INFO) << BOLDRED << "!!!! " << +cLatency << " [latency], " << cLatencyStart << " [start latency] " << +cPhase << " [TDC phase] : converted latency " << convertLatencyPhase (cLatencyStart, cLatency, cPhase) <<  RESET ; 
-            //             cLatHist->GetXaxis()->SetBinLabel (cBin, Form ("%d+%d", cLatency, cPhase) );
-            //         }
-            //     }
                 
-            //     ScanLatency ( cLatencyStart , cLatencyRange , false );
-            // }
+                // if interested in the tdc phase then do the latency scan (trigger only) with TDC on
+                // scan 4 clock cycles around optimal latency
+                // something fishy here ... needs to be fixed (binning on TDC histogram is weird)
+                // if( !pNoTdc )
+                // {
+                //     // I think I need to re-configure the histogram w/ TDC
+                //     TString cName =  Form ( "h_module_latency_Fe%d", cFe->getFeId() );
+                //     TObject* cObj = gROOT->FindObject ( cName );
+                //     if ( cObj ) delete cObj;
+
+                //     int cLatencyStart = std::max( 0, (int)cOptimalLatencies.second - 2 );
+                //     int cLatencyRange = 4 ; 
+                //     TH1F* cLatHist = new TH1F ( cName, Form ( "Latency FE%d; Latency; # of Hits", cFe->getFeId() ), (cLatencyRange) * fTDCBins, cLatencyStart,  cLatencyStart + (cLatencyRange )  * fTDCBins );
+                //     //modify the axis labels
+                //     uint32_t pLabel = cLatencyStart ;
+
+                //     for (uint32_t cLatency = cLatencyStart; cLatency < cLatencyStart + cLatencyRange; ++cLatency)
+                //     {
+                //         for (uint32_t cPhase = 0; cPhase < fTDCBins; ++cPhase)
+                //         {
+                //             int cBin = 1 + cLatHist->GetXaxis()->FindBin( convertLatencyPhase (cLatencyStart, cLatency, cPhase) );
+                //             if( cBin == 0 )
+                //                 LOG(INFO) << BOLDRED << "!!!! " << +cLatency << " [latency], " << cLatencyStart << " [start latency] " << +cPhase << " [TDC phase] : converted latency " << convertLatencyPhase (cLatencyStart, cLatency, cPhase) <<  RESET ; 
+                //             cLatHist->GetXaxis()->SetBinLabel (cBin, Form ("%d+%d", cLatency, cPhase) );
+                //         }
+                //     }
+                    
+                //     ScanLatency ( cLatencyStart , cLatencyRange , false );
+                // }
 
-            LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
-            LOG (INFO) << BOLDRED << "For FE" << +cFe->getFeId() << " found optimal latencies to be : " << RESET ; 
-            LOG (INFO) << BOLDRED << "........ Stub Latency of " << +cOptimalLatencies.first << " and a Trigger Latency of " << +cOptimalLatencies.second << RESET; 
-            LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
+                LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
+                LOG (INFO) << BOLDRED << "For FE" << +cFe->getFeId() << " found optimal latencies to be : " << RESET ; 
+                LOG (INFO) << BOLDRED << "........ Stub Latency of " << +cOptimalLatencies.first << " and a Trigger Latency of " << +cOptimalLatencies.second << RESET; 
+                LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
+            }
         }
     }
 
@@ -431,37 +444,39 @@ int LatencyScan::countHitsLat ( BeBoard* pBoard,  const std::vector<Event*> pEve
 {
     
     uint32_t cTotalHits = 0;
-
-    for ( auto cFe : pBoard->fModuleVector )
+    for(auto cOpticalGroup : *pBoard)
     {
-        uint32_t cHitSum = 0;
-        //  get histogram to fill
-        TH1F* cTmpHist = dynamic_cast<TH1F*> ( getHist ( cFe, pHistName ) );
-        for (auto& cEvent : pEventVec)
+        for ( auto cFe : *cOpticalGroup )
         {
-            //first, reset the hit counter - I need separate counters for each event
-            int cHitCounter = 0;
-            
-            for ( auto cCbc : cFe->fReadoutChipVector )
+            uint32_t cHitSum = 0;
+            //  get histogram to fill
+            TH1F* cTmpHist = dynamic_cast<TH1F*> ( getHist ( cFe, pHistName ) );
+            for (auto& cEvent : pEventVec)
             {
-                //now loop the channels for this particular event and increment a counter
-                cHitCounter += cEvent->GetNHits (cCbc->getFeId(), cCbc->getChipId() );
-            }
+                //first, reset the hit counter - I need separate counters for each event
+                int cHitCounter = 0;
+                
+                for ( auto cCbc : *cFe )
+                {
+                    //now loop the channels for this particular event and increment a counter
+                    cHitCounter += cEvent->GetNHits (cFe->getId(), cCbc->getId() );
+                }
+
+                //now I have the number of hits in this particular event for all CBCs and the TDC value
+                
+                cTmpHist->Fill (pParameter, cHitCounter);
+                
+                //if (cHitCounter != 0 ) std::cout << "Found " << cHitCounter << " Hits in this event!" << std::endl;
 
-            //now I have the number of hits in this particular event for all CBCs and the TDC value
-            
-            cTmpHist->Fill (pParameter, cHitCounter);
-            
-            //if (cHitCounter != 0 ) std::cout << "Found " << cHitCounter << " Hits in this event!" << std::endl;
+                //GA: old, potentially buggy code
+                //cTmpHist->Fill (cBin, cHitCounter);
 
-            //GA: old, potentially buggy code
-            //cTmpHist->Fill (cBin, cHitCounter);
+                cHitSum += cHitCounter;
+            }
 
-            cHitSum += cHitCounter;
+            LOG (INFO) << "FE: " << +cFe->getId() << "; Latency " << +pParameter << " clock cycles; Hits " << cHitSum  << "; Events " << fNevents ;
+            cTotalHits += cHitSum;
         }
-
-        LOG (INFO) << "FE: " << +cFe->getFeId() << "; Latency " << +pParameter << " clock cycles; Hits " << cHitSum  << "; Events " << fNevents ;
-        cTotalHits += cHitSum;
     }
 
     return cTotalHits;
@@ -475,10 +490,10 @@ int LatencyScan::countStubs ( Module* pFe,  const Event* pEvent, std::string pHi
     //  get histogram to fill
     TH1F* cTmpHist = dynamic_cast<TH1F*> ( getHist ( pFe, pHistName ) );
 
-    for ( auto cCbc : pFe->fReadoutChipVector )
+    for ( auto cCbc : *pFe )
     {
-        if ( pEvent->StubBit ( cCbc->getFeId(), cCbc->getChipId() ) )
-            cStubCounter += pEvent->StubVector ( cCbc->getFeId(), cCbc->getChipId() ).size();
+        if ( pEvent->StubBit ( pFe->getId(), cCbc->getId() ) )
+            cStubCounter += pEvent->StubVector ( pFe->getId(), cCbc->getId() ).size();
     }
 
     int cBin = cTmpHist->FindBin (pParameter);
diff --git a/tools/MultiplexingSetup.cc b/tools/MultiplexingSetup.cc
index 7a4ec588e..7b43b7c20 100644
--- a/tools/MultiplexingSetup.cc
+++ b/tools/MultiplexingSetup.cc
@@ -22,11 +22,12 @@ void MultiplexingSetup::Initialise ( )
 // Scan multiplexing set-up
 void MultiplexingSetup::Scan()
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Scanning all available backplanes and cards on BeBoard " << +cBoard->getBeBoardId() << RESET;
-        fBeBoardInterface->setBoard ( cBoard->getBeBoardId() );
-        fBeBoardInterface->getBoardInfo(cBoard);
+        uint16_t theBoardId = static_cast<BeBoard*>(cBoard)->getBeBoardId();
+        LOG (INFO) << BOLDBLUE << "Scanning all available backplanes and cards on BeBoard " << +theBoardId << RESET;
+        fBeBoardInterface->setBoard ( theBoardId );
+        fBeBoardInterface->getBoardInfo(static_cast<BeBoard*>(cBoard));
         fAvailableCards = static_cast<D19cFWInterface*>( fBeBoardInterface->getFirmwareInterface())->ScanMultiplexingSetup();
         parseAvailable(false);
         printAvailableCards();
@@ -36,20 +37,22 @@ void MultiplexingSetup::Scan()
 // Disconnect multiplexing set-up
 void MultiplexingSetup::Disconnect()
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Disconnecting all backplanes and cards on BeBoard " << +cBoard->getBeBoardId() << RESET;
-        fBeBoardInterface->setBoard ( cBoard->getBeBoardId() );
-        fBeBoardInterface->getBoardInfo(cBoard);
+        uint16_t theBoardId = static_cast<BeBoard*>(cBoard)->getBeBoardId();
+        LOG (INFO) << BOLDBLUE << "Disconnecting all backplanes and cards on BeBoard " << +theBoardId << RESET;
+        fBeBoardInterface->setBoard ( theBoardId );
+        fBeBoardInterface->getBoardInfo(static_cast<BeBoard*>(cBoard));
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->DisconnectMultiplexingSetup();
     }
 }
 void MultiplexingSetup::ConfigureSingleCard(uint8_t pBackPlaneId, uint8_t pCardId)
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Configuring backplane " << +pBackPlaneId << " card " << +pCardId << " on BeBoard " << +cBoard->getBeBoardId() << RESET;
-        fBeBoardInterface->setBoard ( cBoard->getBeBoardId() );
+        uint16_t theBoardId = static_cast<BeBoard*>(cBoard)->getBeBoardId();
+        LOG (INFO) << BOLDBLUE << "Configuring backplane " << +pBackPlaneId << " card " << +pCardId << " on BeBoard " << +theBoardId << RESET;
+        fBeBoardInterface->setBoard ( theBoardId );
         fAvailableCards = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureMultiplexingSetup( pBackPlaneId, pCardId );
         parseAvailable();
         printAvailableCards();
@@ -57,10 +60,11 @@ void MultiplexingSetup::ConfigureSingleCard(uint8_t pBackPlaneId, uint8_t pCardI
 }
 void MultiplexingSetup::ConfigureAll()
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Configuring all cards on BeBoard " << +cBoard->getBeBoardId() << RESET;
-        fBeBoardInterface->setBoard ( cBoard->getBeBoardId() );
+        uint16_t theBoardId = static_cast<BeBoard*>(cBoard)->getBeBoardId();
+        LOG (INFO) << BOLDBLUE << "Configuring all cards on BeBoard " << +theBoardId << RESET;
+        fBeBoardInterface->setBoard ( theBoardId );
         fAvailableCards = static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ScanMultiplexingSetup();
         parseAvailable(false);
         printAvailableCards();
@@ -75,9 +79,10 @@ void MultiplexingSetup::ConfigureAll()
 }
 void MultiplexingSetup::Power(bool pEnable)
 {
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        LOG (INFO) << BOLDBLUE << "Powering FMCs on " << +cBoard->getBeBoardId() << RESET;
+        uint16_t theBoardId = static_cast<BeBoard*>(cBoard)->getBeBoardId();
+        LOG (INFO) << BOLDBLUE << "Powering FMCs on " << +theBoardId << RESET;
         //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->InitFMCPower();
     } 
 }
diff --git a/tools/OpenFinder.cc b/tools/OpenFinder.cc
index 4d0b044c2..4505ff9fa 100644
--- a/tools/OpenFinder.cc
+++ b/tools/OpenFinder.cc
@@ -113,10 +113,10 @@ void OpenFinder::FindOpens(bool pExternalTrigger)
 
   // Set the antenna delay and compute the corresponding latency start and stop
   // and force the trigger source to be the antenna trigger (5)
-  for (auto &cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    this->fBeBoardInterface->WriteBoardReg(cBoard, "fc7_daq_cnfg.fast_command_block.antenna_trigger_delay_value", fParameters.antennaDelay);
-    this->fBeBoardInterface->WriteBoardReg(cBoard, "fc7_daq_cnfg.fast_command_block.trigger_source", pExternalTrigger ? fParameters.fExternalTriggerSource : fParameters.fAntennaTriggerSource );
+    this->fBeBoardInterface->WriteBoardReg(static_cast<BeBoard*>(cBoard), "fc7_daq_cnfg.fast_command_block.antenna_trigger_delay_value", fParameters.antennaDelay);
+    this->fBeBoardInterface->WriteBoardReg(static_cast<BeBoard*>(cBoard), "fc7_daq_cnfg.fast_command_block.trigger_source", pExternalTrigger ? fParameters.fExternalTriggerSource : fParameters.fAntennaTriggerSource );
   }
   uint16_t cStart = fParameters.antennaDelay - 1;
   uint16_t cStop = fParameters.antennaDelay + (fParameters.latencyRange) + 1;
@@ -153,9 +153,9 @@ void OpenFinder::FindOpens(bool pExternalTrigger)
       auto &cContainer = cContainerVector.at(iLatency);
       uint16_t &cLatency = cListOfLatencies.at(iLatency);
       double averageOccupancy = 0;
-      for (auto &cBoard : this->fBoardVector)
+      for (auto cBoard : *fDetectorContainer)
         averageOccupancy += cContainer->at(cBoard->getIndex())->getSummary<Occupancy, Occupancy>().fOccupancy;
-      averageOccupancy /= fBoardVector.size();
+      averageOccupancy /= fDetectorContainer->size();
       LOG(DEBUG) << BOLDBLUE << "Latency value of " << +cLatency << " I have occupancy of " << averageOccupancy << RESET;
       if (averageOccupancy > maxOccupancy)
       {
@@ -172,23 +172,25 @@ void OpenFinder::FindOpens(bool pExternalTrigger)
     {
         auto& cOccupancy = cMeasurement.at(cBoard->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy;
         LOG (INFO) << BOLDBLUE << "Measured occupancy for a latency of " << bestLatency << " is " << cOccupancy << RESET;
-        for(auto cFe: *cBoard) // for on module - begin 
-        {
-            for(auto cChip: *cFe) // for on chip - begin 
-            {
-                //ReadoutChip* theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex()));
-                std::vector<uint8_t> cOpens(0);
-                std::vector<int> cConnectedChannels = cSearchAntennaMap->second.find( (int)cChip->getId() )->second;
-                for( auto cConnectedChannel : cConnectedChannels )
-                {
-                  auto cOccupancy = cChip->getChannel<Occupancy>(cConnectedChannel).fOccupancy;
-                  LOG (DEBUG) << BOLDBLUE << "\t.. channel " << +cConnectedChannel << " occupancy is " << cOccupancy << RESET;
-                  if( cOccupancy < fParameters.fThreshold ) 
-                    cOpens.push_back( cConnectedChannel );
-                }
-                LOG (INFO) << BOLDBLUE << "Found " << +cOpens.size() << " opens on readout chip with id " << +cChip->getId() << RESET;
-            } // for on chip - end 
-        } // for on module - end 
+        for(auto cOpticalGroup: *cBoard) // for on opticalGroup - begin 
+          for(auto cFe: *cOpticalGroup) // for on module - begin 
+          {
+              for(auto cChip: *cFe) // for on chip - begin 
+              {
+                  //ReadoutChip* theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(cBoard->getIndex())->at(cFe->getIndex())->at(cChip->getIndex()));
+                  std::vector<uint8_t> cOpens(0);
+                  std::vector<int> cConnectedChannels = cSearchAntennaMap->second.find( (int)cChip->getId() )->second;
+                  for( auto cConnectedChannel : cConnectedChannels )
+                  {
+                    auto cOccupancy = cChip->getChannel<Occupancy>(cConnectedChannel).fOccupancy;
+                    LOG (DEBUG) << BOLDBLUE << "\t.. channel " << +cConnectedChannel << " occupancy is " << cOccupancy << RESET;
+                    if( cOccupancy < fParameters.fThreshold ) 
+                      cOpens.push_back( cConnectedChannel );
+                  }
+                  LOG (INFO) << BOLDBLUE << "Found " << +cOpens.size() << " opens on readout chip with id " << +cChip->getId() << RESET;
+              } // for on chip - end 
+          } // for on module - end 
+        } // for on opticalGroup - end 
     } // for on board - end 
   }
   cAntenna.TurnOnAnalogSwitchChannel (9);
diff --git a/tools/PedeNoise.cc b/tools/PedeNoise.cc
index afff7f9a8..ef0e69729 100644
--- a/tools/PedeNoise.cc
+++ b/tools/PedeNoise.cc
@@ -66,37 +66,43 @@ void PedeNoise::disableStubLogic()
 
     for (auto cBoard : *fDetectorContainer)
     {
-        for ( auto cFe : *cBoard )
+        for(auto cOpticalGroup : *cBoard)
         {
-            for ( auto cCbc : *cFe )
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - thus disabling Stub logic for pedestal and noise measurement." << RESET ;
-                fStubLogicValue.at(cBoard->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>() = fReadoutChipInterface->ReadChipReg (static_cast<ReadoutChip*>(cCbc), "Pipe&StubInpSel&Ptwidth");
-                fHIPCountValue .at(cBoard->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>() = fReadoutChipInterface->ReadChipReg (static_cast<ReadoutChip*>(cCbc), "HIP&TestMode"           );
-                fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbc), "Pipe&StubInpSel&Ptwidth", 0x23);
-                fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbc), "HIP&TestMode", 0x00);
+                for ( auto cCbc : *cHybrid )
+                {
+                    LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - thus disabling Stub logic for pedestal and noise measurement." << RESET ;
+                    fStubLogicValue.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>() = fReadoutChipInterface->ReadChipReg (static_cast<ReadoutChip*>(cCbc), "Pipe&StubInpSel&Ptwidth");
+                    fHIPCountValue .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>() = fReadoutChipInterface->ReadChipReg (static_cast<ReadoutChip*>(cCbc), "HIP&TestMode"           );
+                    fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbc), "Pipe&StubInpSel&Ptwidth", 0x23);
+                    fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbc), "HIP&TestMode", 0x00);
+                }
             }
         }
-
     }
 }
 
 void PedeNoise::reloadStubLogic()
 {
     //re-enable stub logic
-    for ( auto cBoard : *fDetectorContainer )
+
+    for (auto cBoard : *fDetectorContainer)
     {
-        for ( auto cFe : *cBoard )
+        for(auto cOpticalGroup : *cBoard)
         {
-            for ( auto cCbc : *cFe )
+            for ( auto cHybrid : *cOpticalGroup )
             {
-                RegisterVector cRegVec;
+                for ( auto cCbc : *cHybrid )
+                {
+                    RegisterVector cRegVec;
 
-                LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - re-enabling stub logic to original value!" << RESET;
-                cRegVec.push_back ({"Pipe&StubInpSel&Ptwidth", fStubLogicValue.at(cBoard->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>()});
-                cRegVec.push_back ({"HIP&TestMode"           , fHIPCountValue .at(cBoard->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>()});
+                    LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - re-enabling stub logic to original value!" << RESET;
+                    cRegVec.push_back ({"Pipe&StubInpSel&Ptwidth", fStubLogicValue.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>()});
+                    cRegVec.push_back ({"HIP&TestMode"           , fHIPCountValue .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cCbc->getIndex())->getSummary<uint16_t>()});
 
-                fReadoutChipInterface->WriteChipMultReg (static_cast<Cbc*>(cCbc), cRegVec);
+                    fReadoutChipInterface->WriteChipMultReg (static_cast<Cbc*>(cCbc), cRegVec);
+                }
             }
         }
     }
@@ -198,29 +204,31 @@ void PedeNoise::Validate ( uint32_t pNoiseStripThreshold, uint32_t pMultiple )
 
     for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto cFe : *cBoard )
+        for(auto cOpticalGroup : *cBoard)
         {
-            // std::cout << __PRETTY_FUNCTION__ << " The Module Occupancy = " << theOccupancyContainer.at(cBoard->getIndex())->at(cFe->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy << std::endl;
-
-            for ( auto cCbc : *cFe )
+            for ( auto cFe : *cOpticalGroup )
             {
-                RegisterVector cRegVec;
+                // std::cout << __PRETTY_FUNCTION__ << " The Module Occupancy = " << theOccupancyContainer.at(cBoard->getIndex())->at(cFe->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy << std::endl;
 
-                for (uint32_t iChan = 0; iChan < NCHANNELS; iChan++)
+                for ( auto cCbc : *cFe )
                 {
-                    float occupancy = theOccupancyContainer.at(cBoard->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getChannel<Occupancy>(iChan).fOccupancy;
-                    if( occupancy > float ( pNoiseStripThreshold * 0.001 ) )
+                    RegisterVector cRegVec;
+
+                    for (uint32_t iChan = 0; iChan < NCHANNELS; iChan++)
                     {
-                        char cRegName[11];
-                        sprintf(cRegName, "Channel%03d", iChan + 1 );
-                        // cRegName = Form ( "Channel%03d", iChan + 1 );
-                        cRegVec.push_back ({cRegName, 0xFF });
-                        LOG (INFO) << RED << "Found a noisy channel on CBC " << +cCbc->getId() << " Channel " << iChan  << " with an occupancy of " << occupancy << "; setting offset to " << +0xFF << RESET ;
+                        float occupancy = theOccupancyContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cFe->getIndex())->at(cCbc->getIndex())->getChannel<Occupancy>(iChan).fOccupancy;
+                        if( occupancy > float ( pNoiseStripThreshold * 0.001 ) )
+                        {
+                            char cRegName[11];
+                            sprintf(cRegName, "Channel%03d", iChan + 1 );
+                            // cRegName = Form ( "Channel%03d", iChan + 1 );
+                            cRegVec.push_back ({cRegName, 0xFF });
+                            LOG (INFO) << RED << "Found a noisy channel on CBC " << +cCbc->getId() << " Channel " << iChan  << " with an occupancy of " << occupancy << "; setting offset to " << +0xFF << RESET ;
+                        }
                     }
-                }
-
-                fReadoutChipInterface->WriteChipMultReg (static_cast<Cbc*>(cCbc), cRegVec);
 
+                    fReadoutChipInterface->WriteChipMultReg (static_cast<Cbc*>(cCbc), cRegVec);
+                }
             }
         }
 
@@ -247,13 +255,16 @@ uint16_t PedeNoise::findPedestal (bool forceAllChannels)
 
     for (auto cBoard : *fDetectorContainer)
     {
-        for ( auto cFe : *cBoard )
+        for(auto cOpticalGroup : *cBoard)
         {
-            for ( auto cCbc : *cFe )
+            for ( auto cFe : *cOpticalGroup )
             {
-                uint16_t tmpVthr = (static_cast<ReadoutChip*>(cCbc)->getReg("VCth1") + (static_cast<ReadoutChip*>(cCbc)->getReg("VCth2")<<8));
-                cMean+=tmpVthr;
-                ++nCbc;
+                for ( auto cCbc : *cFe )
+                {
+                    uint16_t tmpVthr = (static_cast<ReadoutChip*>(cCbc)->getReg("VCth1") + (static_cast<ReadoutChip*>(cCbc)->getReg("VCth2")<<8));
+                    cMean+=tmpVthr;
+                    ++nCbc;
+                }
             }
         }
     }
@@ -376,26 +387,29 @@ void PedeNoise::extractPedeNoise ()
 
         for ( auto board : *fDetectorContainer)
         {
-            for ( auto module : *board)
+            for ( auto opticalGroup : *board)
             {
-                for ( auto chip : *module )
+                for ( auto hybrid : *opticalGroup)
                 {
-                    for(uint8_t iChannel=0; iChannel<chip->size(); ++iChannel)
+                    for ( auto chip : *hybrid )
                     {
-                        if(!fChannelGroupHandler->allChannelGroup()->isChannelEnabled(iChannel)) continue;
-                        float previousOccupancy = (previousIterator)->second->at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
-                        float currentOccupancy  = mIt->second->at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
-                        float binCenter = (mIt->first + (previousIterator)->first)/2.;
+                        for(uint8_t iChannel=0; iChannel<chip->size(); ++iChannel)
+                        {
+                            if(!fChannelGroupHandler->allChannelGroup()->isChannelEnabled(iChannel)) continue;
+                            float previousOccupancy = (previousIterator)->second->at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
+                            float currentOccupancy  = mIt->second->at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
+                            float binCenter = (mIt->first + (previousIterator)->first)/2.;
 
-                        fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fThreshold +=
-                            binCenter * (previousOccupancy - currentOccupancy);
+                            fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fThreshold +=
+                                binCenter * (previousOccupancy - currentOccupancy);
 
-                        fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fNoise +=
-                            binCenter * binCenter * (previousOccupancy - currentOccupancy);
+                            fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fNoise +=
+                                binCenter * binCenter * (previousOccupancy - currentOccupancy);
 
-                        fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fThresholdError +=
-                            previousOccupancy - currentOccupancy;
+                            fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getChannel<ThresholdAndNoise>(iChannel).fThresholdError +=
+                                previousOccupancy - currentOccupancy;
 
+                        }
                     }
                 }
             }
@@ -409,18 +423,21 @@ void PedeNoise::extractPedeNoise ()
     
     for ( auto board : fThresholdAndNoiseContainer)
     {
-        for ( auto module : *board)
+        for ( auto opticalGroup : *board)
         {
-            for ( auto chip : *module )
+            for ( auto module : *opticalGroup)
             {
-                for(uint8_t iChannel=0; iChannel<chip->size(); ++iChannel)
+                for ( auto chip : *module )
                 {
-                    if(!fChannelGroupHandler->allChannelGroup()->isChannelEnabled(iChannel)) continue;
-                    chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold/=chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError;
-                    chip->getChannel<ThresholdAndNoise>(iChannel).fNoise/=chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError;
-                    chip->getChannel<ThresholdAndNoise>(iChannel).fNoise = sqrt(chip->getChannel<ThresholdAndNoise>(iChannel).fNoise - (chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold * chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold));
-                    chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError = 1;
-                    chip->getChannel<ThresholdAndNoise>(iChannel).fNoiseError = 1;
+                    for(uint8_t iChannel=0; iChannel<chip->size(); ++iChannel)
+                    {
+                        if(!fChannelGroupHandler->allChannelGroup()->isChannelEnabled(iChannel)) continue;
+                        chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold/=chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError;
+                        chip->getChannel<ThresholdAndNoise>(iChannel).fNoise/=chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError;
+                        chip->getChannel<ThresholdAndNoise>(iChannel).fNoise = sqrt(chip->getChannel<ThresholdAndNoise>(iChannel).fNoise - (chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold * chip->getChannel<ThresholdAndNoise>(iChannel).fThreshold));
+                        chip->getChannel<ThresholdAndNoise>(iChannel).fThresholdError = 1;
+                        chip->getChannel<ThresholdAndNoise>(iChannel).fNoiseError = 1;
+                    }
                 }
             }
         }
@@ -444,23 +461,26 @@ void PedeNoise::producePedeNoisePlots()
 
 void PedeNoise::setThresholdtoNSigma (BoardContainer* board, uint32_t pNSigma)
 {
-    for ( auto module : *board)
+    for ( auto opticalGroup : *board)
     {
-        for ( auto chip : *module )
+        for ( auto hybrid : *opticalGroup)
         {
-            uint32_t cCbcId = chip->getId();
-            
-            uint16_t cPedestal = round (fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold);
-            uint16_t cNoise    = round (fThresholdAndNoiseContainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fNoise);
-            int cDiff = -pNSigma * cNoise;
-            uint16_t cValue = cPedestal + cDiff;
+            for ( auto chip : *hybrid )
+            {
+                uint32_t cCbcId = chip->getId();
+                
+                uint16_t cPedestal = round (fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold);
+                uint16_t cNoise    = round (fThresholdAndNoiseContainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fNoise);
+                int cDiff = -pNSigma * cNoise;
+                uint16_t cValue = cPedestal + cDiff;
 
 
-            if (pNSigma > 0) LOG (INFO) << "Changing Threshold on CBC " << +cCbcId << " by " << cDiff << " to " << cPedestal + cDiff << " VCth units to supress noise!" ;
-            else LOG (INFO) << "Changing Threshold on CBC " << +cCbcId << " back to the pedestal at " << +cPedestal ;
+                if (pNSigma > 0) LOG (INFO) << "Changing Threshold on CBC " << +cCbcId << " by " << cDiff << " to " << cPedestal + cDiff << " VCth units to supress noise!" ;
+                else LOG (INFO) << "Changing Threshold on CBC " << +cCbcId << " back to the pedestal at " << +cPedestal ;
 
-            ThresholdVisitor cThresholdVisitor (fReadoutChipInterface, cValue);
-            static_cast<ReadoutChip*>(chip)->accept (cThresholdVisitor);
+                ThresholdVisitor cThresholdVisitor (fReadoutChipInterface, cValue);
+                static_cast<ReadoutChip*>(chip)->accept (cThresholdVisitor);
+            }
         }
     }
 }
diff --git a/tools/PedestalEqualization.cc b/tools/PedestalEqualization.cc
index edcb827b4..52d3064d4 100644
--- a/tools/PedestalEqualization.cc
+++ b/tools/PedestalEqualization.cc
@@ -55,28 +55,31 @@ void PedestalEqualization::Initialise ( bool pAllChan, bool pDisableStubLogic )
 
         for(auto board : *fDetectorContainer)
         {
-            for(auto module: *board)
+            for(auto opticalGroup : *board)
             {
-                for(auto chip: *module)
+                for(auto hybrid: *opticalGroup)
                 {
-                    ReadoutChip *theChip = static_cast<ReadoutChip*>(chip);
-                    //if it is a CBC3, disable the stub logic for this procedure
-                    if( theChip->getFrontEndType() == FrontEndType::CBC3) 
+                    for(auto chip: *hybrid)
                     {
-                        LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - thus disabling Stub logic for offset tuning for CBC " << +chip->getId() << RESET; 
-                    fStubLogicCointainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>() 
-                        = fReadoutChipInterface->ReadChipReg (theChip, "Pipe&StubInpSel&Ptwidth");
-
-                    uint8_t value = fReadoutChipInterface->ReadChipReg (theChip, "HIP&TestMode");
-                    fHIPCountCointainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>() = value;
-                        static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( theChip, false, true , 0);
+                        ReadoutChip *theChip = static_cast<ReadoutChip*>(chip);
+                        //if it is a CBC3, disable the stub logic for this procedure
+                        if( theChip->getFrontEndType() == FrontEndType::CBC3) 
+                        {
+                            LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - thus disabling Stub logic for offset tuning for CBC " << +chip->getId() << RESET; 
+                        fStubLogicCointainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<uint8_t>() 
+                            = fReadoutChipInterface->ReadChipReg (theChip, "Pipe&StubInpSel&Ptwidth");
+
+                        uint8_t value = fReadoutChipInterface->ReadChipReg (theChip, "HIP&TestMode");
+                        fHIPCountCointainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(hybrid->getIndex())->at(chip->getIndex())->getSummary<uint8_t>() = value;
+                            static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( theChip, false, true , 0);
+                    }
+                        else
+                            LOG (INFO) << BOLDBLUE << "Not a CBC3 .. so doing nothing with stub logic." << RESET; 
+                    }
                 }
-                    else
-                        LOG (INFO) << BOLDBLUE << "Not a CBC3 .. so doing nothing with stub logic." << RESET; 
             }
         }
     }
-    }
 
     LOG (INFO) << "Parsed settings:" ;
     LOG (INFO) << "	Nevents = " << fEventsPerPoint ;
@@ -113,19 +116,22 @@ void PedestalEqualization::FindVplus()
 
     for(auto board : theVcthContainer) //for on boards - begin 
     {
-        for(auto module: *board) // for on module - begin 
+        for(auto opticalGroup : *board) // for on opticalGroup - begin 
         {
-            nCbc += module->size();
-            for(auto chip: *module) // for on chip - begin 
+            for(auto module: *opticalGroup) // for on module - begin 
             {
-                ReadoutChip* theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(board->getIndex())->at(module->getIndex())->at(chip->getIndex()));
-                uint16_t tmpVthr = (theChip->getReg("VCth1") + (theChip->getReg("VCth2")<<8));
-                chip->getSummary<uint16_t>()=tmpVthr;
-
-                LOG (INFO) << GREEN << "VCth value for BeBoard " << +board->getId() << " Module " << +module->getId() << " CBC " << +chip->getId() << " = " << tmpVthr << RESET;
-                cMeanValue+=tmpVthr;
-            } // for on chip - end 
-        } // for on module - end 
+                nCbc += module->size();
+                for(auto chip: *module) // for on chip - begin 
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(board->getIndex())->at(opticalGroup->getIndex())->at(module->getIndex())->at(chip->getIndex()));
+                    uint16_t tmpVthr = (theChip->getReg("VCth1") + (theChip->getReg("VCth2")<<8));
+                    chip->getSummary<uint16_t>()=tmpVthr;
+
+                    LOG (INFO) << GREEN << "VCth value for BeBoard " << +board->getId() << " OpticalGroup " << +opticalGroup->getId()  << " Module " << +module->getId() << " CBC " << +chip->getId() << " = " << tmpVthr << RESET;
+                    cMeanValue+=tmpVthr;
+                } // for on chip - end 
+            } // for on module - end
+        } // for on opticalGroup - end
     } // for on board - end 
 
     #ifdef __USE_ROOT__
@@ -162,38 +168,41 @@ void PedestalEqualization::FindOffsets()
 
     for (auto board : theOffsetsCointainer) //for on boards - begin
     {
-        for (auto module : *board) // for on module - begin
+        for (auto opticalGroup : *board) // for on opticalGroup - begin
         {
-            for (auto chip : *module) // for on chip - begin
+            for (auto module : *opticalGroup) // for on module - begin
             {
-                  if (fDisableStubLogic)
-                  {
-                    ReadoutChip *theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(board->getIndex())->at(module->getIndex())->at(chip->getIndex()));
+                for (auto chip : *module) // for on chip - begin
+                {
+                    if (fDisableStubLogic)
+                    {
+                        ReadoutChip *theChip = static_cast<ReadoutChip*>(fDetectorContainer->at(board->getIndex())->at(opticalGroup->getIndex())->at(module->getIndex())->at(chip->getIndex()));
 
-                    uint8_t stubLogicValue = fStubLogicCointainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>();
-                    fReadoutChipInterface->WriteChipReg (theChip, "Pipe&StubInpSel&Ptwidth", stubLogicValue);
+                        uint8_t stubLogicValue = fStubLogicCointainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>();
+                        fReadoutChipInterface->WriteChipReg (theChip, "Pipe&StubInpSel&Ptwidth", stubLogicValue);
 
-                    uint8_t HIPCountValue = fHIPCountCointainer.at(board->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>();
-                    fReadoutChipInterface->WriteChipReg (theChip, "HIP&TestMode", HIPCountValue);
-                  }
+                        uint8_t HIPCountValue = fHIPCountCointainer.at(board->getIndex())->at(opticalGroup->getIndex())->at(module->getIndex())->at(chip->getIndex())->getSummary<uint8_t>();
+                        fReadoutChipInterface->WriteChipReg (theChip, "HIP&TestMode", HIPCountValue);
+                    }
 
 
-                unsigned int channelNumber = 1;
-                int cMeanOffset=0;
+                    unsigned int channelNumber = 1;
+                    int cMeanOffset=0;
 
-                for (auto &channel : *chip->getChannelContainer<uint8_t>()) // for on channel - begin
-                {
-                    char charRegName[20];
-                    sprintf(charRegName, "Channel%03d", channelNumber++);
-                    std::string cRegName = charRegName;
-                    channel = static_cast<ReadoutChip *>(fDetectorContainer->at(board->getIndex())->at(module->getIndex())->at(chip->getIndex()))->getReg(cRegName);
-                    cMeanOffset += channel;
-                } 
-
-                LOG (INFO) << BOLDRED << "Mean offset on CBC" << +chip->getId() << " is : " << (cMeanOffset)/(double)NCHANNELS << " Vcth units." << RESET;
-            } // for on chip - end
-        }     // for on module - end
-    }         // for on board - end
+                    for (auto &channel : *chip->getChannelContainer<uint8_t>()) // for on channel - begin
+                    {
+                        char charRegName[20];
+                        sprintf(charRegName, "Channel%03d", channelNumber++);
+                        std::string cRegName = charRegName;
+                        channel = static_cast<ReadoutChip *>(fDetectorContainer->at(board->getIndex())->at(opticalGroup->getIndex())->at(module->getIndex())->at(chip->getIndex()))->getReg(cRegName);
+                        cMeanOffset += channel;
+                    } 
+
+                    LOG (INFO) << BOLDRED << "Mean offset on CBC" << +chip->getId() << " is : " << (cMeanOffset)/(double)NCHANNELS << " Vcth units." << RESET;
+                } // for on chip - end
+            }     // for on module - end
+        }         // for on opticalGroup - end
+    }             // for on board - end
 
     #ifdef __USE_ROOT__
         fDQMHistogramPedestalEqualization.fillOccupancyPlots(theOccupancyContainer);
diff --git a/tools/PulseShape.cc b/tools/PulseShape.cc
index 9db2e2755..23ea51fe5 100644
--- a/tools/PulseShape.cc
+++ b/tools/PulseShape.cc
@@ -16,59 +16,62 @@ void PulseShape::Initialize()
 
     std::cerr << "void PulseShape::Initialize()"  ;
 
-    for ( auto cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
     	LOG(INFO) << "Loop for board()";
-        uint32_t cBoardId = cBoard->getBeId();
+        uint32_t cBoardId = cBoard->getId();
         std::cerr << "cBoardId = " << cBoardId ;
         LOG(INFO) << "Before reading board parameter()";
         //fDelayAfterPulse = fBeBoardInterface->ReadBoardReg (cBoard, getDelAfterTPString ( cBoard->getBoardType() ) );
         fDelayAfterPulse = 196;
         LOG(INFO) << "After reading board parameter()";
 
-        for ( auto cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
-		
-    	    LOG(INFO) << "Certain board()";
-            uint32_t cFeId = cFe->getFeId();
-            std::cerr << "cFeId = " << cFeId ;
-            fType = cFe->getFrontEndType();
-
-            for ( auto& cCbc : cFe->fReadoutChipVector )
+            for ( auto cFe : *cOpticalGroup)
             {
-                uint16_t cMaxValue = 1023;
-                uint32_t cCbcId = cCbc->getChipId();
-                std::cerr << "cCbcId = " << cCbcId ;
-                fNCbc++;
-                // Create the Canvas to draw
-                TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%dcbc%d", cFeId, cCbcId ), Form ( "FE%dCBC%d  Online Canvas", cFeId, cCbcId ) );
-                ctmpCanvas->Divide ( 2, 1 );
-                fCanvasMap[cCbc] = ctmpCanvas;
-
-                //should set the canvas frames sane!
-		int cLow = ( fDelayAfterPulse + 3 ) * 25;
-                int cHigh = ( fDelayAfterPulse + 8 ) * 25;
-                //TH2I* cFrame = new TH2I ( "cFrame", "PulseShape; Delay [ns]; Amplitude [VCth]", 350, cLow, cHigh, cMaxValue, 0, cMaxValue );
-		TH2I* cFrame = new TH2I ( "cFrame", "PulseShape; Delay [ns]; Amplitude [VCth]", 350, 0, cHigh-cLow, cMaxValue, 0, cMaxValue ); //Jarne
-                cFrame->SetStats ( false );
-                ctmpCanvas->cd ( 2 );
-                cFrame->Draw( );
-                bookHistogram ( cCbc, "frame", cFrame );
-                // Create Multigraph Object for each CBC
-                TString cName =  Form ( "g_cbc_pulseshape_MultiGraph_Fe%dCbc%d", cFeId, cCbcId );
-                TObject* cObj = gROOT->FindObject ( cName );
-
-                if ( cObj ) delete cObj;
-
-                TMultiGraph* cMultiGraph = new TMultiGraph();
-                cMultiGraph->SetName ( cName );
-                bookHistogram ( cCbc, "cbc_pulseshape", cMultiGraph );
-                cName = Form ( "f_cbc_pulse_Fe%dCbc%d", cFeId, cCbcId );
-                cObj = gROOT->FindObject ( cName );
-
-                if ( cObj ) delete cObj;
-            }
+            
+                LOG(INFO) << "Certain board()";
+                uint32_t cFeId = cFe->getId();
+                std::cerr << "cFeId = " << cFeId ;
+                fType = static_cast<OuterTrackerModule*>(cFe)->getFrontEndType();
+
+                for ( auto cCbc : *cFe)
+                {
+                    uint16_t cMaxValue = 1023;
+                    uint32_t cCbcId = cCbc->getId();
+                    std::cerr << "cCbcId = " << cCbcId ;
+                    fNCbc++;
+                    // Create the Canvas to draw
+                    TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%dcbc%d", cFeId, cCbcId ), Form ( "FE%dCBC%d  Online Canvas", cFeId, cCbcId ) );
+                    ctmpCanvas->Divide ( 2, 1 );
+                    fCanvasMap[cCbc] = ctmpCanvas;
+
+                    //should set the canvas frames sane!
+            int cLow = ( fDelayAfterPulse + 3 ) * 25;
+                    int cHigh = ( fDelayAfterPulse + 8 ) * 25;
+                    //TH2I* cFrame = new TH2I ( "cFrame", "PulseShape; Delay [ns]; Amplitude [VCth]", 350, cLow, cHigh, cMaxValue, 0, cMaxValue );
+            TH2I* cFrame = new TH2I ( "cFrame", "PulseShape; Delay [ns]; Amplitude [VCth]", 350, 0, cHigh-cLow, cMaxValue, 0, cMaxValue ); //Jarne
+                    cFrame->SetStats ( false );
+                    ctmpCanvas->cd ( 2 );
+                    cFrame->Draw( );
+                    bookHistogram ( cCbc, "frame", cFrame );
+                    // Create Multigraph Object for each CBC
+                    TString cName =  Form ( "g_cbc_pulseshape_MultiGraph_Fe%dCbc%d", cFeId, cCbcId );
+                    TObject* cObj = gROOT->FindObject ( cName );
+
+                    if ( cObj ) delete cObj;
+
+                    TMultiGraph* cMultiGraph = new TMultiGraph();
+                    cMultiGraph->SetName ( cName );
+                    bookHistogram ( cCbc, "cbc_pulseshape", cMultiGraph );
+                    cName = Form ( "f_cbc_pulse_Fe%dCbc%d", cFeId, cCbcId );
+                    cObj = gROOT->FindObject ( cName );
+
+                    if ( cObj ) delete cObj;
+                }
 
+            }
         }
     }
 
@@ -141,25 +144,29 @@ void PulseShape::ScanVcth ( uint32_t pDelay , int cLow)
         int cNHits = 0;
 
         // Take Data for all Modules
-        for ( BeBoard* pBoard : fBoardVector )
+        for ( auto pBoard : *fDetectorContainer )
         {
-            for (Module* cFe : pBoard->fModuleVector)
+            BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
+            for(auto cOpticalGroup : *pBoard)
             {
-                cVisitor.setThreshold (cVcth);
-                cFe->accept (cVisitor);
+                for (auto cFe : *cOpticalGroup)
+                {
+                    cVisitor.setThreshold (cVcth);
+                    static_cast<OuterTrackerModule*>(cFe)->accept (cVisitor);
+                }
             }
 
 	    //LOG(INFO) << "Reading N Events";
-            ReadNEvents ( pBoard, fNevents );
+            ReadNEvents ( theBoard, fNevents );
 	    //LOG(INFO) << "End Reading N Events";
-            const std::vector<Event*>& events = GetEvents ( pBoard );
+            const std::vector<Event*>& events = GetEvents ( theBoard );
             if (events.empty())LOG (INFO) << " EMPTY EVENT VECTOR !!!" ;
            // LOG (INFO) <<"events size, VCTH value " << events.size()<< "  "<< (uint16_t) cVcth;
            // int iii=0;
             for ( auto& cEvent : events ){
                 //LOG (INFO) <<"EVENT ID "<< iii;
                 //iii++;
-                cNHits += fillVcthHist ( pBoard, cEvent, cVcth );
+                cNHits += fillVcthHist ( theBoard, cEvent, cVcth );
             }
             cNthAcq++;
 
@@ -365,14 +372,14 @@ void PulseShape::setDelayAndTesGroup ( uint32_t pDelay )
     LOG (INFO) << "cCoarseDelay: " << +cCoarseDelay ;
     LOG (INFO) << "Current Time: " << +pDelay ;
 
-    for (BeBoard* pBoard : fBoardVector)
+    for (auto pBoard : *fDetectorContainer)
     {
         //potentially have to reset the IC FW commissioning cycle state machine?
 
         LOG(INFO) << "Writing the delay values to the board";
 	//for (auto cReg : getDelAfterTPString (pBoard->getBoardType() ) )
         //        fBeBoardInterface->WriteBoardReg (pBoard, cReg, cCoarseDelay);
-	fBeBoardInterface->WriteBoardReg(pBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse", cCoarseDelay);
+	fBeBoardInterface->WriteBoardReg(static_cast<BeBoard*>(pBoard), "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse", cCoarseDelay);
     }
 
     LOG(INFO) << "Writing fine delay and test group, i2c...";
@@ -387,28 +394,29 @@ uint32_t PulseShape::fillVcthHist ( BeBoard* pBoard, Event* pEvent, uint32_t pVc
     uint32_t cHits = 0;
 
     // Loop over Events from this Acquisition
-    for ( auto cFe : pBoard->fModuleVector )
+    for(auto cOpticalGroup : *pBoard)
     {
-        for ( auto cCbc : cFe->fReadoutChipVector )
+        for ( auto cFe : *cOpticalGroup )
         {
-            //  get histogram to fill
-            auto cChannelVector = fChannelMap.find ( cCbc );
-
-            if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel vector mapped to this CBC ( " << +cCbc->getChipId() << " )" ;
-            else
+            for ( auto cCbc : *cFe )
             {
-                for ( auto& cChannel : cChannelVector->second )
+                //  get histogram to fill
+                auto cChannelVector = fChannelMap.find ( cCbc );
+
+                if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel vector mapped to this CBC ( " << +cCbc->getId() << " )" ;
+                else
                 {
-                    if ( pEvent->DataBit ( cFe->getFeId(), cCbc->getChipId(), cChannel->fChannelId - 1 ) )
+                    for ( auto& cChannel : cChannelVector->second )
                     {
-                        cChannel->fillHist ( pVcth );
-                        cHits++;
+                        if ( pEvent->DataBit ( cFe->getId(), cCbc->getId(), cChannel->fChannelId - 1 ) )
+                        {
+                            cChannel->fillHist ( pVcth );
+                            cHits++;
+                        }
                     }
                 }
             }
         }
-
-        return cHits;
     }
     return cHits;
 }
@@ -534,33 +542,36 @@ void PulseShape::setSystemTestPulse ( uint8_t pTPAmplitude )
 
     this->accept ( cWriter );
 
-    for ( auto& cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        uint32_t cBoardId = cBoard->getBeId();
-
-        for ( auto& cFe : cBoard->fModuleVector )
+        uint32_t cBoardId = cBoard->getId();
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-
-            for ( auto& cCbc : cFe->fReadoutChipVector )
+            uint32_t cOpticalGroupId = cOpticalGroup->getId();
+            for ( auto cFe : *cOpticalGroup)
             {
-                std::vector<Channel*> cChannelVector;
-                uint32_t cCbcId = cCbc->getChipId();
-                int cMakerColor = 1;
+                uint32_t cFeId = cFe->getId();
 
-                for ( auto& cChannelId : fChannelVector )
+                for ( auto cCbc : *cFe )
                 {
-                    Channel* cChannel = new Channel ( cBoardId, cFeId, cCbcId, cChannelId );
-                    TString cName =  Form ( "g_cbc_pulseshape_Fe%dCbc%d_Channel%d", cFeId, cCbcId, cChannelId );
-                    cChannel->initializePulse ( cName );
-                    cChannelVector.push_back ( cChannel );
-                    cChannel->fPulse->SetMarkerColor ( cMakerColor );
-                    cMakerColor++;
-                    TMultiGraph* cTmpGraph = static_cast<TMultiGraph*> ( getHist ( cCbc, "cbc_pulseshape" ) );
-                    cTmpGraph->Add ( cChannel->fPulse, "lp" );
-                }
+                    std::vector<Channel*> cChannelVector;
+                    uint32_t cCbcId = cCbc->getId();
+                    int cMakerColor = 1;
 
-                fChannelMap[cCbc] = cChannelVector;
+                    for ( auto& cChannelId : fChannelVector )
+                    {
+                        Channel* cChannel = new Channel ( cBoardId, cOpticalGroupId, cFeId, cCbcId, cChannelId );
+                        TString cName =  Form ( "g_cbc_pulseshape_Fe%dCbc%d_Channel%d", cFeId, cCbcId, cChannelId );
+                        cChannel->initializePulse ( cName );
+                        cChannelVector.push_back ( cChannel );
+                        cChannel->fPulse->SetMarkerColor ( cMakerColor );
+                        cMakerColor++;
+                        TMultiGraph* cTmpGraph = static_cast<TMultiGraph*> ( getHist ( cCbc, "cbc_pulseshape" ) );
+                        cTmpGraph->Add ( cChannel->fPulse, "lp" );
+                    }
+
+                    fChannelMap[cCbc] = cChannelVector;
+                }
             }
         }
     }
diff --git a/tools/PulseShape.h b/tools/PulseShape.h
index 93eae0b1f..08b5768ba 100644
--- a/tools/PulseShape.h
+++ b/tools/PulseShape.h
@@ -36,7 +36,7 @@ using namespace Ph2_System;
  * \class PulseShape
  * \brief Class to reconstruct pulse shape
  */
-typedef std::map<Ph2_HwDescription::Chip*, std::vector<Channel*> > ChannelMap;
+typedef std::map<ChipContainer*, std::vector<Channel*> > ChannelMap;
 
 class PulseShape : public Tool
 {
diff --git a/tools/RD53ClockDelay.cc b/tools/RD53ClockDelay.cc
index dbee133f6..3d17bac3b 100644
--- a/tools/RD53ClockDelay.cc
+++ b/tools/RD53ClockDelay.cc
@@ -30,7 +30,7 @@ void ClockDelay::ConfigureCalibration ()
   nEvents        = this->findValueInSettings("nEvents");
   doFast         = this->findValueInSettings("DoFast");
   startValue     = 0;
-  stopValue      = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY"))+1) - 1;
+  stopValue      = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY"))+1) - 1;
   doDisplay      = this->findValueInSettings("DisplayHisto");
   doUpdateChip   = this->findValueInSettings("UpdateChipCfg");
   saveBinaryData = this->findValueInSettings("SaveBinaryData");
@@ -54,10 +54,10 @@ void ClockDelay::ConfigureCalibration ()
   // ##########################
   // # Clock register masking #
   // ##########################
-  shiftData = static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_DATA_DELAY");
-  saveData = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY")) -
-    (RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY")) << shiftData);
-  maxDelay = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY"));
+  shiftData = static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_DATA_DELAY");
+  saveData = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY")) -
+    (RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY")) << shiftData);
+  maxDelay = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("CLK_DATA_DELAY_CLK_DELAY"));
 
 
   // #######################
@@ -147,12 +147,13 @@ void ClockDelay::run ()
   // # Run Latency #
   // ###############
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY");
-          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY", val & saveData, true);
-        }
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          {
+            auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY");
+            this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY", val & saveData, true);
+          }
   la.run();
   la.analyze();
 
@@ -164,12 +165,13 @@ void ClockDelay::run ()
   // # Set Initial latency #
   // #######################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
-          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency - 1, true);
-        }
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          {
+            auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
+            this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency - 1, true);
+          }
 
 
   // ###############################
@@ -180,12 +182,13 @@ void ClockDelay::run ()
       std::vector<uint16_t> halfDacList(dacList.begin() + i*(dacList.end() - dacList.begin()) / 2, dacList.begin() + (i+1)*(dacList.end() - dacList.begin()) / 2);
 
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
-            {
-              auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency + i, true);
-            }
+        for(auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
+                  {
+                    auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
+                    this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency + i, true);
+                  }
 
       ClockDelay::scanDac("CLK_DATA_DELAY", halfDacList, nEvents, &theOccContainer);
     }
@@ -227,41 +230,42 @@ void ClockDelay::analyze ()
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theClockDelayContainer);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        {
-          auto best   = 0.;
-          auto regVal = 0;
-
-          for (auto i = 0u; i < dacList.size(); i++)
-            {
-              auto current = theOccContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<ClkDelaySize>>().data[i];
-              if (current > best)
-                {
-                  regVal = dacList[i];
-                  best   = current;
-                }
-            }
-
-          LOG (INFO) << GREEN << "Best delay for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                     << BOLDYELLOW << regVal << RESET << GREEN << " (1.5625 ns) computed over two bx" << RESET;
-          LOG (INFO) << GREEN << "New delay dac value for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                     << BOLDYELLOW << (regVal & maxDelay) << RESET;
-
-
-          // ####################################################
-          // # Fill delay container and download new DAC values #
-          // ####################################################
-          theClockDelayContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
-          auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY");
-          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY", (val & saveData) | ((regVal & maxDelay) << shiftData), true);
-
-          auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
-          if (regVal / (maxDelay+1) == 0) latency--;
-          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency, true);
-          LOG (INFO) << GREEN << "New latency dac value for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                     << BOLDYELLOW << latency << RESET;
-        }
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          {
+            auto best   = 0.;
+            auto regVal = 0;
+
+            for (auto i = 0u; i < dacList.size(); i++)
+              {
+                auto current = theOccContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<ClkDelaySize>>().data[i];
+                if (current > best)
+                  {
+                    regVal = dacList[i];
+                    best   = current;
+                  }
+              }
+
+            LOG (INFO) << GREEN << "Best delay for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                      << BOLDYELLOW << regVal << RESET << GREEN << " (1.5625 ns) computed over two bx" << RESET;
+            LOG (INFO) << GREEN << "New delay dac value for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                      << BOLDYELLOW << (regVal & maxDelay) << RESET;
+
+
+            // ####################################################
+            // # Fill delay container and download new DAC values #
+            // ####################################################
+            theClockDelayContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
+            auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY");
+            this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "CLK_DATA_DELAY", (val & saveData) | ((regVal & maxDelay) << shiftData), true);
+
+            auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
+            if (regVal / (maxDelay+1) == 0) latency--;
+            this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency, true);
+            LOG (INFO) << GREEN << "New latency dac value for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                      << BOLDYELLOW << latency << RESET;
+          }
 }
 
 void ClockDelay::fillHisto ()
@@ -283,12 +287,13 @@ void ClockDelay::scanDac (const std::string& regName, const std::vector<uint16_t
       // ###########################
       LOG (INFO) << BOLDMAGENTA << ">>> Register value = " << BOLDYELLOW << dacList[i] << BOLDMAGENTA << " <<<" << RESET;
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
-            {
-              auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), regName);
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, (val & saveData) | ((dacList[i] & maxDelay) << shiftData), true);
-            }
+        for(auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
+                  {
+                    auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), regName);
+                    this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, (val & saveData) | ((dacList[i] & maxDelay) << shiftData), true);
+                  }
 
 
       // ################
@@ -303,12 +308,13 @@ void ClockDelay::scanDac (const std::string& regName, const std::vector<uint16_t
       // # Save output #
       // ###############
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
-            {
-              float occ = cChip->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy;
-              theContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<ClkDelaySize>>().data[i] = occ;
-            }
+        for(auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
+                  {
+                    float occ = cChip->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy;
+                    theContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<ClkDelaySize>>().data[i] = occ;
+                  }
     }
 }
 
@@ -317,10 +323,11 @@ void ClockDelay::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -336,14 +343,15 @@ void ClockDelay::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> ClockDelay saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> ClockDelay saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53Gain.cc b/tools/RD53Gain.cc
index 60f453275..23ed34a24 100644
--- a/tools/RD53Gain.cc
+++ b/tools/RD53Gain.cc
@@ -147,9 +147,10 @@ void Gain::run ()
   // # Set new VCAL_MED value #
   // ##########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "VCAL_MED", offset, true);
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "VCAL_MED", offset, true);
 
 
   for (auto container : detectorContainerVector) theRecyclingBin.free(container);
@@ -168,13 +169,14 @@ void Gain::run ()
   // # Mark enabled channels #
   // #########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        for (auto row = 0u; row < RD53::nRows; row++)
-          for (auto col = 0u; col < RD53::nCols; col++)
-            if (!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) || !this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
-              for (auto i = 0u; i < dacList.size(); i++)
-                detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          for (auto row = 0u; row < RD53::nRows; row++)
+            for (auto col = 0u; col < RD53::nCols; col++)
+              if (!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) || !this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
+                for (auto i = 0u; i < dacList.size(); i++)
+                  detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
 
 
   // ################
@@ -218,13 +220,15 @@ void Gain::draw (int currentRun)
   if (saveBinaryData == true)
     {
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for(auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               std::stringstream myString;
               myString.clear(); myString.str("");
               myString << this->fDirectoryName + "/Run" + RD53Shared::fromInt2Str(currentRun) + "_Gain_"
                        << "B"    << std::setfill('0') << std::setw(2) << cBoard->getId()  << "_"
+                       << "O"    << std::setfill('0') << std::setw(2) << cOpticalGroup->getId() << "_"
                        << "M"    << std::setfill('0') << std::setw(2) << cModule->getId() << "_"
                        << "C"    << std::setfill('0') << std::setw(2) << cChip->getId()   << ".dat";
               std::ofstream fileOutID(myString.str(),std::ios::out);
@@ -235,8 +239,8 @@ void Gain::draw (int currentRun)
                     for (auto col = 0u; col < RD53::nCols; col++)
                       if (static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) && this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
                         fileOutID << "r " << row << " c " << col
-                                  << " h " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy*nEvents
-                                  << " a " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh
+                                  << " h " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy*nEvents
+                                  << " a " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh
                                   << std::endl;
                 }
               fileOutID.close();
@@ -258,8 +262,9 @@ std::shared_ptr<DetectorDataContainer> Gain::analyze ()
 
   size_t index = 0;
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
@@ -268,24 +273,24 @@ std::shared_ptr<DetectorDataContainer> Gain::analyze ()
                   for (auto i = 0u; i < dacList.size(); i++)
                     {
                       x[i] = dacList[i]-offset;
-                      y[i] = detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh;
-                      e[i] = detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPhError;
+                      y[i] = detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh;
+                      e[i] = detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPhError;
                     }
 
                   Gain::computeStats(x,y,e,gain,gainErr,intercept,interceptErr);
 
                   if (gain != 0)
                     {
-                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGain           = gain;
-                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGainError      = gainErr;
-                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fIntercept      = intercept;
-                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fInterceptError = interceptErr;
+                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGain           = gain;
+                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGainError      = gainErr;
+                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fIntercept      = intercept;
+                      theGainAndInterceptContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fInterceptError = interceptErr;
 
-                      if (gain > theMaxGainContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>())
-                        theMaxGainContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = gain;
+                      if (gain > theMaxGainContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>())
+                        theMaxGainContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = gain;
                     }
                   else
-                    theGainAndInterceptContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGain = RD53Shared::FITERROR;
+                    theGainAndInterceptContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<GainAndIntercept>(row,col).fGain = RD53Shared::FITERROR;
                 }
 
           index++;
@@ -294,12 +299,13 @@ std::shared_ptr<DetectorDataContainer> Gain::analyze ()
   theGainAndInterceptContainer->normalizeAndAverageContainers(fDetectorContainer, this->fChannelGroupHandler->allChannelGroup(), 1);
 
   for (const auto cBoard : *theGainAndInterceptContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Average gain for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << GREEN << "] is " << BOLDYELLOW
+          LOG (INFO) << GREEN << "Average gain for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << GREEN << "] is " << BOLDYELLOW
                      << std::fixed << std::setprecision(4) << cChip->getSummary<GainAndIntercept,GainAndIntercept>().fGain << RESET << GREEN << " (ToT/Delta_VCal)" << std::setprecision(-1) << RESET;
-          LOG (INFO) << BOLDBLUE << "\t--> Highest gain: " << BOLDYELLOW << theMaxGainContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> Highest gain: " << BOLDYELLOW << theMaxGainContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() << RESET;
         }
 
   return theGainAndInterceptContainer;
@@ -388,10 +394,11 @@ void Gain::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -407,14 +414,15 @@ void Gain::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for(auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> Gain saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> Gain saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53GainOptimization.cc b/tools/RD53GainOptimization.cc
index ee9dc2934..d22895322 100644
--- a/tools/RD53GainOptimization.cc
+++ b/tools/RD53GainOptimization.cc
@@ -127,9 +127,10 @@ void GainOptimization::run ()
   // #######################################
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theKrumCurrContainer);
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        theKrumCurrContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->gainReg);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          theKrumCurrContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->gainReg);
 
 
   // ################
@@ -166,10 +167,11 @@ void GainOptimization::draw (int currentRun)
 void GainOptimization::analyze ()
 {
   for (const auto cBoard : theKrumCurrContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        LOG(INFO) << GREEN << "Krummenacher Current for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                  << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          LOG(INFO) << GREEN << "Krummenacher Current for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                    << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
 }
 
 void GainOptimization::fillHisto ()
@@ -199,9 +201,10 @@ void GainOptimization::bitWiseScanGlobal (const std::string& regName, uint32_t n
   ContainerFactory::copyAndInitChip<OccupancyAndPh>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        cChip->getSummary<OccupancyAndPh>().fPh = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          cChip->getSummary<OccupancyAndPh>().fPh = 0;
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -210,14 +213,15 @@ void GainOptimization::bitWiseScanGlobal (const std::string& regName, uint32_t n
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
-              midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
-                 maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
+              midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
+                 maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
 
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
             }
 
 
@@ -233,8 +237,9 @@ void GainOptimization::bitWiseScanGlobal (const std::string& regName, uint32_t n
       // # Compute next step #
       // #####################
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               // ##############################################
               // # Search for maximum and build discriminator #
@@ -257,23 +262,23 @@ void GainOptimization::bitWiseScanGlobal (const std::string& regName, uint32_t n
               // ########################
               // # Save best DAC values #
               // ########################
-              float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
+              float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
               if (fabs(newValue - target) < fabs(oldValue - target))
                 {
-                  bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
-                  bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                    midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                  bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
+                  bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                    midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
                 }
 
               if ((newValue > target) || (newValue < 0))
 
-                maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
 
               else
 
-                minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
             }
     }
 
@@ -282,9 +287,10 @@ void GainOptimization::bitWiseScanGlobal (const std::string& regName, uint32_t n
   // # Download new DAC values #
   // ###########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
 
 
   // ################
@@ -299,10 +305,11 @@ void GainOptimization::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -318,14 +325,15 @@ void GainOptimization::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> GainOptimization saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> GainOptimization saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53InjectionDelay.cc b/tools/RD53InjectionDelay.cc
index dcad44d3f..c12517932 100644
--- a/tools/RD53InjectionDelay.cc
+++ b/tools/RD53InjectionDelay.cc
@@ -29,7 +29,7 @@ void InjectionDelay::ConfigureCalibration ()
   colStop        = this->findValueInSettings("COLstop");
   nEvents        = this->findValueInSettings("nEvents");
   startValue     = 0;
-  stopValue      = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"))+1) - 1;
+  stopValue      = RD53Shared::NLATENCYBINS*(RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"))+1) - 1;
   doDisplay      = this->findValueInSettings("DisplayHisto");
   doUpdateChip   = this->findValueInSettings("UpdateChipCfg");
   saveBinaryData = this->findValueInSettings("SaveBinaryData");
@@ -53,9 +53,9 @@ void InjectionDelay::ConfigureCalibration ()
   // ##############################
   // # Injection register masking #
   // ##############################
-  saveInjection = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT")) -
-    RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
-  maxDelay      = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
+  saveInjection = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT")) -
+    RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
+  maxDelay      = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
 
 
   // #######################
@@ -145,8 +145,9 @@ void InjectionDelay::run ()
   // # Run Latency #
   // ###############
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT");
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT", val & saveInjection, true);
@@ -162,8 +163,9 @@ void InjectionDelay::run ()
   // # Set Initial latency #
   // #######################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency - 1, true);
@@ -178,8 +180,9 @@ void InjectionDelay::run ()
       std::vector<uint16_t> halfDacList(dacList.begin() + i*(dacList.end() - dacList.begin()) / 2, dacList.begin() + (i+1)*(dacList.end() - dacList.begin()) / 2);
 
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
               this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency + i, true);
@@ -225,15 +228,16 @@ void InjectionDelay::analyze ()
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theInjectionDelayContainer);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           auto best   = 0.;
           auto regVal = 0;
 
           for (auto i = 0u; i < dacList.size(); i++)
             {
-              auto current = theOccContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<InjDelaySize>>().data[i];
+              auto current = theOccContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<InjDelaySize>>().data[i];
               if (current > best)
                 {
                   regVal = dacList[i];
@@ -241,23 +245,23 @@ void InjectionDelay::analyze ()
                 }
             }
 
-          LOG (INFO) << GREEN << "Best delay for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+          LOG (INFO) << GREEN << "Best delay for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
                      << BOLDYELLOW << regVal << RESET << GREEN << " (1.5625 ns) computed over two bx" << RESET;
-          LOG (INFO) << GREEN << "New delay dac value for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+          LOG (INFO) << GREEN << "New delay dac value for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
                      << BOLDYELLOW << (regVal & maxDelay) << RESET;
 
 
           // ####################################################
           // # Fill delay container and download new DAC values #
           // ####################################################
-          theInjectionDelayContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
+          theInjectionDelayContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
           auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT");
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT", (val & saveInjection) | (regVal & maxDelay), true);
 
           auto latency = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG");
           if (regVal / (maxDelay+1) == 0) latency--;
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", latency, true);
-          LOG (INFO) << GREEN << "New latency dac value for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+          LOG (INFO) << GREEN << "New latency dac value for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
                      << BOLDYELLOW << latency << RESET;
         }
 }
@@ -281,8 +285,9 @@ void InjectionDelay::scanDac (const std::string& regName, const std::vector<uint
       // ###########################
       LOG (INFO) << BOLDMAGENTA << ">>> Register value = " << BOLDYELLOW << dacList[i] << BOLDMAGENTA << " <<<" << RESET;
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), regName);
               this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, (val & saveInjection) | (dacList[i] & maxDelay), true);
@@ -301,11 +306,12 @@ void InjectionDelay::scanDac (const std::string& regName, const std::vector<uint
       // # Save output #
       // ###############
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               float occ = cChip->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy;
-              theContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<InjDelaySize>>().data[dacList[i]] = occ;
+              theContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<InjDelaySize>>().data[dacList[i]] = occ;
             }
     }
 }
@@ -315,10 +321,11 @@ void InjectionDelay::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -334,14 +341,15 @@ void InjectionDelay::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> InjectionDelay saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> InjectionDelay saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53Latency.cc b/tools/RD53Latency.cc
index 6536e1253..b2277d0ba 100644
--- a/tools/RD53Latency.cc
+++ b/tools/RD53Latency.cc
@@ -156,15 +156,16 @@ void Latency::analyze ()
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theLatencyContainer);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           auto best   = 0.;
           auto regVal = 0;
 
           for (auto i = 0u; i < dacList.size(); i++)
             {
-              auto current = theOccContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<LatencySize>>().data[i];
+              auto current = theOccContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<LatencySize>>().data[i];
               if (current > best)
                 {
                   regVal = dacList[i];
@@ -173,17 +174,17 @@ void Latency::analyze ()
             }
 
           if (nTRIGxEvent > 1)
-            LOG (INFO) << GREEN << "Best latency for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is within ["
+            LOG (INFO) << GREEN << "Best latency for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is within ["
                        << BOLDYELLOW << regVal - nTRIGxEvent + 1 << "," << regVal << GREEN << "] (n.bx)" << RESET;
           else
-            LOG (INFO) << GREEN << "Best latency for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+            LOG (INFO) << GREEN << "Best latency for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
                        << BOLDYELLOW << regVal << RESET << GREEN << " (n.bx)" << RESET;
 
 
           // ######################################################
           // # Fill latency container and download new DAC values #
           // ######################################################
-          theLatencyContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
+          theLatencyContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = regVal;
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "LATENCY_CONFIG", regVal, true);
         }
 }
@@ -222,11 +223,12 @@ void Latency::scanDac (const std::string& regName, const std::vector<uint16_t>&
       // # Save output #
       // ###############
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               float occ = cChip->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy;
-              theContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<LatencySize>>().data[i] = occ;
+              theContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<LatencySize>>().data[i] = occ;
             }
     }
 }
@@ -236,10 +238,11 @@ void Latency::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -255,14 +258,15 @@ void Latency::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> Latency saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> Latency saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53Physics.cc b/tools/RD53Physics.cc
index a96d68c8d..da6adb4db 100644
--- a/tools/RD53Physics.cc
+++ b/tools/RD53Physics.cc
@@ -73,9 +73,10 @@ void Physics::Start (int currentRun)
   // # Download mask to the chips #
   // ##############################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        fReadoutChipInterface->maskChannelsAndSetInjectionSchema(static_cast<ReadoutChip*>(cChip), theChnGroupHandler->allChannelGroup(), true, false);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          fReadoutChipInterface->maskChannelsAndSetInjectionSchema(static_cast<ReadoutChip*>(cChip), theChnGroupHandler->allChannelGroup(), true, false);
 
 
   for (const auto cBoard : *fDetectorContainer)
@@ -229,8 +230,9 @@ void Physics::fillDataContainer (BoardContainer* const& cBoard)
   // # Clear container #
   // ###################
   for (const auto cBoard : theOccContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
@@ -241,8 +243,8 @@ void Physics::fillDataContainer (BoardContainer* const& cBoard)
                 cChip->getChannel<OccupancyAndPh>(row,col).readoutError = false;
               }
 
-          for (auto i = 0u; i < BCIDsize; i++)  theBCIDContainer .at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[i]  = 0;
-          for (auto i = 0u; i < TrgIDsize; i++) theTrgIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[i] = 0;
+          for (auto i = 0u; i < BCIDsize; i++)  theBCIDContainer .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[i]  = 0;
+          for (auto i = 0u; i < TrgIDsize; i++) theTrgIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[i] = 0;
         }
 
 
@@ -258,15 +260,16 @@ void Physics::fillDataContainer (BoardContainer* const& cBoard)
   // # Copy register values for streaming #
   // ######################################
   for (const auto cBoard : theOccContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           for (auto i = 1u; i < cChip->getSummary<GenericDataVector,OccupancyAndPh>().data1.size(); i++)
             {
               int deltaBCID = cChip->getSummary<GenericDataVector,OccupancyAndPh>().data1[i] - cChip->getSummary<GenericDataVector,OccupancyAndPh>().data1[i-1];
               deltaBCID += (deltaBCID >= 0 ? 0 : RD53Shared::setBits(RD53EvtEncoder::NBIT_BCID) + 1);
               if (deltaBCID >= int(BCIDsize)) LOG (ERROR) << BOLDBLUE <<"[Physics::fillDataContainer] " << BOLDRED << "deltaBCID out of range: " << deltaBCID << RESET;
-              else theBCIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[deltaBCID]++;
+              else theBCIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[deltaBCID]++;
             }
           cChip->getSummary<GenericDataVector,OccupancyAndPh>().data1.clear();
 
@@ -275,7 +278,7 @@ void Physics::fillDataContainer (BoardContainer* const& cBoard)
               int deltaTrgID = cChip->getSummary<GenericDataVector,OccupancyAndPh>().data2[i] - cChip->getSummary<GenericDataVector,OccupancyAndPh>().data2[i-1];
               deltaTrgID += (deltaTrgID >= 0 ? 0 : RD53Shared::setBits(RD53EvtEncoder::NBIT_TRIGID) + 1);
               if (deltaTrgID >= int(TrgIDsize)) LOG (ERROR) << BOLDBLUE << "[Physics::fillDataContainer] " << BOLDRED << "deltaTrgID out of range: " << deltaTrgID << RESET;
-              else theTrgIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[deltaTrgID]++;
+              else theTrgIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[deltaTrgID]++;
             }
           cChip->getSummary<GenericDataVector,OccupancyAndPh>().data2.clear();
         }
@@ -285,11 +288,12 @@ void Physics::fillDataContainer (BoardContainer* const& cBoard)
   // # Normalize container #
   // #######################
   for (const auto cBoard : theOccContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        for (auto row = 0u; row < RD53::nRows; row++)
-          for (auto col = 0u; col < RD53::nCols; col++)
-            cChip->getChannel<OccupancyAndPh>(row,col).normalize(events.size(), true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          for (auto row = 0u; row < RD53::nRows; row++)
+            for (auto col = 0u; col < RD53::nCols; col++)
+              cChip->getChannel<OccupancyAndPh>(row,col).normalize(events.size(), true);
 }
 
 void Physics::chipErrorReport ()
@@ -297,10 +301,11 @@ void Physics::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -316,15 +321,16 @@ void Physics::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> Physics saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> Physics saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 
 }
diff --git a/tools/RD53PixelAlive.cc b/tools/RD53PixelAlive.cc
index 556a70f94..b10e2c5ca 100644
--- a/tools/RD53PixelAlive.cc
+++ b/tools/RD53PixelAlive.cc
@@ -50,12 +50,13 @@ void PixelAlive::ConfigureCalibration ()
   // # Set injection type #
   // ######################
   size_t inj = 0;
-  if (injType == INJtype::Digital) inj = 1 << static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY");
-  size_t maxDelay = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
+  if (injType == INJtype::Digital) inj = 1 << static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY");
+  size_t maxDelay = RD53Shared::setBits(static_cast<RD53*>(fDetectorContainer->at(0)->at(0)->at(0)->at(0))->getNumberOfBits("INJECTION_SELECT_DELAY"));
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           auto val = this->fReadoutChipInterface->ReadChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT");
           this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "INJECTION_SELECT", inj | (val & maxDelay), true);
@@ -197,13 +198,14 @@ std::shared_ptr<DetectorDataContainer> PixelAlive::analyze ()
   ContainerFactory::copyAndInitChip<GenericDataArray<TrgIDsize>>(*fDetectorContainer, theTrgIDContainer);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           size_t nMaskedPixelsPerCalib = 0;
 
-          LOG (INFO) << GREEN << "Average occupancy for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is " << BOLDYELLOW
-                     << theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy << RESET;
+          LOG (INFO) << GREEN << "Average occupancy for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is " << BOLDYELLOW
+                     << theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().fOccupancy << RESET;
 
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
 
@@ -211,7 +213,7 @@ std::shared_ptr<DetectorDataContainer> PixelAlive::analyze ()
             for (auto col = 0u; col < RD53::nCols; col++)
               if (static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) && this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
                 {
-                  float occupancy = theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy;
+                  float occupancy = theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy;
                   static_cast<RD53*>(cChip)->enablePixel(row, col, injType == INJtype::None ? occupancy < thrOccupancy : occupancy != 0);
                   if (((injType == INJtype::None) && (occupancy >= thrOccupancy)) || ((injType != INJtype::None) && (occupancy == 0))) nMaskedPixelsPerCalib++;
                 }
@@ -223,25 +225,25 @@ std::shared_ptr<DetectorDataContainer> PixelAlive::analyze ()
           // ######################################
           // # Copy register values for streaming #
           // ######################################
-          for (auto i = 0u; i < BCIDsize; i++)  theBCIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[i]   = 0;
-          for (auto i = 0u; i < TrgIDsize; i++) theTrgIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[i] = 0;
+          for (auto i = 0u; i < BCIDsize; i++)  theBCIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[i]   = 0;
+          for (auto i = 0u; i < TrgIDsize; i++) theTrgIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[i] = 0;
 
-          for (auto i = 1u; i < theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1.size(); i++)
+          for (auto i = 1u; i < theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1.size(); i++)
             {
-              int deltaBCID = theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1[i] -
-                theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1[i-1];
+              int deltaBCID = theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1[i] -
+                theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data1[i-1];
               deltaBCID += (deltaBCID >= 0 ? 0 : RD53Shared::setBits(RD53EvtEncoder::NBIT_BCID) + 1);
               if (deltaBCID >= int(BCIDsize)) LOG (ERROR) << BOLDBLUE <<"[PixelAlive::analyze] " << BOLDRED << "deltaBCID out of range: " << deltaBCID << RESET;
-              else theBCIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[deltaBCID]++;
+              else theBCIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<BCIDsize>>().data[deltaBCID]++;
             }
 
-          for (auto i = 1u; i < theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2.size(); i++)
+          for (auto i = 1u; i < theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2.size(); i++)
             {
-              int deltaTrgID = theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2[i] -
-                theOccContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2[i-1];
+              int deltaTrgID = theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2[i] -
+                theOccContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataVector,OccupancyAndPh>().data2[i-1];
               deltaTrgID += (deltaTrgID >= 0 ? 0 : RD53Shared::setBits(RD53EvtEncoder::NBIT_TRIGID) + 1);
               if (deltaTrgID >= int(TrgIDsize)) LOG (ERROR) << BOLDBLUE << "[PixelAlive::analyze] " << BOLDRED << "deltaTrgID out of range: " << deltaTrgID << RESET;
-              else theTrgIDContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[deltaTrgID]++;
+              else theTrgIDContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<GenericDataArray<TrgIDsize>>().data[deltaTrgID]++;
             }
         }
 
@@ -262,10 +264,11 @@ void PixelAlive::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -281,13 +284,14 @@ void PixelAlive::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> PixelAlive saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> PixelAlive saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53SCurve.cc b/tools/RD53SCurve.cc
index ba6e40e8e..eea9c5e7b 100644
--- a/tools/RD53SCurve.cc
+++ b/tools/RD53SCurve.cc
@@ -147,9 +147,10 @@ void SCurve::run ()
   // # Set new VCAL_MED value #
   // ##########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "VCAL_MED", offset, true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), "VCAL_MED", offset, true);
 
 
   for (auto container : detectorContainerVector) theRecyclingBin.free(container);
@@ -168,13 +169,14 @@ void SCurve::run ()
   // # Mark enabled channels #
   // #########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        for (auto row = 0u; row < RD53::nRows; row++)
-          for (auto col = 0u; col < RD53::nCols; col++)
-            if (!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) || !this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
-              for (auto i = 0u; i < dacList.size(); i++)
-                detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          for (auto row = 0u; row < RD53::nRows; row++)
+            for (auto col = 0u; col < RD53::nCols; col++)
+              if (!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) || !this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
+                for (auto i = 0u; i < dacList.size(); i++)
+                  detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
 
 
   // ################
@@ -212,15 +214,17 @@ void SCurve::draw (int currentRun)
   if (saveBinaryData == true)
     {
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               std::stringstream myString;
               myString.clear(); myString.str("");
               myString << this->fDirectoryName + "/Run" + RD53Shared::fromInt2Str(currentRun) + "_SCurve_"
-                       << "B"    << std::setfill('0') << std::setw(2) << cBoard->getId()  << "_"
-                       << "M"    << std::setfill('0') << std::setw(2) << cModule->getId() << "_"
-                       << "C"    << std::setfill('0') << std::setw(2) << cChip->getId()   << ".dat";
+                       << "O"    << std::setfill('0') << std::setw(2) << cOpticalGroup->getId()  << "_"
+                       << "B"    << std::setfill('0') << std::setw(2) << cBoard->getId()         << "_"
+                       << "M"    << std::setfill('0') << std::setw(2) << cModule->getId()        << "_"
+                       << "C"    << std::setfill('0') << std::setw(2) << cChip->getId()          << ".dat";
               std::ofstream fileOutID(myString.str(),std::ios::out);
               for (auto i = 0u; i < dacList.size(); i++)
                 {
@@ -229,8 +233,8 @@ void SCurve::draw (int currentRun)
                     for (auto col = 0u; col < RD53::nCols; col++)
                       if (static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) && this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
                         fileOutID << "r " << row << " c " << col
-                                  << " h " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy*nEvents
-                                  << " a " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh
+                                  << " h " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy*nEvents
+                                  << " a " << detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fPh
                                   << std::endl;
                 }
               fileOutID.close();
@@ -251,30 +255,31 @@ std::shared_ptr<DetectorDataContainer> SCurve::analyze ()
 
   size_t index = 0;
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
               if (static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) && this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
                 {
                   for (auto i = 1u; i < dacList.size(); i++)
-                    measurements[i] = fabs(detectorContainerVector[i]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy -
-                                           detectorContainerVector[i-1]->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy);
+                    measurements[i] = fabs(detectorContainerVector[i]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy -
+                                           detectorContainerVector[i-1]->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy);
 
                   SCurve::computeStats(measurements, offset, nHits, mean, rms);
 
                   if ((rms > 0) && (nHits > 0) && (isnan(rms) == false))
                     {
-                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fThreshold      = mean;
-                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fThresholdError = rms / sqrt(nHits);
-                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fNoise          = rms;
+                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fThreshold      = mean;
+                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fThresholdError = rms / sqrt(nHits);
+                      theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fNoise          = rms;
 
-                      if (mean > theMaxThresholdContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>())
-                        theMaxThresholdContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = mean;
+                      if (mean > theMaxThresholdContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>())
+                        theMaxThresholdContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = mean;
                     }
                   else
-                    theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fNoise = RD53Shared::FITERROR;
+                    theThresholdAndNoiseContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<ThresholdAndNoise>(row,col).fNoise = RD53Shared::FITERROR;
                 }
 
           index++;
@@ -283,12 +288,13 @@ std::shared_ptr<DetectorDataContainer> SCurve::analyze ()
   theThresholdAndNoiseContainer->normalizeAndAverageContainers(fDetectorContainer, this->fChannelGroupHandler->allChannelGroup(), 1);
 
   for (const auto cBoard : *theThresholdAndNoiseContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Average threshold for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << GREEN << "] is " << BOLDYELLOW
+          LOG (INFO) << GREEN << "Average threshold for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << GREEN << "] is " << BOLDYELLOW
                      << std::fixed << std::setprecision(1) << cChip->getSummary<ThresholdAndNoise,ThresholdAndNoise>().fThreshold << RESET << GREEN << " (Delta_VCal)" << std::setprecision(-1) << RESET;
-          LOG (INFO) << BOLDBLUE << "\t--> Highest threshold: " << BOLDYELLOW << theMaxThresholdContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> Highest threshold: " << BOLDYELLOW << theMaxThresholdContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() << RESET;
         }
 
   return theThresholdAndNoiseContainer;
@@ -336,10 +342,11 @@ void SCurve::chipErrorReport ()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -355,14 +362,15 @@ void SCurve::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> SCurve saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> SCurve saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53ThrAdjustment.cc b/tools/RD53ThrAdjustment.cc
index 824c1c966..66735d49f 100644
--- a/tools/RD53ThrAdjustment.cc
+++ b/tools/RD53ThrAdjustment.cc
@@ -126,9 +126,10 @@ void ThrAdjustment::run ()
   // ############################
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theThrContainer);
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        theThrContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->thresholdReg);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          theThrContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->thresholdReg);
 
 
   // ################
@@ -165,10 +166,11 @@ void ThrAdjustment::draw (int currentRun)
 void ThrAdjustment::analyze ()
 {
   for (const auto cBoard : theThrContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        LOG(INFO) << GREEN << "Global threshold for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                  << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          LOG(INFO) << GREEN << "Global threshold for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                    << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
 }
 
 void ThrAdjustment::fillHisto ()
@@ -198,9 +200,10 @@ void ThrAdjustment::bitWiseScanGlobal (const std::string& regName, uint32_t nEve
   ContainerFactory::copyAndInitChip<float>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        cChip->getSummary<float>() = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          cChip->getSummary<float>() = 0;
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -209,14 +212,15 @@ void ThrAdjustment::bitWiseScanGlobal (const std::string& regName, uint32_t nEve
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
-              midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
-                 maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
+              midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
+                 maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
 
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
             }
 
 
@@ -230,37 +234,38 @@ void ThrAdjustment::bitWiseScanGlobal (const std::string& regName, uint32_t nEve
       // # Compute next step #
       // #####################
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               // #######################
               // # Build discriminator #
               // #######################
-              float newValue = RD53chargeConverter::VCAl2Charge(cChip->getSummary<uint16_t>() - static_cast<RD53*>(fDetectorContainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()))->getReg("VCAL_MED"));
+              float newValue = RD53chargeConverter::VCAl2Charge(cChip->getSummary<uint16_t>() - static_cast<RD53*>(fDetectorContainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()))->getReg("VCAL_MED"));
 
 
               // ########################
               // # Save best DAC values #
               // ########################
-              float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>();
+              float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>();
 
               if (fabs(newValue - target) < fabs(oldValue - target))
                 {
-                  bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = newValue;
+                  bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<float>() = newValue;
 
-                  bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                    midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                  bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                    midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
                 }
 
               if (newValue > target)
 
-                maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
 
               else
 
-                minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
             }
     }
 
@@ -269,9 +274,10 @@ void ThrAdjustment::bitWiseScanGlobal (const std::string& regName, uint32_t nEve
   // # Download new DAC values #
   // ###########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
 
 
   // ################
@@ -301,9 +307,10 @@ std::shared_ptr<DetectorDataContainer> ThrAdjustment::bitWiseScanGlobal_MeasureT
   ContainerFactory::copyAndInitChip<OccupancyAndPh>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        cChip->getSummary<OccupancyAndPh>().fPh = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          cChip->getSummary<OccupancyAndPh>().fPh = 0;
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -312,14 +319,15 @@ std::shared_ptr<DetectorDataContainer> ThrAdjustment::bitWiseScanGlobal_MeasureT
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
-              midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
-                 maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
+              midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
+                 maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
 
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
             }
 
 
@@ -335,8 +343,9 @@ std::shared_ptr<DetectorDataContainer> ThrAdjustment::bitWiseScanGlobal_MeasureT
       // # Compute next step #
       // #####################
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               // #######################
               // # Build discriminator #
@@ -347,25 +356,25 @@ std::shared_ptr<DetectorDataContainer> ThrAdjustment::bitWiseScanGlobal_MeasureT
               // ########################
               // # Save best DAC values #
               // ########################
-              float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
+              float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
 
               if (fabs(newValue - target) < fabs(oldValue - target))
                 {
-                  bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
+                  bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
 
-                  bestDACcontainer->at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                    midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                  bestDACcontainer->at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                    midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
                 }
 
               if (newValue > target)
 
-                maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
 
               else
 
-                minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
             }
     }
 
@@ -378,10 +387,11 @@ void ThrAdjustment::chipErrorReport()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -397,14 +407,15 @@ void ThrAdjustment::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> ThrAdjustment saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> ThrAdjustment saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53ThrEqualization.cc b/tools/RD53ThrEqualization.cc
index 2a5159ed5..3ab1b93f2 100644
--- a/tools/RD53ThrEqualization.cc
+++ b/tools/RD53ThrEqualization.cc
@@ -162,17 +162,18 @@ void ThrEqualization::run ()
   // # Fill TDAC container and mark enabled channels #
   // #################################################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          this->fReadoutChipInterface->ReadChipAllLocalReg(static_cast<RD53*>(cChip), "PIX_PORTAL", *theTDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
+          this->fReadoutChipInterface->ReadChipAllLocalReg(static_cast<RD53*>(cChip), "PIX_PORTAL", *theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
 
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
               if (!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) || !this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
                 {
-                  theOccContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
-                  theTDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col)                 = TDACsize;
+                  theOccContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = RD53Shared::ISDISABLED;
+                  theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col)                 = TDACsize;
                 }
         }
 
@@ -211,15 +212,16 @@ void ThrEqualization::draw (int currentRun)
 void ThrEqualization::analyze ()
 {
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
 
           for (auto row = 0u; row < RD53::nRows; row++)
             for (auto col = 0u; col < RD53::nCols; col++)
               if (static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row,col) && this->fChannelGroupHandler->allChannelGroup()->isChannelEnabled(row,col))
-                static_cast<RD53*>(cChip)->setTDAC(row, col, theTDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col));
+                static_cast<RD53*>(cChip)->setTDAC(row, col, theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col));
 
           static_cast<RD53*>(cChip)->copyMaskToDefault();
         }
@@ -253,9 +255,10 @@ void ThrEqualization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
   ContainerFactory::copyAndInitChip<OccupancyAndPh>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        cChip->getSummary<OccupancyAndPh>().fPh = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          cChip->getSummary<OccupancyAndPh>().fPh = 0;
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -264,14 +267,15 @@ void ThrEqualization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
-              midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
-                 maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
+              midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
+                 maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
 
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
             }
 
 
@@ -287,8 +291,9 @@ void ThrEqualization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
       // # Compute next step #
       // #####################
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               // #######################
               // # Build discriminator #
@@ -299,25 +304,25 @@ void ThrEqualization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
               // ########################
               // # Save best DAC values #
               // ########################
-              float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
+              float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
 
               if (fabs(newValue - target) < fabs(oldValue - target))
                 {
-                  bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
+                  bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
 
-                  bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                    midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                  bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                    midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
                 }
 
               if (newValue > target)
 
-                maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
 
               else
 
-                minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
             }
     }
 
@@ -326,9 +331,10 @@ void ThrEqualization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
   // # Download new DAC values #
   // ###########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
 
 
   // ################
@@ -358,20 +364,22 @@ void ThrEqualization::bitWiseScanLocal (const std::string& regName, uint32_t nEv
   ContainerFactory::copyAndInitChannel<OccupancyAndPh>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        for (auto row = 0u; row < RD53::nRows; row++)
-          for (auto col = 0u; col < RD53::nCols; col++)
-            cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          for (auto row = 0u; row < RD53::nRows; row++)
+            for (auto col = 0u; col < RD53::nCols; col++)
+              cChip->getChannel<OccupancyAndPh>(row,col).fOccupancy = 0;
 
 
   // ############################
   // # Read DAC starting values #
   // ############################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->ReadChipAllLocalReg(static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->ReadChipAllLocalReg(static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -380,9 +388,10 @@ void ThrEqualization::bitWiseScanLocal (const std::string& regName, uint32_t nEv
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
-            this->fReadoutChipInterface->WriteChipAllLocalReg(static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
+                  this->fReadoutChipInterface->WriteChipAllLocalReg(static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
 
 
       // ################
@@ -395,10 +404,11 @@ void ThrEqualization::bitWiseScanLocal (const std::string& regName, uint32_t nEv
       // # Compute next step #
       // #####################
       for (const auto cBoard : theOccContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
-            for (auto row = 0u; row < RD53::nRows; row++)
-              for (auto col = 0u; col < RD53::nCols; col++)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
+              for (auto row = 0u; row < RD53::nRows; row++)
+                for (auto col = 0u; col < RD53::nCols; col++)
                 {
                   // #######################
                   // # Build discriminator #
@@ -409,28 +419,28 @@ void ThrEqualization::bitWiseScanLocal (const std::string& regName, uint32_t nEv
                   // ########################
                   // # Save best DAC values #
                   // ########################
-                  float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy;
+                  float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy;
 
                   if (fabs(newValue - target) < fabs(oldValue - target) || (newValue == oldValue))
                     {
-                      bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = newValue;
-                      bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
-                        midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
+                      bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row,col).fOccupancy = newValue;
+                      bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
+                        midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
                     }
 
                   if (newValue < target)
 
-                    minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
-                      midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
+                    minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
+                      midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
 
                   else
 
-                    maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
-                      midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
+                    maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
+                      midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col);
 
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
-                    (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) +
-                     maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col)) / 2;
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) =
+                    (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col) +
+                     maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row,col)) / 2;
                 }
     }
 
@@ -439,9 +449,10 @@ void ThrEqualization::bitWiseScanLocal (const std::string& regName, uint32_t nEv
   // # Download new DAC values #
   // ###########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipAllLocalReg(static_cast<RD53*>(cChip), regName, *bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipAllLocalReg(static_cast<RD53*>(cChip), regName, *bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex()));
 
 
   // ################
@@ -455,10 +466,11 @@ void ThrEqualization::chipErrorReport()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -474,13 +486,14 @@ void ThrEqualization::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> ThrEqualization saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> ThrEqualization saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RD53ThrMinimization.cc b/tools/RD53ThrMinimization.cc
index 901c620f4..7d805c65a 100644
--- a/tools/RD53ThrMinimization.cc
+++ b/tools/RD53ThrMinimization.cc
@@ -124,9 +124,10 @@ void ThrMinimization::run ()
   // ############################
   ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, theThrContainer);
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        theThrContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->thresholdReg);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          theThrContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<RD53*>(cChip)->getReg(frontEnd->thresholdReg);
 
 
   // ################
@@ -163,10 +164,11 @@ void ThrMinimization::draw (int currentRun)
 void ThrMinimization::analyze ()
 {
   for (const auto cBoard : theThrContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        LOG(INFO) << GREEN << "Global threshold for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
-                  << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          LOG(INFO) << GREEN << "Global threshold for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "] is "
+                    << BOLDYELLOW << cChip->getSummary<uint16_t>() << RESET;
 }
 
 void ThrMinimization::fillHisto ()
@@ -196,9 +198,10 @@ void ThrMinimization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
   ContainerFactory::copyAndInitChip<OccupancyAndPh>(*fDetectorContainer, bestContainer);
 
   for (const auto cBoard : bestContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        cChip->getSummary<OccupancyAndPh>().fPh = 0;
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          cChip->getSummary<OccupancyAndPh>().fPh = 0;
 
 
   for (auto i = 0u; i <= numberOfBits; i++)
@@ -207,14 +210,15 @@ void ThrMinimization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
       // # Download new DAC values #
       // ###########################
       for (const auto cBoard : *fDetectorContainer)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
-              midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                (minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
-                 maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
+              midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
+                 maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) / 2;
 
-              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+              this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
             }
 
 
@@ -230,8 +234,9 @@ void ThrMinimization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
       // # Compute next step #
       // #####################
       for (const auto cBoard : *output)
-        for (const auto cModule : *cBoard)
-          for (const auto cChip : *cModule)
+        for (const auto cOpticalGroup : *cBoard)
+          for (const auto cModule : *cOpticalGroup)
+            for (const auto cChip : *cModule)
             {
               // #######################
               // # Build discriminator #
@@ -242,25 +247,25 @@ void ThrMinimization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
               // ########################
               // # Save best DAC values #
               // ########################
-              float oldValue = bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
+              float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh;
 
               if (fabs(newValue - target) < fabs(oldValue - target))
                 {
-                  bestContainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
+                  bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<OccupancyAndPh>().fPh = newValue;
 
-                  bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                    midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                  bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                    midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
                 }
 
               if (newValue < target)
 
-                maxDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
 
               else
 
-                minDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
-                  midDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+                minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
+                  midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
             }
     }
 
@@ -269,9 +274,10 @@ void ThrMinimization::bitWiseScanGlobal (const std::string& regName, uint32_t nE
   // # Download new DAC values #
   // ###########################
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
-        this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
+          this->fReadoutChipInterface->WriteChipReg(static_cast<RD53*>(cChip), regName, bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cModule->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(), true);
 
 
   // ################
@@ -286,10 +292,11 @@ void ThrMinimization::chipErrorReport()
   auto RD53ChipInterface = static_cast<RD53Interface*>(this->fReadoutChipInterface);
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
-          LOG (INFO) << GREEN << "Readout chip error report for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
+          LOG (INFO) << GREEN << "Readout chip error report for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << GREEN << "]" << RESET;
           LOG (INFO) << BOLDBLUE << "LOCKLOSS_CNT        = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "LOCKLOSS_CNT")        << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_WNG_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_WNG_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
           LOG (INFO) << BOLDBLUE << "BITFLIP_ERR_CNT     = " << BOLDYELLOW << RD53ChipInterface->ReadChipReg (static_cast<RD53*>(cChip), "BITFLIP_ERR_CNT")     << std::setfill(' ') << std::setw(8) << "" << RESET;
@@ -305,14 +312,15 @@ void ThrMinimization::saveChipRegisters (int currentRun)
   std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
 
   for (const auto cBoard : *fDetectorContainer)
-    for (const auto cModule : *cBoard)
-      for (const auto cChip : *cModule)
+    for (const auto cOpticalGroup : *cBoard)
+      for (const auto cModule : *cOpticalGroup)
+        for (const auto cChip : *cModule)
         {
           static_cast<RD53*>(cChip)->copyMaskFromDefault();
           if (doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
           static_cast<RD53*>(cChip)->saveRegMap(fileReg);
           std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RESULTDIR);
           system(command.c_str());
-          LOG (INFO) << BOLDBLUE << "\t--> ThrMinimization saved the configuration file for [board/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
+          LOG (INFO) << BOLDBLUE << "\t--> ThrMinimization saved the configuration file for [board/opticalGroup/module/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/" << cModule->getId() << "/" << cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
         }
 }
diff --git a/tools/RegisterTester.cc b/tools/RegisterTester.cc
index e76213f58..6b319a7e0 100644
--- a/tools/RegisterTester.cc
+++ b/tools/RegisterTester.cc
@@ -20,43 +20,47 @@ void RegisterTester::TestRegisters()
     report.open (fDirectoryName + "/TestReport.txt", std::ofstream::out | std::ofstream::app);
     char line[240];
 
-    for ( auto cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
-            for ( auto cCbc : cFe->fReadoutChipVector )
+            for ( auto cFe : *cOpticalGroup )
             {
-                ChipRegMap cMap = cCbc->getRegMap();
-
-                for ( const auto& cReg : cMap )
+                for ( auto cCbc : *cFe )
                 {
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                    ChipRegMap cMap = theCbc->getRegMap();
 
-                    if ( !fReadoutChipInterface->WriteChipReg ( cCbc, cReg.first, cFirstBitPattern, true ) )
+                    for ( const auto& cReg : cMap )
                     {
-                        sprintf (line, "# Writing 0x%.2x to CBC Register %s FAILED.\n", cFirstBitPattern, (cReg.first).c_str()  );
-                        LOG (INFO) << BOLDRED << line << RESET ;
-                        report << line ;
-                        fBadRegisters[cCbc->getChipId()] .insert ( cReg.first );
-                        fNBadRegisters++;
-                    }
-
-                    // sleep for 100 ns between register writes
-                    std::this_thread::sleep_for (std::chrono::nanoseconds (100) );
 
-                    if ( !fReadoutChipInterface->WriteChipReg ( cCbc, cReg.first, cSecondBitPattern, true ) )
-                    {
-                        sprintf (line, "# Writing 0x%.2x to CBC Register %s FAILED.\n", cSecondBitPattern, (cReg.first).c_str()  );
-                        LOG (INFO) << BOLDRED << line << RESET ;
-                        report << line ;
-                        fBadRegisters[cCbc->getChipId()] .insert ( cReg.first );
-                        fNBadRegisters++;
+                        if ( !fReadoutChipInterface->WriteChipReg ( theCbc, cReg.first, cFirstBitPattern, true ) )
+                        {
+                            sprintf (line, "# Writing 0x%.2x to CBC Register %s FAILED.\n", cFirstBitPattern, (cReg.first).c_str()  );
+                            LOG (INFO) << BOLDRED << line << RESET ;
+                            report << line ;
+                            fBadRegisters[cCbc->getId()] .insert ( cReg.first );
+                            fNBadRegisters++;
+                        }
+
+                        // sleep for 100 ns between register writes
+                        std::this_thread::sleep_for (std::chrono::nanoseconds (100) );
+
+                        if ( !fReadoutChipInterface->WriteChipReg ( theCbc, cReg.first, cSecondBitPattern, true ) )
+                        {
+                            sprintf (line, "# Writing 0x%.2x to CBC Register %s FAILED.\n", cSecondBitPattern, (cReg.first).c_str()  );
+                            LOG (INFO) << BOLDRED << line << RESET ;
+                            report << line ;
+                            fBadRegisters[cCbc->getId()] .insert ( cReg.first );
+                            fNBadRegisters++;
+                        }
+
+                        // sleep for 100 ns between register writes
+                        std::this_thread::sleep_for (std::chrono::nanoseconds (100) );
                     }
 
-                    // sleep for 100 ns between register writes
-                    std::this_thread::sleep_for (std::chrono::nanoseconds (100) );
+                    fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
                 }
-
-                fBeBoardInterface->ChipReSync ( cBoard );
             }
         }
     }
@@ -70,32 +74,36 @@ void RegisterTester::TestRegisters()
 void RegisterTester::ReconfigureRegisters (std::string pDirectoryName )
 {
 
-    for (auto& cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        fBeBoardInterface->ChipReset ( cBoard );
+        fBeBoardInterface->ChipReset ( static_cast<BeBoard*>(cBoard) );
 
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto& cCbc : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                std::string pRegFile ;
-
-                if ( pDirectoryName.empty() )
-                    pRegFile = "settings/CbcFiles/Cbc_default_electron.txt";
-                else
+                for (auto cCbc : *cFe)
                 {
-                    char buffer[120];
-                    sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cCbc->getFeId(), cCbc->getChipId() );
-                    pRegFile = buffer;
-                }
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                    std::string pRegFile ;
 
-                cCbc->loadfRegMap (pRegFile);
-                fReadoutChipInterface->ConfigureChip ( cCbc );
-                LOG (INFO) << GREEN << "\t\t Successfully (re)configured CBC" << int ( cCbc->getChipId() ) << "'s regsiters from " << pRegFile << " ." << RESET;
+                    if ( pDirectoryName.empty() )
+                        pRegFile = "settings/CbcFiles/Cbc_default_electron.txt";
+                    else
+                    {
+                        char buffer[120];
+                        sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cFe->getId(), cCbc->getId() );
+                        pRegFile = buffer;
+                    }
+
+                    theCbc->loadfRegMap (pRegFile);
+                    fReadoutChipInterface->ConfigureChip ( theCbc );
+                    LOG (INFO) << GREEN << "\t\t Successfully (re)configured CBC" << int ( cCbc->getId() ) << "'s regsiters from " << pRegFile << " ." << RESET;
+                }
             }
         }
 
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 }
 void RegisterTester::PrintTestReport()
diff --git a/tools/SSAPhysics.cc b/tools/SSAPhysics.cc
index 16a68972b..50e945e93 100644
--- a/tools/SSAPhysics.cc
+++ b/tools/SSAPhysics.cc
@@ -169,13 +169,14 @@ void SSAPhysics::fillDataContainer(BoardContainer *const &cBoard)
   // ###################
   // # Clear container #
   // ###################
-  for (const auto cModule : *fOccContainer.at(cBoard->getIndex()))
-    for (const auto cChip : *cModule)
-      for (auto &channel : *cChip->getChannelContainer<Occupancy>())
-      {
-        channel.fOccupancy      = 0;
-        channel.fOccupancyError = 0;
-      }
+  for (const auto cOpticalGroup : *fOccContainer.at(cBoard->getIndex()))
+    for (const auto cModule : *cOpticalGroup)
+      for (const auto cChip : *cModule)
+        for (auto &channel : *cChip->getChannelContainer<Occupancy>())
+        {
+          channel.fOccupancy      = 0;
+          channel.fOccupancyError = 0;
+        }
 
   // ###################
   // # Fill containers #
diff --git a/tools/ShortFinder.cc b/tools/ShortFinder.cc
index 48c905676..bdcff1fc5 100644
--- a/tools/ShortFinder.cc
+++ b/tools/ShortFinder.cc
@@ -57,14 +57,15 @@ void ShortFinder::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(cFirmwareTPdelay,cFirmwareTriggerDelay,1000);
 
     // check that the hits are there... so find test pulse
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         //first, set VCth to the target value for each CBC
-        this->setSameDacBeBoard(cBoard , "VCth", pThreshold);
+        this->setSameDacBeBoard(theBoard , "VCth", pThreshold);
         auto& cThisShortsContainer = fShortsContainer.at(cBoard->getIndex());
         uint16_t cMinValue=0;
-        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( cBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
-        this->setSameDacBeBoard(cBoard, "TriggerLatency", cDelay-1);
+        uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
+        this->setSameDacBeBoard(theBoard, "TriggerLatency", cDelay-1);
         uint8_t cTestGroup=0;
         for(auto cGroup : *fChannelGroupHandler)
         {
@@ -72,36 +73,39 @@ void ShortFinder::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
             // bitset for this group
             std::bitset<NCHANNELS> cBitset = std::bitset<NCHANNELS>( static_cast<const ChannelGroup<NCHANNELS>*>(cGroup)->getBitset() );
             LOG (INFO) << "Injecting charge into front-end object using test capacitor " << +cTestGroup << " : L1A latency set to " << +cDelay << RESET; 
-            this->ReadNEvents ( cBoard , fEventsPerPoint );
-            const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
-            for (auto& cFe : cBoard->fModuleVector)
+            this->ReadNEvents ( theBoard , fEventsPerPoint );
+            const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+            for(auto cOpticalGroup : *cBoard)
             {
-                auto& cHybridShorts = cThisShortsContainer->at(cFe->getIndex());
-                for (auto& cChip : cFe->fReadoutChipVector) 
+                for (auto cFe : *cOpticalGroup)
                 {
-                    auto& cReadoutChipShorts = cHybridShorts->at(cChip->getIndex());
-                    int cNhits=0;
-                    for( auto cEvent : cEvents ) 
+                    auto& cHybridShorts = cThisShortsContainer->at(cOpticalGroup->getIndex())->at(cFe->getIndex());
+                    for (auto cChip : *cFe) 
                     {
-                        // Debug information
-                        auto cEventCount = cEvent->GetEventCount(); 
-                        // Hits
-                        auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
-                        LOG (INFO) << BOLDBLUE << "\t\tGroup " << +cTestGroup << " FE" << +cFe->getFeId() << " .. CBC" << +cChip->getId() << ".. Event " << +cEventCount << " FE" << +cFe->getId() << " - " << +cHits.size() << " hits found/" << +cBitset.count() << " channels in test group" << RESET;
-                        for ( auto cHit : cHits )
+                        auto& cReadoutChipShorts = cHybridShorts->at(cChip->getIndex());
+                        int cNhits=0;
+                        for( auto cEvent : cEvents ) 
                         {
-                            if (cBitset[cHit] == 0) 
+                            // Debug information
+                            auto cEventCount = cEvent->GetEventCount(); 
+                            // Hits
+                            auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
+                            LOG (INFO) << BOLDBLUE << "\t\tGroup " << +cTestGroup << " OG" << +cOpticalGroup->getId() <<  " FE" << +cFe->getId() << " .. CBC" << +cChip->getId() << ".. Event " << +cEventCount << " FE" << +cFe->getId() << " - " << +cHits.size() << " hits found/" << +cBitset.count() << " channels in test group" << RESET;
+                            for ( auto cHit : cHits )
                             {
-                                cReadoutChipShorts->getChannelContainer<int>()->at(cHit)+=1;
+                                if (cBitset[cHit] == 0) 
+                                {
+                                    cReadoutChipShorts->getChannelContainer<int>()->at(cHit)+=1;
+                                }
                             }
+                            cNhits += cHits.size();
                         }
-                        cNhits += cHits.size();
+                        // get list of channels with hits; remember - I've only added a hit if the channel is not in this test group 
+                        auto cShorts = cReadoutChipShorts->getChannelContainer<int>();
+                        float cNshorts = cShorts->size() - std::count (cShorts->begin(), cShorts->end(), 0) ; //
+                        LOG (INFO) << BOLDBLUE << "\t\t\t FE" << +cFe->getId() << " CBC" << +cChip->getId() << " : number of shorts is  " << cNshorts << RESET;
+                
                     }
-                    // get list of channels with hits; remember - I've only added a hit if the channel is not in this test group 
-                    auto cShorts = cReadoutChipShorts->getChannelContainer<int>();
-                    float cNshorts = cShorts->size() - std::count (cShorts->begin(), cShorts->end(), 0) ; //
-                    LOG (INFO) << BOLDBLUE << "\t\t\t FE" << +cFe->getFeId() << " CBC" << +cChip->getId() << " : number of shorts is  " << cNshorts << RESET;
-            
                 }
             }
             cTestGroup++;
diff --git a/tools/SignalScan.cc b/tools/SignalScan.cc
index 7602e88d8..af070ef3a 100644
--- a/tools/SignalScan.cc
+++ b/tools/SignalScan.cc
@@ -10,24 +10,27 @@ SignalScan::~SignalScan()
 
 void SignalScan::Initialize ()
 {
-    for ( auto& cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto& cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-            fNCbc = cFe->getNChip();
-            TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) );
-            // ctmpCanvas->Divide( 2, 2 );
-            fCanvasMap[cFe] = ctmpCanvas;
+            for ( auto cFe : *cOpticalGroup )
+            {
+                uint32_t cFeId = cFe->getId();
+                fNCbc = cFe->size();
+                TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) );
+                // ctmpCanvas->Divide( 2, 2 );
+                fCanvasMap[cFe] = ctmpCanvas;
 
-            // 1D Hist forlatency scan
-            TString cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
-            TObject* cObj = gROOT->FindObject ( cName );
+                // 1D Hist forlatency scan
+                TString cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
+                TObject* cObj = gROOT->FindObject ( cName );
 
-            if ( cObj ) delete cObj;
+                if ( cObj ) delete cObj;
 
-            TH2F* cSignalHist = new TH2F ( cName, Form ( "Signal threshold vs channel FE%d; Channel # ; Threshold; # of Hits", cFeId ), fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, 255, -.5,  255 - .5 );
-            bookHistogram ( cFe, "module_signal", cSignalHist );
+                TH2F* cSignalHist = new TH2F ( cName, Form ( "Signal threshold vs channel FE%d; Channel # ; Threshold; # of Hits", cFeId ), fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, 255, -.5,  255 - .5 );
+                bookHistogram ( cFe, "module_signal", cSignalHist );
+            }
         }
     }
 
@@ -46,174 +49,178 @@ void SignalScan::ScanSignal(uint16_t cVcthStart, uint16_t cVcthStop )
     
     int cNevents = fNevents;
     int cMaxClusterSize = 150; 
-    for ( BeBoard* pBoard : fBoardVector )
+    for (auto cBoard : *fDetectorContainer)
     {
-        fBeBoardInterface->Start(pBoard);
-        fBeBoardInterface->Pause(pBoard);
-        for (auto cFe : pBoard->fModuleVector)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        fBeBoardInterface->Start(theBoard);
+        fBeBoardInterface->Pause(theBoard);
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-
-                uint32_t cCbcId = cCbc->getChipId();
-
-                TString cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getFeId() , +cCbcId );
-                TH2D* cSignalScan = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
-                if ( !cSignalScan ) 
+                for (auto cCbc : *cFe)
                 {
-                    cSignalScan = new TH2D(cHistName.Data(), cHistName.Data() , NCHANNELS + 1 , 0 - 0.5 , NCHANNELS  + 1 - 0.5 , 1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
-                    cSignalScan->GetXaxis()->SetTitle("Channel");
-                    cSignalScan->GetYaxis()->SetTitle("Vcth");
-                    bookHistogram( cCbc , cHistName.Data(), cSignalScan );
-                }
 
-                cHistName = Form("Fe%dCbc%d_ClusterWidth_SignalScan" , +cFe->getFeId() , +cCbcId );
-                TH2D* cClusterWidth = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
-                if ( !cClusterWidth ) 
-                {
-                    cClusterWidth = new TH2D(cHistName.Data(), cHistName.Data() ,  cMaxClusterSize , 0 - 0.5 , cMaxClusterSize - 0.5 , 1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
-                    cClusterWidth->GetXaxis()->SetTitle("Cluster Width");
-                    cClusterWidth->GetYaxis()->SetTitle("Vcth");
-                    bookHistogram( cCbc , cHistName.Data(), cClusterWidth );
-                }
-                cHistName = Form("Fe%dCbc%d_Clusters_SignalScan" , +cFe->getFeId() , +cCbcId );
-                TH1D* cClusters = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
-                if ( !cClusters ) 
-                {
-                    cClusters = new TH1D(cHistName.Data(), cHistName.Data() ,  1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
-                    cClusters->GetXaxis()->SetTitle("Vcth");
-                    bookHistogram( cCbc , cHistName.Data(), cClusters );
-                }
+                    uint32_t cCbcId = cCbc->getId();
 
-                cHistName = Form("Fe%dCbc%d_Time_SignalScan" , +cFe->getFeId() , +cCbcId );
-                TH1D* cTime = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
-                if ( !cTime ) 
-                {
-                    cTime = new TH1D(cHistName.Data(), cHistName.Data() ,  1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
-                    cTime->GetXaxis()->SetTitle("Vcth");
-                    bookHistogram( cCbc , cHistName.Data(), cTime );
-                }
+                    TString cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getId() , +cCbcId );
+                    TH2D* cSignalScan = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
+                    if ( !cSignalScan ) 
+                    {
+                        cSignalScan = new TH2D(cHistName.Data(), cHistName.Data() , NCHANNELS + 1 , 0 - 0.5 , NCHANNELS  + 1 - 0.5 , 1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
+                        cSignalScan->GetXaxis()->SetTitle("Channel");
+                        cSignalScan->GetYaxis()->SetTitle("Vcth");
+                        bookHistogram( cCbc , cHistName.Data(), cSignalScan );
+                    }
 
-            }
+                    cHistName = Form("Fe%dCbc%d_ClusterWidth_SignalScan" , +cFe->getId() , +cCbcId );
+                    TH2D* cClusterWidth = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
+                    if ( !cClusterWidth ) 
+                    {
+                        cClusterWidth = new TH2D(cHistName.Data(), cHistName.Data() ,  cMaxClusterSize , 0 - 0.5 , cMaxClusterSize - 0.5 , 1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
+                        cClusterWidth->GetXaxis()->SetTitle("Cluster Width");
+                        cClusterWidth->GetYaxis()->SetTitle("Vcth");
+                        bookHistogram( cCbc , cHistName.Data(), cClusterWidth );
+                    }
+                    cHistName = Form("Fe%dCbc%d_Clusters_SignalScan" , +cFe->getId() , +cCbcId );
+                    TH1D* cClusters = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
+                    if ( !cClusters ) 
+                    {
+                        cClusters = new TH1D(cHistName.Data(), cHistName.Data() ,  1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
+                        cClusters->GetXaxis()->SetTitle("Vcth");
+                        bookHistogram( cCbc , cHistName.Data(), cClusters );
+                    }
 
-            for( int cVcth = cVcthStart ; cVcth >= cVcthStop ; cVcth -= cVcthStep )
-            {   
-                ThresholdVisitor cVisitor (fReadoutChipInterface, cVcth);
-                cVisitor.setThreshold (cVcth);
-                this->accept ( cVisitor );
-
-                LOG (INFO) << BOLDBLUE <<  "Setting Vcth to " << cVcth << RESET ; 
-                int cTotalHitCounter=0;
-                int cTotalEventCounter=0;
-
-                bool cContinue = true;
-                fBeBoardInterface->Resume(pBoard);
-                LOG (INFO) << BOLDBLUE << "Trying to read data from FEs .... " << RESET ; 
-                Timer t; 
-                t.start();
-                do
-                {
-                    int cHitCounter = 0; 
-                    int cClusterCounter = 0 ; 
-                    
-                    //ReadNEvents ( pBoard, cNeventsPerLoop );
-                    //cTotalEventCounter+= cNeventsPerLoop;
-                    uint32_t cNeventsReadBack = ReadData( pBoard );
-                    if( cNeventsReadBack == 0 )
+                    cHistName = Form("Fe%dCbc%d_Time_SignalScan" , +cFe->getId() , +cCbcId );
+                    TH1D* cTime = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
+                    if ( !cTime ) 
                     {
-                       LOG (INFO) << BOLDRED << "..... Read back " << +cNeventsReadBack << " events!! Why?!" << RESET ;
-                       continue;
+                        cTime = new TH1D(cHistName.Data(), cHistName.Data() ,  1024/cVcthStep , -0.5*cVcthStep , 1024 - 0.5*cVcthStep );
+                        cTime->GetXaxis()->SetTitle("Vcth");
+                        bookHistogram( cCbc , cHistName.Data(), cTime );
                     }
-                    
-                    const std::vector<Event*>& events = GetEvents ( pBoard );
-                    cTotalEventCounter+= events.size() ;
-                    for (auto& cEvent : events)
+
+                }
+
+                for( int cVcth = cVcthStart ; cVcth >= cVcthStop ; cVcth -= cVcthStep )
+                {   
+                    ThresholdVisitor cVisitor (fReadoutChipInterface, cVcth);
+                    cVisitor.setThreshold (cVcth);
+                    this->accept ( cVisitor );
+
+                    LOG (INFO) << BOLDBLUE <<  "Setting Vcth to " << cVcth << RESET ; 
+                    int cTotalHitCounter=0;
+                    int cTotalEventCounter=0;
+
+                    bool cContinue = true;
+                    fBeBoardInterface->Resume(theBoard);
+                    LOG (INFO) << BOLDBLUE << "Trying to read data from FEs .... " << RESET ; 
+                    Timer t; 
+                    t.start();
+                    do
                     {
+                        int cHitCounter = 0; 
+                        int cClusterCounter = 0 ; 
+                        
+                        //ReadNEvents ( theBoard, cNeventsPerLoop );
+                        //cTotalEventCounter+= cNeventsPerLoop;
+                        uint32_t cNeventsReadBack = ReadData( theBoard );
+                        if( cNeventsReadBack == 0 )
+                        {
+                        LOG (INFO) << BOLDRED << "..... Read back " << +cNeventsReadBack << " events!! Why?!" << RESET ;
+                        continue;
+                        }
                         
-                        for ( auto cCbc : cFe->fReadoutChipVector )
+                        const std::vector<Event*>& events = GetEvents ( theBoard );
+                        cTotalEventCounter+= events.size() ;
+                        for (auto& cEvent : events)
                         {
-                            TString cHistName;
-                            cHistName = Form("Fe%dCbc%d_Clusters_SignalScan" , +cFe->getFeId() ,+cCbc->getChipId() );
-                            TH1D* cClustersHisto = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
+                            
+                            for ( auto cCbc : *cFe)
+                            {
+                                TString cHistName;
+                                cHistName = Form("Fe%dCbc%d_Clusters_SignalScan" , +cFe->getId() ,+cCbc->getId() );
+                                TH1D* cClustersHisto = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
 
 
-                            cHistName = Form("Fe%dCbc%d_ClusterWidth_SignalScan" , +cFe->getFeId() , +cCbc->getChipId() );
-                            TH2D* cClusterWidth = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
-                            // cHistName = Form("Fe%dCbc%d_ClusterOccupancy" , +cFe->getFeId() , +cCbc->getChipId() );
-                            // TH2F* cClustersHisto = ( TH2F* ) ( gROOT->FindObject ( cHistName ) );
+                                cHistName = Form("Fe%dCbc%d_ClusterWidth_SignalScan" , +cFe->getId() , +cCbc->getId() );
+                                TH2D* cClusterWidth = ( TH2D* ) ( gROOT->FindObject ( cHistName ) );
+                                // cHistName = Form("Fe%dCbc%d_ClusterOccupancy" , +cFe->getId() , +cCbc->getId() );
+                                // TH2F* cClustersHisto = ( TH2F* ) ( gROOT->FindObject ( cHistName ) );
 
-                            const std::vector<Cluster>& cClusters = cEvent->getClusters( cFe->getFeId(), cCbc->getChipId() );
-                            cClustersHisto->Fill( cVcth , cClusters.size() );
-                            for(auto& cCluster : cClusters)
-                            {
-                                cClusterWidth->Fill(cCluster.fClusterWidth, cVcth );
-                                //cClustersHisto->Fill(cCluster.fFirstStrip, cCluster.fClusterWidth);
-                                if( cCluster.fClusterWidth  <= 2 )
+                                const std::vector<Cluster>& cClusters = cEvent->getClusters( cFe->getId(), cCbc->getId() );
+                                cClustersHisto->Fill( cVcth , cClusters.size() );
+                                for(auto& cCluster : cClusters)
                                 {
-                                    cClusterCounter++;
+                                    cClusterWidth->Fill(cCluster.fClusterWidth, cVcth );
+                                    //cClustersHisto->Fill(cCluster.fFirstStrip, cCluster.fClusterWidth);
+                                    if( cCluster.fClusterWidth  <= 2 )
+                                    {
+                                        cClusterCounter++;
+                                    }
                                 }
-                            }
-                            
-                            cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getFeId() , +cCbc->getChipId() );
-                            TH2D* cSignalScan = dynamic_cast<TH2D*> ( getHist ( cCbc, cHistName.Data() ) );
+                                
+                                cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getId() , +cCbc->getId() );
+                                TH2D* cSignalScan = dynamic_cast<TH2D*> ( getHist ( cCbc, cHistName.Data() ) );
 
-                            for(int cChan = 0 ; cChan < NCHANNELS ; cChan++ )
-                            {
+                                for(int cChan = 0 ; cChan < NCHANNELS ; cChan++ )
+                                {
 
-                                int cHits = cEvent->DataBit ( cFe->getFeId(), cCbc->getChipId(), cChan ); 
-                                cSignalScan->Fill( cChan,cVcth,  cHits );
-                                cHitCounter += cHits;
-                                cTotalHitCounter += cHits;
+                                    int cHits = cEvent->DataBit ( cFe->getId(), cCbc->getId(), cChan ); 
+                                    cSignalScan->Fill( cChan,cVcth,  cHits );
+                                    cHitCounter += cHits;
+                                    cTotalHitCounter += cHits;
+                                }
                             }
                         }
-                    }
 
-                    double cMaxNhits = cNeventsReadBack*NCHANNELS*2 ; 
-                    double cMeanOccupancy  = cHitCounter/(double)(cMaxNhits);
-                    LOG (INFO) << BOLDBLUE << "........Event# " << cTotalEventCounter << " finished - inst. hit occ = " << cMeanOccupancy*100 << " percent [ counting for " << t.getCurrentTime() << " s.]" << RESET ;
-                
-                    cContinue = pTimedRun ? ( t.getCurrentTime() < fTimeToWait ) :  (cTotalEventCounter < cNevents );
-                    std::this_thread::sleep_for (std::chrono::milliseconds (100) );
-                }while( cContinue ); 
+                        double cMaxNhits = cNeventsReadBack*NCHANNELS*2 ; 
+                        double cMeanOccupancy  = cHitCounter/(double)(cMaxNhits);
+                        LOG (INFO) << BOLDBLUE << "........Event# " << cTotalEventCounter << " finished - inst. hit occ = " << cMeanOccupancy*100 << " percent [ counting for " << t.getCurrentTime() << " s.]" << RESET ;
+                    
+                        cContinue = pTimedRun ? ( t.getCurrentTime() < fTimeToWait ) :  (cTotalEventCounter < cNevents );
+                        std::this_thread::sleep_for (std::chrono::milliseconds (100) );
+                    }while( cContinue ); 
 
-                double cTimeElapsed = t.getCurrentTime();  
-                for ( auto cCbc : cFe->fReadoutChipVector )
-                {
-                    TString cHistName = Form("Fe%dCbc%d_Time_SignalScan" , +cFe->getFeId() , +cCbc->getChipId() );
-                    TH1D* cTime = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
-                    cTime->Fill( cVcth , cTimeElapsed );
-                }
-                fBeBoardInterface->Pause(pBoard);
-                t.stop();
+                    double cTimeElapsed = t.getCurrentTime();  
+                    for ( auto cCbc : *cFe)
+                    {
+                        TString cHistName = Form("Fe%dCbc%d_Time_SignalScan" , +cFe->getId() , +cCbc->getId() );
+                        TH1D* cTime = ( TH1D* ) ( gROOT->FindObject ( cHistName ) );
+                        cTime->Fill( cVcth , cTimeElapsed );
+                    }
+                    fBeBoardInterface->Pause(theBoard);
+                    t.stop();
 
-                // calculate efficiency and assoc. error for each channel 
-                for ( auto cCbc : cFe->fReadoutChipVector )
-                {
-                    TString cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getFeId() , +cCbc->getChipId() );
-                    TH2D* cSignalScan = dynamic_cast<TH2D*> ( getHist ( cCbc, cHistName.Data() ) );
-                    int cBinY = cSignalScan->GetYaxis()->FindBin( cVcth );
+                    // calculate efficiency and assoc. error for each channel 
+                    for ( auto cCbc : *cFe )
+                    {
+                        TString cHistName = Form("Fe%dCbc%d_SignalScan" , +cFe->getId() , +cCbc->getId() );
+                        TH2D* cSignalScan = dynamic_cast<TH2D*> ( getHist ( cCbc, cHistName.Data() ) );
+                        int cBinY = cSignalScan->GetYaxis()->FindBin( cVcth );
 
 
-                    for( int cBin = 1 ; cBin < cSignalScan->GetNbinsX() ; cBin++ )
-                    {
-                        int cHits = cSignalScan->GetBinContent(cBin, cBinY);
-                        double k = (double)cHits;
-                        double n = (double)cTotalEventCounter;
-                        
-                        double cEfficiency_Bayesian =  (k+1)/(n+2);
-                        double cSigmaEfficiency_Bayesian = std::sqrt( ((k+1)*(k+2))/( (n+2)*(n+3) ) - std::pow((k+1)/(n+2) , 2.0) );
+                        for( int cBin = 1 ; cBin < cSignalScan->GetNbinsX() ; cBin++ )
+                        {
+                            int cHits = cSignalScan->GetBinContent(cBin, cBinY);
+                            double k = (double)cHits;
+                            double n = (double)cTotalEventCounter;
+                            
+                            double cEfficiency_Bayesian =  (k+1)/(n+2);
+                            double cSigmaEfficiency_Bayesian = std::sqrt( ((k+1)*(k+2))/( (n+2)*(n+3) ) - std::pow((k+1)/(n+2) , 2.0) );
 
-                        cSignalScan->SetBinContent(cBin ,cBinY, cEfficiency_Bayesian*100);
-                        cSignalScan->SetBinError(cBin, cBinY, cSigmaEfficiency_Bayesian*100);
+                            cSignalScan->SetBinContent(cBin ,cBinY, cEfficiency_Bayesian*100);
+                            cSignalScan->SetBinError(cBin, cBinY, cSigmaEfficiency_Bayesian*100);
+                        }
                     }
-                }
 
-                // stop if it takes more than 20 s to record the data point ... 
-                if( cTimeElapsed > 20 )
-                    break; 
+                    // stop if it takes more than 20 s to record the data point ... 
+                    if( cTimeElapsed > 20 )
+                        break; 
+                }
             }
         }
-        fBeBoardInterface->Stop(pBoard);
+        fBeBoardInterface->Stop(theBoard);
     }
 
 }
diff --git a/tools/SignalScanFit.cc b/tools/SignalScanFit.cc
index 85dfbc131..94b964814 100644
--- a/tools/SignalScanFit.cc
+++ b/tools/SignalScanFit.cc
@@ -11,100 +11,103 @@ void SignalScanFit::Initialize ( )
     parseSettings();    
 
     // Initialize all the plots
-    for ( auto& cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto& cFe : cBoard->fModuleVector )
+        for(auto cOpticalGroup : *cBoard)
         {
+            for ( auto cFe : *cOpticalGroup)
+            {
 
-            fVCthNbins = int( (1024 / double(fSignalScanStep)) + 1 ); 
-            fVCthMax = double( ( fVCthNbins * fSignalScanStep ) - (double(fSignalScanStep) / 2.) ); //"center" de bins
-            fVCthMin = 0. - ( double(fSignalScanStep) / 2. );
+                fVCthNbins = int( (1024 / double(fSignalScanStep)) + 1 ); 
+                fVCthMax = double( ( fVCthNbins * fSignalScanStep ) - (double(fSignalScanStep) / 2.) ); //"center" de bins
+                fVCthMin = 0. - ( double(fSignalScanStep) / 2. );
 
-            // Make a canvas for the live plot
-            uint32_t cFeId = cFe->getFeId();
-            fNCbc = 0;//cFe->getNChip();
-            for ( auto cCbc : cFe->fReadoutChipVector )
-            {
-                fNCbc = ( cCbc->getChipId() >= fNCbc ) ? (cCbc->getChipId()+1) : fNCbc; 
-            }
-            TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) ); 
-            fCanvasMap[cFe] = ctmpCanvas;
-
-            // Histograms
-            TString cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
-            TObject* cObj = gROOT->FindObject ( cName );
-
-            if ( cObj ) delete cObj;
-            
-            // 2D-plot with all the channels on the x-axis, Vcth on the y-axis and #clusters on the z-axis.
-            cName =  Form ( "h_module_thresholdScan_SingleStripClusters_S0_Fe%d", cFeId );
-            TH2D* cSignalEven = new TH2D ( cName, "Signal threshold vs channel [half strips] ; Even Sensor Strip [half strips] ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
-            bookHistogram ( cFe, "SingleStripClusters_S0", cSignalEven );
-            
-            cName =  Form ( "h_module_thresholdScan_SingleStripClusters_S1_Fe%d", cFeId );
-            TH2D* cSignalOdd = new TH2D ( cName, "Signal threshold vs channel [half strips] ; Odd Sensor Strip [half strips] ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
-            bookHistogram ( cFe, "SingleStripClusters_S1", cSignalOdd );
-
-            // 2D-plot with all the channels on the x-axis, Vcth on the y-axis and #clusters on the z-axis.
-            cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
-            TH2D* cSignalHist = new TH2D ( cName, "Signal threshold vs channel ; Channel # ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
-            bookHistogram ( cFe, "module_signal", cSignalHist );
-
-            // 2D-plot with cluster width on the x-axis, Vcth on y-axis, counts of certain clustersize on z-axis.
-            TH2D* cVCthClusterSizeHist = new TH2D ( Form ( "h_module_clusterSize_per_Vcth_Fe%d", cFeId ), "Cluster size vs Vcth ; Cluster size [strips] ; Threshold [Vcth] ; # clusters", 15, -0.5, 14.5, fVCthNbins, fVCthMin, fVCthMax );
-            bookHistogram ( cFe, "vcth_ClusterSize", cVCthClusterSizeHist );
-
-            // 1D-plot with the number of triggers per VCth
-            TProfile* cNumberOfTriggers = new TProfile ( Form("h_module_totalNumberOfTriggers_Fe%d", cFeId), Form ( "Total number of triggers received ; Threshold [Vcth] ; Number of triggers" ), fVCthNbins, fVCthMin, fVCthMax);
-            bookHistogram ( cFe, "number_of_triggers", cNumberOfTriggers );
-
-            // 1D-plot with the timeout value per VCth
-            TH1D* cNclocks = new TH1D ( Form("h_module_nClocks_Fe%d", cFeId), Form ( "Number of clock cycles spent at each Vcth value ; Threshold [Vcth] ; Number of clocks to wait" ), fVCthNbins, fVCthMin, fVCthMax);
-            bookHistogram ( cFe, "number_of_clocks", cNclocks );
-
-            uint32_t cCbcCount = 0;
-            uint32_t cCbcIdMax = 0;
-
-            for ( auto cCbc : cFe->fReadoutChipVector )
-            {
-                uint32_t cCbcId = cCbc->getChipId();
-                cCbcCount++;
+                // Make a canvas for the live plot
+                uint32_t cFeId = cFe->getId();
+                fNCbc = 0;//cFe->getNChip();
+                for ( auto cCbc : *cFe)
+                {
+                    fNCbc = ( cCbc->getId() >= fNCbc ) ? (cCbc->getId()+1) : fNCbc; 
+                }
+                TCanvas* ctmpCanvas = new TCanvas ( Form ( "c_online_canvas_fe%d", cFeId ), Form ( "FE%d  Online Canvas", cFeId ) ); 
+                fCanvasMap[cFe] = ctmpCanvas;
 
-                if ( cCbcId > cCbcIdMax ) cCbcIdMax = cCbcId;
+                // Histograms
+                TString cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
+                TObject* cObj = gROOT->FindObject ( cName );
 
-                TString cHistname;
-                TH1D* cHist;
-                TH2D* cHist2D;
+                if ( cObj ) delete cObj;
+                
+                // 2D-plot with all the channels on the x-axis, Vcth on the y-axis and #clusters on the z-axis.
+                cName =  Form ( "h_module_thresholdScan_SingleStripClusters_S0_Fe%d", cFeId );
+                TH2D* cSignalEven = new TH2D ( cName, "Signal threshold vs channel [half strips] ; Even Sensor Strip [half strips] ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
+                bookHistogram ( cFe, "SingleStripClusters_S0", cSignalEven );
+                
+                cName =  Form ( "h_module_thresholdScan_SingleStripClusters_S1_Fe%d", cFeId );
+                TH2D* cSignalOdd = new TH2D ( cName, "Signal threshold vs channel [half strips] ; Odd Sensor Strip [half strips] ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
+                bookHistogram ( cFe, "SingleStripClusters_S1", cSignalOdd );
 
-                cHistname = Form ( "Fe%dCBC%d_Hits_even", cFeId, cCbcId );
-                cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of hits", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
-                bookHistogram ( cCbc, "Cbc_Hits_even", cHist );
+                // 2D-plot with all the channels on the x-axis, Vcth on the y-axis and #clusters on the z-axis.
+                cName =  Form ( "h_module_thresholdScan_Fe%d", cFeId );
+                TH2D* cSignalHist = new TH2D ( cName, "Signal threshold vs channel ; Channel # ; Threshold; # of Hits", fNCbc * NCHANNELS, -0.5, fNCbc * NCHANNELS - 0.5, fVCthNbins, fVCthMin, fVCthMax );
+                bookHistogram ( cFe, "module_signal", cSignalHist );
 
-                cHistname = Form ( "Fe%dCBC%d_Hits_odd", cFeId, cCbcId );
-                cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of hits", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
-                bookHistogram ( cCbc, "Cbc_Hits_odd", cHist );
+                // 2D-plot with cluster width on the x-axis, Vcth on y-axis, counts of certain clustersize on z-axis.
+                TH2D* cVCthClusterSizeHist = new TH2D ( Form ( "h_module_clusterSize_per_Vcth_Fe%d", cFeId ), "Cluster size vs Vcth ; Cluster size [strips] ; Threshold [Vcth] ; # clusters", 15, -0.5, 14.5, fVCthNbins, fVCthMin, fVCthMax );
+                bookHistogram ( cFe, "vcth_ClusterSize", cVCthClusterSizeHist );
 
-                cHistname = Form ( "Fe%dCBC%d_Clusters2D_even", cFeId, cCbcId );
-                cHist2D = new TH2D ( cHistname, Form("%s ; Threshold [Vcth] ; Cluster Size [strips];Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax , 20 , 0-0.5 , 20-0.5 );
-                bookHistogram ( cCbc, "Cbc_Clusters2D_even", cHist2D );
-                
-                cHistname = Form ( "Fe%dCBC%d_Clusters_even", cFeId, cCbcId );
-                cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
-                bookHistogram ( cCbc, "Cbc_Clusters_even", cHist );
+                // 1D-plot with the number of triggers per VCth
+                TProfile* cNumberOfTriggers = new TProfile ( Form("h_module_totalNumberOfTriggers_Fe%d", cFeId), Form ( "Total number of triggers received ; Threshold [Vcth] ; Number of triggers" ), fVCthNbins, fVCthMin, fVCthMax);
+                bookHistogram ( cFe, "number_of_triggers", cNumberOfTriggers );
 
-                cHistname = Form ( "Fe%dCBC%d_Clusters_odd", cFeId, cCbcId );
-                cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
-                bookHistogram ( cCbc, "Cbc_Clusters_odd", cHist );
-                
-                cHistname = Form ( "Fe%dCBC%d_Clusters2D_odd", cFeId, cCbcId );
-                cHist2D = new TH2D ( cHistname, Form("%s ; Threshold [Vcth] ; Cluster Size [strips];Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax , 20 , 0-0.5 , 20-0.5 );
-                bookHistogram ( cCbc, "Cbc_Clusters2D_odd", cHist2D );
+                // 1D-plot with the timeout value per VCth
+                TH1D* cNclocks = new TH1D ( Form("h_module_nClocks_Fe%d", cFeId), Form ( "Number of clock cycles spent at each Vcth value ; Threshold [Vcth] ; Number of clocks to wait" ), fVCthNbins, fVCthMin, fVCthMax);
+                bookHistogram ( cFe, "number_of_clocks", cNclocks );
 
-                cHistname = Form ( "Fe%dCBC%d_ClusterSize_even", cFeId, cCbcId );
-                bookHistogram ( cCbc, "Cbc_ClusterSize_even", cHist );
+                uint32_t cCbcCount = 0;
+                uint32_t cCbcIdMax = 0;
 
-                cHistname = Form ( "Fe%dCBC%d_ClusterSize_odd", cFeId, cCbcId );
-                bookHistogram ( cCbc, "Cbc_ClusterSize_odd", cHist );
+                for ( auto cCbc : *cFe )
+                {
+                    uint32_t cCbcId = cCbc->getId();
+                    cCbcCount++;
+
+                    if ( cCbcId > cCbcIdMax ) cCbcIdMax = cCbcId;
+
+                    TString cHistname;
+                    TH1D* cHist;
+                    TH2D* cHist2D;
+
+                    cHistname = Form ( "Fe%dCBC%d_Hits_even", cFeId, cCbcId );
+                    cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of hits", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
+                    bookHistogram ( cCbc, "Cbc_Hits_even", cHist );
+
+                    cHistname = Form ( "Fe%dCBC%d_Hits_odd", cFeId, cCbcId );
+                    cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of hits", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
+                    bookHistogram ( cCbc, "Cbc_Hits_odd", cHist );
+
+                    cHistname = Form ( "Fe%dCBC%d_Clusters2D_even", cFeId, cCbcId );
+                    cHist2D = new TH2D ( cHistname, Form("%s ; Threshold [Vcth] ; Cluster Size [strips];Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax , 20 , 0-0.5 , 20-0.5 );
+                    bookHistogram ( cCbc, "Cbc_Clusters2D_even", cHist2D );
+                    
+                    cHistname = Form ( "Fe%dCBC%d_Clusters_even", cFeId, cCbcId );
+                    cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
+                    bookHistogram ( cCbc, "Cbc_Clusters_even", cHist );
+
+                    cHistname = Form ( "Fe%dCBC%d_Clusters_odd", cFeId, cCbcId );
+                    cHist = new TH1D ( cHistname, Form("%s ; Threshold [Vcth] ; Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax );
+                    bookHistogram ( cCbc, "Cbc_Clusters_odd", cHist );
+                    
+                    cHistname = Form ( "Fe%dCBC%d_Clusters2D_odd", cFeId, cCbcId );
+                    cHist2D = new TH2D ( cHistname, Form("%s ; Threshold [Vcth] ; Cluster Size [strips];Number of clusters", cHistname.Data()), fVCthNbins, fVCthMin, fVCthMax , 20 , 0-0.5 , 20-0.5 );
+                    bookHistogram ( cCbc, "Cbc_Clusters2D_odd", cHist2D );
+
+                    cHistname = Form ( "Fe%dCBC%d_ClusterSize_even", cFeId, cCbcId );
+                    bookHistogram ( cCbc, "Cbc_ClusterSize_even", cHist );
+
+                    cHistname = Form ( "Fe%dCBC%d_ClusterSize_odd", cFeId, cCbcId );
+                    bookHistogram ( cCbc, "Cbc_ClusterSize_odd", cHist );
+                }
             }
         }
     }
@@ -133,33 +136,34 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
     {
         LOG (DEBUG) << BLUE << "Threshold: " << +cVCth << " - Iteration " << i << " - Taking data for x*25ns time (see triggers_to_accept in HWDesciption file.)" << RESET;
         // Take Data for all Boards
-        for ( BeBoard* pBoard : fBoardVector )
+        for ( auto pBoard : *fDetectorContainer )
         {
+            BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
             uint32_t cTotalEvents = 0;
-            uint32_t cTriggerSource = fBeBoardInterface->ReadBoardReg( pBoard , "fc7_daq_cnfg.fast_command_block.trigger_source"); // check trigger source
+            uint32_t cTriggerSource = fBeBoardInterface->ReadBoardReg( theBoard , "fc7_daq_cnfg.fast_command_block.trigger_source"); // check trigger source
             double cTime=0;
             uint32_t cTimeout=0;
             if( cTriggerSource == 2 ) 
             {
                 // start the trigger FSM
-                fBeBoardInterface->Start (pBoard);
+                fBeBoardInterface->Start (theBoard);
                 std::this_thread::sleep_for (std::chrono::microseconds (100) );
                 // if timeout is enabled ... then wait here until the trigger FMS is ready 
-                while ( fBeBoardInterface->ReadBoardReg (pBoard, "fc7_daq_stat.fast_command_block.general.fsm_state" ) !=  0 )
+                while ( fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_stat.fast_command_block.general.fsm_state" ) !=  0 )
                 {
                     std::this_thread::sleep_for (std::chrono::microseconds (100) );
                 }
-                ReadData( pBoard, false);
-                fBeBoardInterface->Stop (pBoard);
+                ReadData( theBoard, false);
+                fBeBoardInterface->Stop (theBoard);
                 std::this_thread::sleep_for (std::chrono::microseconds (100) );
-                cTimeout = fBeBoardInterface->ReadBoardReg( pBoard , "fc7_daq_cnfg.fast_command_block.triggers_to_accept"); // in units of 25ns periods
+                cTimeout = fBeBoardInterface->ReadBoardReg( theBoard , "fc7_daq_cnfg.fast_command_block.triggers_to_accept"); // in units of 25ns periods
                 cTime = cTimeout*25.0; 
             }
             else 
             {
                 LOG (INFO) << BOLDBLUE << "Generating periodic triggers : sending " << +fNevents << " triggers." << RESET;
                 // start the trigger FSM
-                fBeBoardInterface->Start (pBoard);
+                fBeBoardInterface->Start (theBoard);
                 std::this_thread::sleep_for (std::chrono::microseconds (100) );
                 // if timeout is enabled ... then wait here until the trigger FMS is ready 
                 uint8_t cCounter=0;
@@ -168,13 +172,13 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
                     std::this_thread::sleep_for (std::chrono::milliseconds (10) );
                     cCounter+=1;
                 }
-                fBeBoardInterface->Stop (pBoard);
+                fBeBoardInterface->Stop (theBoard);
                 std::this_thread::sleep_for (std::chrono::microseconds (10) );
-                ReadData( pBoard, false);
+                ReadData( theBoard, false);
                 cTimeout = 10e-3;
                 cTime = fNevents * 1e-3;
             }
-            const std::vector<Event*>& cEvents = GetEvents ( pBoard ); // Get the events and play with them    
+            const std::vector<Event*>& cEvents = GetEvents ( theBoard ); // Get the events and play with them    
             double   cTriggerRate = (cEvents.size())/cTime; 
             cTotalEvents = cEvents.size();
             LOG (INFO) << BOLDBLUE << "Vcth: " << +cVCth << ". Recorded " << cTotalEvents << " Events [ average trigger rate " << cTriggerRate << " ]"<< RESET;
@@ -188,71 +192,74 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
             {
                 //if( (uint32_t)cEventCounter > cMaxEvents_toProcess ) 
                 //    continue;
-                for ( auto cFe : pBoard->fModuleVector )
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    TH1D* cClocksHist       = static_cast<TH1D*> ( getHist ( cFe, "number_of_clocks" ) );  
-                    TH2D* cClustersS0       = static_cast<TH2D*> ( getHist ( cFe, "SingleStripClusters_S0") );
-                    TH2D* cClustersS1       = static_cast<TH2D*> ( getHist ( cFe, "SingleStripClusters_S1") );
-                    TH2D* cSignalHist       = static_cast<TH2D*> ( getHist ( cFe, "module_signal") );
-                    TH2D* cVcthClusters     = static_cast<TH2D*> ( getHist ( cFe, "vcth_ClusterSize" ) );
-                    TProfile* cEventsHist   = static_cast<TProfile*> ( getHist ( cFe, "number_of_triggers" ) );
-                    if( cEventCounter == 0 )
-                    {
-                        cClocksHist->Fill( cVCth, cTimeout );
-                        cEventsHist->Fill( cVCth, cTotalEvents );
-                    }
-                    for ( auto cCbc : cFe->fReadoutChipVector )
+                    for ( auto cFe : *cOpticalGroup )
                     {
-                        TH1D* cHitsEvenHist         = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Hits_even" ) );
-                        TH1D* cHitsOddHist          = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Hits_odd" ) );
-                        TH1D* cClustersEvenHist     = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Clusters_even" ) );
-                        TH1D* cClustersOddHist      = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Clusters_odd" ) );
-                        TProfile* cClusterSizeEven  = static_cast<TProfile*> ( getHist ( cCbc, "Cbc_ClusterSize_even" ) );
-                        TProfile* cClusterSizeOdd   = static_cast<TProfile*> ( getHist ( cCbc, "Cbc_ClusterSize_odd" ) );
-                        TH2D* cClusters2DEvenHist     = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_even" ) );
-                        TH2D* cClusters2DOddHist      = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_odd" ) );
-                        std::vector<uint32_t> cHits = cEvent->GetHits( cCbc->getFeId() , cCbc->getChipId() );
-                        LOG (DEBUG) << BOLDBLUE << "Found " << +cHits.size() << " hits in CBC" << +cCbc->getChipId() << RESET;
-                        for ( auto cId : cHits ) 
+                        TH1D* cClocksHist       = static_cast<TH1D*> ( getHist ( cFe, "number_of_clocks" ) );  
+                        TH2D* cClustersS0       = static_cast<TH2D*> ( getHist ( cFe, "SingleStripClusters_S0") );
+                        TH2D* cClustersS1       = static_cast<TH2D*> ( getHist ( cFe, "SingleStripClusters_S1") );
+                        TH2D* cSignalHist       = static_cast<TH2D*> ( getHist ( cFe, "module_signal") );
+                        TH2D* cVcthClusters     = static_cast<TH2D*> ( getHist ( cFe, "vcth_ClusterSize" ) );
+                        TProfile* cEventsHist   = static_cast<TProfile*> ( getHist ( cFe, "number_of_triggers" ) );
+                        if( cEventCounter == 0 )
                         {
-                            LOG (DEBUG) << BOLDBLUE << "\t.... Hit found in channel " << +cId << " i.e. sensor " << (int)(cId%2) << RESET;
-                            // Check which sensor we are on
-                            if ( ( int (cId) % 2 ) == 0 ) 
-                                cHitsEvenHist->Fill( cVCth );
-                            else 
-                                cHitsOddHist->Fill( cVCth );
-
-                            cSignalHist->Fill (cCbc->getChipId() * NCHANNELS + cId, cVCth );
-                            cEventHits++;
-                        }//end for cId 
-                        // Fill the cluster histos, use the middleware clustering
-                        std::vector<Cluster> cClusters = cEvent->getClusters (cCbc->getFeId(), cCbc->getChipId() ); 
-                        cEventClusters += cClusters.size();
-                        // Now fill the ClusterWidth per VCth plots:
-                        for ( auto& cCluster : cClusters )
+                            cClocksHist->Fill( cVCth, cTimeout );
+                            cEventsHist->Fill( cVCth, cTotalEvents );
+                        }
+                        for ( auto cCbc : *cFe)
                         {
-                            double cClusterSize = cCluster.fClusterWidth;
-                            cVcthClusters->Fill( cClusterSize, cCluster.fClusterWidth ); // Cluster size counter
-                            uint32_t cStrip = cCluster.getBaricentre()*2 + cCbc->getChipId()*127*2;
-                            LOG (DEBUG) << BOLDBLUE << "\t " << cClusterSize << " strip cluster found with center in strip " << cStrip << " [half-strips] of sensor " << +cCluster.fSensor << RESET;
-                            if ( cCluster.fSensor == 0 ) 
+                            TH1D* cHitsEvenHist         = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Hits_even" ) );
+                            TH1D* cHitsOddHist          = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Hits_odd" ) );
+                            TH1D* cClustersEvenHist     = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Clusters_even" ) );
+                            TH1D* cClustersOddHist      = dynamic_cast<TH1D*> ( getHist ( cCbc, "Cbc_Clusters_odd" ) );
+                            TProfile* cClusterSizeEven  = static_cast<TProfile*> ( getHist ( cCbc, "Cbc_ClusterSize_even" ) );
+                            TProfile* cClusterSizeOdd   = static_cast<TProfile*> ( getHist ( cCbc, "Cbc_ClusterSize_odd" ) );
+                            TH2D* cClusters2DEvenHist     = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_even" ) );
+                            TH2D* cClusters2DOddHist      = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_odd" ) );
+                            std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getId(), cCbc->getId() );
+                            LOG (DEBUG) << BOLDBLUE << "Found " << +cHits.size() << " hits in CBC" << +cCbc->getChipId() << RESET;
+                            for ( auto cId : cHits ) 
                             {
-                                if( cCluster.fClusterWidth == 1 )
-                                    cClustersS0->Fill( cStrip, cVCth );
-                                cClustersEvenHist->Fill ( cVCth );
-                                cClusterSizeEven->Fill ( cVCth, cClusterSize );
-                                cClusters2DEvenHist->Fill( cVCth, cClusterSize);
-                            } 
-                            else if ( cCluster.fSensor == 1 ) 
+                                LOG (DEBUG) << BOLDBLUE << "\t.... Hit found in channel " << +cId << " i.e. sensor " << (int)(cId%2) << RESET;
+                                // Check which sensor we are on
+                                if ( ( int (cId) % 2 ) == 0 ) 
+                                    cHitsEvenHist->Fill( cVCth );
+                                else 
+                                    cHitsOddHist->Fill( cVCth );
+
+                                cSignalHist->Fill (cCbc->getId() * NCHANNELS + cId, cVCth );
+                                cEventHits++;
+                            }//end for cId 
+                            // Fill the cluster histos, use the middleware clustering
+                            std::vector<Cluster> cClusters = cEvent->getClusters (cFe->getId(), cCbc->getId() ); 
+                            cEventClusters += cClusters.size();
+                            // Now fill the ClusterWidth per VCth plots:
+                            for ( auto& cCluster : cClusters )
                             {
-                                if( cCluster.fClusterWidth == 1 )
-                                    cClustersS1->Fill( cStrip , cVCth);
-                                cClustersOddHist->Fill ( cVCth );
-                                cClusterSizeOdd->Fill ( cVCth, cClusterSize );
-                                cClusters2DOddHist->Fill( cVCth, cClusterSize);
+                                double cClusterSize = cCluster.fClusterWidth;
+                                cVcthClusters->Fill( cClusterSize, cCluster.fClusterWidth ); // Cluster size counter
+                                uint32_t cStrip = cCluster.getBaricentre()*2 + cCbc->getId()*127*2;
+                                LOG (DEBUG) << BOLDBLUE << "\t " << cClusterSize << " strip cluster found with center in strip " << cStrip << " [half-strips] of sensor " << +cCluster.fSensor << RESET;
+                                if ( cCluster.fSensor == 0 ) 
+                                {
+                                    if( cCluster.fClusterWidth == 1 )
+                                        cClustersS0->Fill( cStrip, cVCth );
+                                    cClustersEvenHist->Fill ( cVCth );
+                                    cClusterSizeEven->Fill ( cVCth, cClusterSize );
+                                    cClusters2DEvenHist->Fill( cVCth, cClusterSize);
+                                } 
+                                else if ( cCluster.fSensor == 1 ) 
+                                {
+                                    if( cCluster.fClusterWidth == 1 )
+                                        cClustersS1->Fill( cStrip , cVCth);
+                                    cClustersOddHist->Fill ( cVCth );
+                                    cClusterSizeOdd->Fill ( cVCth, cClusterSize );
+                                    cClusters2DOddHist->Fill( cVCth, cClusterSize);
+                                }
                             }
-                        }
 
+                        }
                     }
                 }
                 cEventCounter+=1;
diff --git a/tools/StubQuickCheck.cc b/tools/StubQuickCheck.cc
index f1502dfd1..883b0db10 100644
--- a/tools/StubQuickCheck.cc
+++ b/tools/StubQuickCheck.cc
@@ -62,39 +62,47 @@ void StubQuickCheck::Initialise ()
     }
     
 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            TString  cName = Form ( "h_StubBend");
-            TObject* cObj = gROOT->FindObject ( cName );
-            if ( cObj ) delete cObj;
-            TH1D* cBend = new TH1D ( cName, Form("Stub Bend - CIC%d; Bend",(int)cFe->getFeId()) , cBinsBend_Default.size()-1, cBinsBend_Default.data() );
-            bookHistogram ( cFe , "StubBend", cBend );
-            
-            cName = Form ( "h_StubInformation");
-            cObj = gROOT->FindObject ( cName );
-            TH2D* cStubInformation = new TH2D ( cName, Form("Stub Information - CIC%d ; Stub Bend; Stub Seed",(int)cFe->getFeId()) , cBinsBend_Default.size()-1, cBinsBend_Default.data(), 127*8/0.5, 0 , 127*8 );
-            bookHistogram ( cFe , "StubInformation", cStubInformation );
-            
-            cName = Form ( "h_StubHitCorrelation");
-            cObj = gROOT->FindObject ( cName );
-            TH2D* cStubHitCorrelation = new TH2D ( cName, Form("Stub & Hit correlation - CIC%d; Hit in Bottom Sensor ; Stub Seed",(int)cFe->getFeId()) , 127*8, 0 , 127*8 , 127*8/0.5, 0 , 127*8 );
-            bookHistogram ( cFe , "StubHitCorrelation", cStubHitCorrelation );
-            
-            // now want to loop over all other FEs 
-            for (auto& cOtherFe : cBoard->fModuleVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                if( cFe->getFeId() == cOtherFe->getFeId() )
-                    continue;
+                TString  cName = Form ( "h_StubBend");
+                TObject* cObj = gROOT->FindObject ( cName );
+                if ( cObj ) delete cObj;
+                TH1D* cBend = new TH1D ( cName, Form("Stub Bend - CIC%d; Bend",(int)cFe->getId()) , cBinsBend_Default.size()-1, cBinsBend_Default.data() );
+                bookHistogram ( cFe , "StubBend", cBend );
                 
-                cName = Form ( "h_BxId_Cic%d_Cic%d", cFe->getFeId(), cOtherFe->getFeId());
+                cName = Form ( "h_StubInformation");
                 cObj = gROOT->FindObject ( cName );
-                if ( cObj ) delete cObj;
-                TString cTitle = Form("BxId from 2 CICs [%d and %d] on links [%d and %d]; Bx Id [CIC %d]; BxId [CIC%d]", cFe->getFeId(), cOtherFe->getFeId(), cFe->getLinkId(), cOtherFe->getLinkId(), cFe->getFeId(), cOtherFe->getFeId());
-                TH2D* cHist2D = new TH2D( cName, cTitle , 3565 , 0 , 3565 , 3565 , 0 , 3565);
-                bookHistogram ( cFe , Form("BxId_CIC%d", cOtherFe->getFeId()), cHist2D );
+                TH2D* cStubInformation = new TH2D ( cName, Form("Stub Information - CIC%d ; Stub Bend; Stub Seed",(int)cFe->getId()) , cBinsBend_Default.size()-1, cBinsBend_Default.data(), 127*8/0.5, 0 , 127*8 );
+                bookHistogram ( cFe , "StubInformation", cStubInformation );
+                
+                cName = Form ( "h_StubHitCorrelation");
+                cObj = gROOT->FindObject ( cName );
+                TH2D* cStubHitCorrelation = new TH2D ( cName, Form("Stub & Hit correlation - CIC%d; Hit in Bottom Sensor ; Stub Seed",(int)cFe->getId()) , 127*8, 0 , 127*8 , 127*8/0.5, 0 , 127*8 );
+                bookHistogram ( cFe , "StubHitCorrelation", cStubHitCorrelation );
+                
+                // now want to loop over all other FEs 
+                for(auto cOtherOpticalGroup : *cBoard)
+                {
+                    if( cOpticalGroup->getId() == cOtherOpticalGroup->getId() )
+                        continue;
+
+                    for (auto& cOtherFe : *cOtherOpticalGroup)
+                    {
+                        if( cFe->getId() == cOtherFe->getId() )
+                            continue;
+                        
+                        cName = Form ( "h_BxId_Cic%d_Cic%d", cFe->getId(), cOtherFe->getId());
+                        cObj = gROOT->FindObject ( cName );
+                        if ( cObj ) delete cObj;
+                        TString cTitle = Form("BxId from 2 CICs [%d and %d] on links [%d and %d]; Bx Id [CIC %d]; BxId [CIC%d]", cFe->getId(), cOtherFe->getId(), static_cast<OuterTrackerModule*>(cFe)->getLinkId(), static_cast<OuterTrackerModule*>(cOtherFe)->getLinkId(), cFe->getId(), cOtherFe->getId());
+                        TH2D* cHist2D = new TH2D( cName, cTitle , 3565 , 0 , 3565 , 3565 , 0 , 3565);
+                        bookHistogram ( cFe , Form("BxId_CIC%d", cOtherFe->getId()), cHist2D );
+                    }
+                }
             }
         }
         
@@ -156,98 +164,107 @@ void StubQuickCheck::StubCheck(BeBoard* pBoard, const std::vector<Event*> pEvent
         LOG (DEBUG) << BOLDBLUE << "Event " << +cEventCount << " --- TDC  " << +cTDC << RESET;
         std::vector<double> cSeeds(0);
 
-        for (auto& cFe : pBoard->fModuleVector)
+        for(auto cOpticalGroup : *pBoard)
         {
-            TH1D* cBendHistogram = static_cast<TH1D*> ( getHist ( cFe, Form("StubBend") ) );
-            TH2D* cStubInformation = static_cast<TH2D*> ( getHist ( cFe, Form("StubInformation") ) );
-            TH2D* cStubHitCorrelation = static_cast<TH2D*> ( getHist ( cFe, Form("StubHitCorrelation") ) );
-
-            auto cBxId = cEvent->BxId( cFe->getFeId() );
-            auto cStatus = static_cast<D19cCicEvent*>(cEvent)->Status ( cFe->getFeId() );
-            LOG (DEBUG) << BOLDBLUE << "FE" << +cFe->getFeId() << " BxId " << +cBxId << RESET; 
-            if ( std::find(cBxIds.begin(), cBxIds.end(), cBxId) == cBxIds.end() )
-                cBxIds.push_back(cBxId);
-
-            // correlation plot for BxIds 
-            for (auto& cOtherFe : pBoard->fModuleVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                if( cFe->getFeId() == cOtherFe->getFeId() )
-                    continue;
-            
-                TH2D* cBxCorrelation = static_cast<TH2D*> ( getHist ( cFe, Form("BxId_CIC%d", cOtherFe->getFeId())  ) );
-                cBxCorrelation->Fill(cBxId ,  cEvent->BxId( cOtherFe->getFeId() ) );
-            }
-                
-            for (auto& cChip : cFe->fReadoutChipVector) 
-            {
-                auto cHits = cEvent->GetHits( cFe->getFeId() , cChip->getChipId() );
-                auto cStubs = cEvent->StubVector( cFe->getFeId(), cChip->getChipId()) ;
-                
-                // quick cut on exactly one hit in each layer 
-                if( cHits.size() > 2 ) 
-                    continue;
+                TH1D* cBendHistogram = static_cast<TH1D*> ( getHist ( cFe, Form("StubBend") ) );
+                TH2D* cStubInformation = static_cast<TH2D*> ( getHist ( cFe, Form("StubInformation") ) );
+                TH2D* cStubHitCorrelation = static_cast<TH2D*> ( getHist ( cFe, Form("StubHitCorrelation") ) );
 
-                bool cBottomSensor=false;
-                bool cTopSensor=false;
-                for( auto cHit : cHits )
-                {
-                    if( cHit%2 == 0 )
-                        cBottomSensor = true;
+                auto cBxId = cEvent->BxId( cFe->getId() );
+                auto cStatus = static_cast<D19cCicEvent*>(cEvent)->Status ( cFe->getId() );
+                LOG (DEBUG) << BOLDBLUE << "FE" << +cFe->getId() << " BxId " << +cBxId << RESET; 
+                if ( std::find(cBxIds.begin(), cBxIds.end(), cBxId) == cBxIds.end() )
+                    cBxIds.push_back(cBxId);
 
-                    if( cHit%2 != 0 )
-                        cTopSensor = true;
-                }
-                if( !(cBottomSensor&&cTopSensor) )
-                    continue;
-
-                for( auto cHit : cHits )
+                // correlation plot for BxIds 
+                for(auto cOtherOpticalGroup : *pBoard)
                 {
-                    if( cHit%2 == 0 ) 
+                    if( cOpticalGroup->getId() == cOtherOpticalGroup->getId() )
+                        continue;
+
+                    for (auto& cOtherFe : *cOtherOpticalGroup)
                     {
-                        auto cStripHit = cChip->getChipId()*127 + std::floor(cHit/2.0) ;
-                        auto cModuleStrip = (cFe->getFeId()%2 == 0 ) ? cStripHit :  (8*127 - 1 -  cStripHit) ; 
-                        for( auto cStub : cStubs )
-                        {
-                            auto cStripSeed = cChip->getChipId()*127 + cStub.getPosition()*0.5 ;
-                            auto cSeedModuleStrip = (cFe->getFeId()%2 == 0 ) ? cStripSeed :  (8*127 - 1 -  cStripSeed) ; 
-                            cStubHitCorrelation->Fill( cModuleStrip, cSeedModuleStrip );
-                        }
-                        if( cStubs.size() == 0 )
-                            cStubHitCorrelation->Fill( cModuleStrip, -1 ); // fill underflow bin if no stubs are present in the event
+                        if( cFe->getId() == cOtherFe->getId() )
+                            continue;
+                
+                        TH2D* cBxCorrelation = static_cast<TH2D*> ( getHist ( cFe, Form("BxId_CIC%d", cOtherFe->getId())  ) );
+                        cBxCorrelation->Fill(cBxId ,  cEvent->BxId( cOtherFe->getId() ) );
                     }
                 }
-
-                cCandidatesHist->Fill(cTDC);
-                cNevents+=1;
-                for( auto cStub : cStubs )
+                    
+                for (auto cChip : *cFe) 
                 {
+                    auto cHits = cEvent->GetHits( cFe->getId() , cChip->getId() );
+                    auto cStubs = cEvent->StubVector( cFe->getId(), cChip->getId()) ;
+                    
+                    // quick cut on exactly one hit in each layer 
+                    if( cHits.size() > 2 ) 
+                        continue;
 
-                    //cHist->Fill(cStub.getBend());
-                    std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cStub.getPosition() , cStub.getBend() ); 
-                    bool cMatchFound=false;
-                    for( auto cExpectedHit : cExpectedHits )
+                    bool cBottomSensor=false;
+                    bool cTopSensor=false;
+                    for( auto cHit : cHits )
                     {
-                        auto cLookForMatch = std::find(cHits.begin(), cHits.end(), cExpectedHit);
-                        if( cLookForMatch != cHits.end() )
+                        if( cHit%2 == 0 )
+                            cBottomSensor = true;
+
+                        if( cHit%2 != 0 )
+                            cTopSensor = true;
+                    }
+                    if( !(cBottomSensor&&cTopSensor) )
+                        continue;
+
+                    for( auto cHit : cHits )
+                    {
+                        if( cHit%2 == 0 ) 
                         {
-                            cMatchFound = true;
+                            auto cStripHit = cChip->getId()*127 + std::floor(cHit/2.0) ;
+                            auto cModuleStrip = (cFe->getId()%2 == 0 ) ? cStripHit :  (8*127 - 1 -  cStripHit) ; 
+                            for( auto cStub : cStubs )
+                            {
+                                auto cStripSeed = cChip->getId()*127 + cStub.getPosition()*0.5 ;
+                                auto cSeedModuleStrip = (cFe->getId()%2 == 0 ) ? cStripSeed :  (8*127 - 1 -  cStripSeed) ; 
+                                cStubHitCorrelation->Fill( cModuleStrip, cSeedModuleStrip );
+                            }
+                            if( cStubs.size() == 0 )
+                                cStubHitCorrelation->Fill( cModuleStrip, -1 ); // fill underflow bin if no stubs are present in the event
                         }
                     }
-                    if( cMatchFound )
+
+                    cCandidatesHist->Fill(cTDC);
+                    cNevents+=1;
+                    for( auto cStub : cStubs )
                     {
-                        auto cBendValue = (cStub.getBend() & 0x7 );
-                        auto cBendSign = std::pow(-1, (cStub.getBend() & 0x8 ) >> 3 ) ;
-                        auto cBendDefLUT = (cBendSign < 0 ) ? cBendValue*cBendSign : cBendValue*cBendSign*0.5 ; 
-                        auto cStrip = cChip->getChipId()*127 + cStub.getPosition()*0.5 ;
-                        auto cModuleStrip = (cFe->getFeId()%2 == 0 ) ? cStrip :  (8*127 - 1 -  cStrip) ; 
-                        //LOG(DEBUG) << BOLDGREEN << "Stub seed " << +cStub.getPosition() << " - bend code " << std::bitset<4>(cStub.getBend()) << " -- bend value " << +cBendValue << " sign is " << +cBendSign << " --- " << +cBendDefLUT << RESET;
-                        //LOG(DEBUG) << BOLDGREEN << ">>>event " << +cEventCount << "\t..FE" << +cFe->getFeId() << "CBC" << +cChip->getChipId() << "\t.. MATCH FOUND! Stub seed " << +cStub.getPosition() << "-- TDC phase " << +cTDC << RESET;
-                        cBendHistogram->Fill( cBendDefLUT  );
-                        cStubInformation->Fill( cBendDefLUT, cModuleStrip );
-                        cNstubs +=1; 
-                        cMatchesHist->Fill(cTDC);
+
+                        //cHist->Fill(cStub.getBend());
+                        std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( static_cast<ReadoutChip*>(cChip), cStub.getPosition() , cStub.getBend() ); 
+                        bool cMatchFound=false;
+                        for( auto cExpectedHit : cExpectedHits )
+                        {
+                            auto cLookForMatch = std::find(cHits.begin(), cHits.end(), cExpectedHit);
+                            if( cLookForMatch != cHits.end() )
+                            {
+                                cMatchFound = true;
+                            }
+                        }
+                        if( cMatchFound )
+                        {
+                            auto cBendValue = (cStub.getBend() & 0x7 );
+                            auto cBendSign = std::pow(-1, (cStub.getBend() & 0x8 ) >> 3 ) ;
+                            auto cBendDefLUT = (cBendSign < 0 ) ? cBendValue*cBendSign : cBendValue*cBendSign*0.5 ; 
+                            auto cStrip = cChip->getId()*127 + cStub.getPosition()*0.5 ;
+                            auto cModuleStrip = (cFe->getId()%2 == 0 ) ? cStrip :  (8*127 - 1 -  cStrip) ; 
+                            //LOG(DEBUG) << BOLDGREEN << "Stub seed " << +cStub.getPosition() << " - bend code " << std::bitset<4>(cStub.getBend()) << " -- bend value " << +cBendValue << " sign is " << +cBendSign << " --- " << +cBendDefLUT << RESET;
+                            //LOG(DEBUG) << BOLDGREEN << ">>>event " << +cEventCount << "\t..FE" << +cFe->getId() << "CBC" << +cChip->getId() << "\t.. MATCH FOUND! Stub seed " << +cStub.getPosition() << "-- TDC phase " << +cTDC << RESET;
+                            cBendHistogram->Fill( cBendDefLUT  );
+                            cStubInformation->Fill( cBendDefLUT, cModuleStrip );
+                            cNstubs +=1; 
+                            cMatchesHist->Fill(cTDC);
+                        }
+                        cMatchingEfficiency->Fill( (float)cMatchFound , cTDC);
                     }
-                    cMatchingEfficiency->Fill( (float)cMatchFound , cTDC);
                 }
             }
         }
diff --git a/tools/StubSweep.cc b/tools/StubSweep.cc
index a43e7a8a2..10a093f12 100644
--- a/tools/StubSweep.cc
+++ b/tools/StubSweep.cc
@@ -40,61 +40,64 @@ void StubSweep::Initialize()
     uint32_t cCbcIdMax = 0;
     uint32_t cFeCount = 0;
 
-    for (auto cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-            cFeCount++;
-            fType = cFe->getFrontEndType();
-
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                uint32_t cCbcId = cCbc->getChipId();
-                cCbcCount++;
-
-                if ( cCbcId > cCbcIdMax ) cCbcIdMax = cCbcId;
-
-                cName = Form ("StubSweep_Fe%d_Cbc%d", cCbc->getFeId(), cCbc->getChipId() );
-                cObj = gROOT->FindObject (cName);
-
-                if (cObj) delete cObj;
-
-                // stub sweep
-                TProfile* cStubSweepHist = new TProfile ( cName, Form ( "Stub Sweep FE%d CBC%d ; Test Pulse Channel [1-254]; Stub Address", cFeId, cCbcId ), 254, -0.5, 254.5 );
-                cStubSweepHist->SetMarkerStyle ( 20 );
-                cStubSweepHist->SetStats (0);
-                cStubSweepHist->SetMarkerStyle (4);
-                cStubSweepHist->SetMarkerSize (0.5);
-                cStubSweepHist->SetLineColor (kBlue);
-                cStubSweepHist->SetMarkerColor (kBlue);
-                cStubSweepHist->GetYaxis()->SetTitleOffset (1.3);
-                cStubSweepHist->GetYaxis()->SetRangeUser (0, 255);
-                cStubSweepHist->GetXaxis()->SetRangeUser (0, 255);
-
-                bookHistogram ( cCbc, "StubAddresses", cStubSweepHist );
-
-                // bend information
-                cName = Form ("StubBends_Fe%d_Cbc%d", cCbc->getFeId(), cCbc->getChipId() );
-                cObj = gROOT->FindObject (cName);
-
-                if (cObj) delete cObj;
-
-                TProfile* cStubBendHist = new TProfile ( cName, Form ( "Bend Information FE%d CBC%d ; Test Pulse Channel [1-254]; Stub Bend", cFeId, cCbcId ), 254, -0.5, 254.5 );
-                cStubBendHist->SetMarkerStyle ( 20 );
-                cStubBendHist->SetStats (0);
-                cStubBendHist->SetMarkerStyle (4);
-                cStubBendHist->SetMarkerSize (0.5);
-                cStubBendHist->SetLineColor (kBlue);
-                cStubBendHist->SetMarkerColor (kBlue);
-                cStubBendHist->GetXaxis()->SetRangeUser (0, 255);
-                cStubBendHist->GetYaxis()->SetRangeUser (0.0, 15.0 );
-                cStubBendHist->GetYaxis()->SetTitleOffset (1.3);
-
-                bookHistogram ( cCbc, "StubBends", cStubBendHist );
-
-                // mask all channels on the CBC here
-                maskAllChannels ( cCbc );
+                uint32_t cFeId = cFe->getId();
+                cFeCount++;
+                fType = static_cast<OuterTrackerModule*>(cFe)->getFrontEndType();
+
+                for (auto cCbc : *cFe)
+                {
+                    uint32_t cCbcId = cCbc->getId();
+                    cCbcCount++;
+
+                    if ( cCbcId > cCbcIdMax ) cCbcIdMax = cCbcId;
+
+                    cName = Form ("StubSweep_Fe%d_Cbc%d", cFe->getId(), cCbc->getId() );
+                    cObj = gROOT->FindObject (cName);
+
+                    if (cObj) delete cObj;
+
+                    // stub sweep
+                    TProfile* cStubSweepHist = new TProfile ( cName, Form ( "Stub Sweep FE%d CBC%d ; Test Pulse Channel [1-254]; Stub Address", cFeId, cCbcId ), 254, -0.5, 254.5 );
+                    cStubSweepHist->SetMarkerStyle ( 20 );
+                    cStubSweepHist->SetStats (0);
+                    cStubSweepHist->SetMarkerStyle (4);
+                    cStubSweepHist->SetMarkerSize (0.5);
+                    cStubSweepHist->SetLineColor (kBlue);
+                    cStubSweepHist->SetMarkerColor (kBlue);
+                    cStubSweepHist->GetYaxis()->SetTitleOffset (1.3);
+                    cStubSweepHist->GetYaxis()->SetRangeUser (0, 255);
+                    cStubSweepHist->GetXaxis()->SetRangeUser (0, 255);
+
+                    bookHistogram ( cCbc, "StubAddresses", cStubSweepHist );
+
+                    // bend information
+                    cName = Form ("StubBends_Fe%d_Cbc%d", cFe->getId(), cCbc->getId() );
+                    cObj = gROOT->FindObject (cName);
+
+                    if (cObj) delete cObj;
+
+                    TProfile* cStubBendHist = new TProfile ( cName, Form ( "Bend Information FE%d CBC%d ; Test Pulse Channel [1-254]; Stub Bend", cFeId, cCbcId ), 254, -0.5, 254.5 );
+                    cStubBendHist->SetMarkerStyle ( 20 );
+                    cStubBendHist->SetStats (0);
+                    cStubBendHist->SetMarkerStyle (4);
+                    cStubBendHist->SetMarkerSize (0.5);
+                    cStubBendHist->SetLineColor (kBlue);
+                    cStubBendHist->SetMarkerColor (kBlue);
+                    cStubBendHist->GetXaxis()->SetRangeUser (0, 255);
+                    cStubBendHist->GetYaxis()->SetRangeUser (0.0, 15.0 );
+                    cStubBendHist->GetYaxis()->SetTitleOffset (1.3);
+
+                    bookHistogram ( cCbc, "StubBends", cStubBendHist );
+
+                    // mask all channels on the CBC here
+                    maskAllChannels ( static_cast<ReadoutChip*>(cCbc) );
+                }
             }
         }
 
@@ -119,133 +122,138 @@ void StubSweep::SweepStubs (uint32_t pNEvents )
 {
     std::stringstream outp;
 
-    for (auto cBoard : fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto cFe : cBoard->fModuleVector)
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        for(auto cOpticalGroup : *cBoard)
         {
-            uint32_t cFeId = cFe->getFeId();
-
-            for (auto cCbc : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                uint32_t cCbcId = cCbc->getChipId();
-
-                // before you do anything else make sure that the test pulse is enabled
-                configureTestPulse (cCbc, 1);
+                uint32_t cFeId = cFe->getId();
 
-                for ( uint8_t  cTestGroup = 0 ; cTestGroup < 8 ; cTestGroup++)
+                for (auto cCbc : *cFe)
                 {
-                    //re-run the phase finding at least at the end of each group
-                    // without this it looks like I loose sync with the FC7
-                    // [ get un-correlated stubs showing up in the CBC event]
-                    //fBeBoardInterface->FindPhase (cBoard);
+                    uint32_t cCbcId = cCbc->getId();
 
+                    // before you do anything else make sure that the test pulse is enabled
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
+                    configureTestPulse (theCbc, 1);
 
-                    // get channels in test group
-                    std::vector<uint8_t> cChannelVector;
-                    cChannelVector.clear();
-                    cChannelVector = findChannelsInTestGroup ( cTestGroup );
+                    for ( uint8_t  cTestGroup = 0 ; cTestGroup < 8 ; cTestGroup++)
+                    {
+                        //re-run the phase finding at least at the end of each group
+                        // without this it looks like I loose sync with the FC7
+                        // [ get un-correlated stubs showing up in the CBC event]
+                        //fBeBoardInterface->FindPhase (cBoard);
 
-                    // first, configure test pulse
-                    uint8_t cRegValue =  to_reg ( fDelay, cTestGroup );
-                    fReadoutChipInterface->WriteChipReg ( cCbc, "TestPulseDel&ChanGroup",  cRegValue  );
 
+                        // get channels in test group
+                        std::vector<uint8_t> cChannelVector;
+                        cChannelVector.clear();
+                        cChannelVector = findChannelsInTestGroup ( cTestGroup );
 
-                    // now un-mask channel in pairs
-                    bool isEven = ( (cChannelVector.size() % 2) == 0 ) ;
-                    unsigned int cNumberOfPairs = ( (isEven) ? 0 : 1) + cChannelVector.size() / 2;
-                    LOG (DEBUG) << "Test Group : " << +cTestGroup  ;
+                        // first, configure test pulse
+                        uint8_t cRegValue =  to_reg ( fDelay, cTestGroup );
+                        fReadoutChipInterface->WriteChipReg ( theCbc, "TestPulseDel&ChanGroup",  cRegValue  );
 
-                    for ( unsigned int i = 0 ; i < cNumberOfPairs ; i++ )
-                    {
-                        std::vector<uint8_t> cChannelPair;
-                        cChannelPair.clear();
-                        cChannelPair.push_back ( cChannelVector[2 * i]   );
 
-                        if ( ! (!isEven && i == cNumberOfPairs - 1) ) cChannelPair.push_back ( cChannelVector[2 * i + 1] );
+                        // now un-mask channel in pairs
+                        bool isEven = ( (cChannelVector.size() % 2) == 0 ) ;
+                        unsigned int cNumberOfPairs = ( (isEven) ? 0 : 1) + cChannelVector.size() / 2;
+                        LOG (DEBUG) << "Test Group : " << +cTestGroup  ;
 
-                        // if( cChannelPair.size() == 2 ) LOG (DEBUG) << "\t\t (" << +i << ") " << +cChannelPair[0] << " and " << +cChannelPair[1] ;
-                        // else LOG (DEBUG) << "\t\t (" << +i << ") " << +cChannelPair[0] ;
+                        for ( unsigned int i = 0 ; i < cNumberOfPairs ; i++ )
+                        {
+                            std::vector<uint8_t> cChannelPair;
+                            cChannelPair.clear();
+                            cChannelPair.push_back ( cChannelVector[2 * i]   );
 
-                        //only un-mask channels in this test pair
-                        uint8_t cMaskRegValue = 0 ;
+                            if ( ! (!isEven && i == cNumberOfPairs - 1) ) cChannelPair.push_back ( cChannelVector[2 * i + 1] );
 
-                        for ( unsigned int j = 0 ; j < cChannelVector.size() ; j++ )
-                        {
-                            uint8_t cBitShift = (cChannelVector[j] - 1) % 8;
+                            // if( cChannelPair.size() == 2 ) LOG (DEBUG) << "\t\t (" << +i << ") " << +cChannelPair[0] << " and " << +cChannelPair[1] ;
+                            // else LOG (DEBUG) << "\t\t (" << +i << ") " << +cChannelPair[0] ;
 
-                            if ( std::find (cChannelPair.begin(), cChannelPair.end(), cChannelVector[j] ) != cChannelPair.end()  )
-                                cMaskRegValue |=  (1 << cBitShift);
-                        }
+                            //only un-mask channels in this test pair
+                            uint8_t cMaskRegValue = 0 ;
 
-                        // write the CBC mask registers
-                        uint8_t cRegisterIndex = (cChannelPair[0] - 1) / 8;
-                        std::string cRegName;
+                            for ( unsigned int j = 0 ; j < cChannelVector.size() ; j++ )
+                            {
+                                uint8_t cBitShift = (cChannelVector[j] - 1) % 8;
 
-                        //LOG (DEBUG) << BLUE << "Un-masking channels " <<  +cChannelPair[0] << " and " << +cChannelPair[1] << RESET ;
-                        if (fType == FrontEndType::CBC3)
+                                if ( std::find (cChannelPair.begin(), cChannelPair.end(), cChannelVector[j] ) != cChannelPair.end()  )
+                                    cMaskRegValue |=  (1 << cBitShift);
+                            }
 
-                            cRegName = fChannelMaskMapCBC3[cRegisterIndex];
+                            // write the CBC mask registers
+                            uint8_t cRegisterIndex = (cChannelPair[0] - 1) / 8;
+                            std::string cRegName;
 
-                        // get value that is already in the register
-                        cRegValue = cCbc->getReg (cRegName );
-                        // write new mask to cbc register
-                        fReadoutChipInterface->WriteChipReg ( cCbc, cRegName,  cMaskRegValue  );
-                        //LOG (DEBUG) << "\t" << cRegName << MAGENTA << " wrote - " << std::bitset<8> (cMaskRegValue) << RESET  ;
+                            //LOG (DEBUG) << BLUE << "Un-masking channels " <<  +cChannelPair[0] << " and " << +cChannelPair[1] << RESET ;
+                            if (fType == FrontEndType::CBC3)
 
+                                cRegName = fChannelMaskMapCBC3[cRegisterIndex];
 
-                        // Read an event from the cbc
-                        // I'm going to keep reading until i have the same number of hits as expected ...
-                        // this is to make sure that I'm not looking at noise on the chip
-                        // do this a maximum of fReadBackAttempts times
-                        uint32_t cNhits = 0 ;
-                        int cCounter = 0 ;
-                        uint8_t cStubPosition ;
-                        std::vector<Event*> cEvents;
-                        std::stringstream outp;
+                            // get value that is already in the register
+                            cRegValue = theCbc->getReg (cRegName );
+                            // write new mask to cbc register
+                            fReadoutChipInterface->WriteChipReg ( theCbc, cRegName,  cMaskRegValue  );
+                            //LOG (DEBUG) << "\t" << cRegName << MAGENTA << " wrote - " << std::bitset<8> (cMaskRegValue) << RESET  ;
 
-                        do
-                        {
-                            cEvents.clear();
-                            ReadNEvents (cBoard, pNEvents);
-                            cEvents = GetEvents ( cBoard );
-                            unsigned int j = 0 ;
+
+                            // Read an event from the cbc
+                            // I'm going to keep reading until i have the same number of hits as expected ...
+                            // this is to make sure that I'm not looking at noise on the chip
+                            // do this a maximum of fReadBackAttempts times
+                            uint32_t cNhits = 0 ;
+                            int cCounter = 0 ;
+                            uint8_t cStubPosition ;
+                            std::vector<Event*> cEvents;
+                            std::stringstream outp;
 
                             do
                             {
-                                outp.str ("");
-                                outp << *cEvents[j];
-
-                                cNhits = cEvents[j]->GetNHits ( cFeId, cCbcId );
-                                std::vector<Stub> cStubs = cEvents[j]->StubVector (cFeId, cCbcId );
-                                cStubPosition = cStubs[0].getPosition();
-                                j++;
+                                cEvents.clear();
+                                ReadNEvents (theBoard, pNEvents);
+                                cEvents = GetEvents ( theBoard );
+                                unsigned int j = 0 ;
+
+                                do
+                                {
+                                    outp.str ("");
+                                    outp << *cEvents[j];
+
+                                    cNhits = cEvents[j]->GetNHits ( cFeId, cCbcId );
+                                    std::vector<Stub> cStubs = cEvents[j]->StubVector (cFeId, cCbcId );
+                                    cStubPosition = cStubs[0].getPosition();
+                                    j++;
+                                }
+                                while ( cNhits != cChannelPair.size() && j < cEvents.size() );
+
+                                cCounter++;
                             }
-                            while ( cNhits != cChannelPair.size() && j < cEvents.size() );
+                            while ( ( cStubPosition - cChannelPair[cChannelPair.size() - 1]  != 0) && cCounter < fReadBackAttempts  );
 
-                            cCounter++;
-                        }
-                        while ( ( cStubPosition - cChannelPair[cChannelPair.size() - 1]  != 0) && cCounter < fReadBackAttempts  );
-
-                        //while( cNhits != cChannelPair.size() && cCounter < fReadBackAttempts );
+                            //while( cNhits != cChannelPair.size() && cCounter < fReadBackAttempts );
 
-                        //LOG (DEBUG) << outp.str();
-                        //LOG (DEBUG) << "Channels : " << +cChannelPair[0] << " and " << +cChannelPair[1] << " -  got stub :  " << +cStubPosition << " with bend : " << +cStubBend << RESET ;
-                        if ( cStubPosition - cChannelPair[cChannelPair.size() - 1]  != 0  )
-                            LOG (INFO) << RED << "WARNING! Mismatch between injected test pulse and stub in channels " << +cChannelPair[0] << " and " << +cChannelPair[1] << " - got " << +cStubPosition << "." << RESET ;
+                            //LOG (DEBUG) << outp.str();
+                            //LOG (DEBUG) << "Channels : " << +cChannelPair[0] << " and " << +cChannelPair[1] << " -  got stub :  " << +cStubPosition << " with bend : " << +cStubBend << RESET ;
+                            if ( cStubPosition - cChannelPair[cChannelPair.size() - 1]  != 0  )
+                                LOG (INFO) << RED << "WARNING! Mismatch between injected test pulse and stub in channels " << +cChannelPair[0] << " and " << +cChannelPair[1] << " - got " << +cStubPosition << "." << RESET ;
 
-                        // //update histograms
-                        fillStubSweepHist ( cCbc,  cChannelPair, cStubPosition );
+                            // //update histograms
+                            fillStubSweepHist ( theCbc,  cChannelPair, cStubPosition );
 
-                        // Re-configure the CBC mask register back to its original state
-                        fReadoutChipInterface->WriteChipReg ( cCbc, cRegName,  cRegValue  );
+                            // Re-configure the CBC mask register back to its original state
+                            fReadoutChipInterface->WriteChipReg ( theCbc, cRegName,  cRegValue  );
 
-                        //if( i%4 == 0 )
-                        updateHists ( "StubAddresses" );
+                            //if( i%4 == 0 )
+                            updateHists ( "StubAddresses" );
+                        }
                     }
-                }
 
-                // and before you leave make sure that the test pulse is disabled
-                configureTestPulse (cCbc, 0);
+                    // and before you leave make sure that the test pulse is disabled
+                    configureTestPulse (theCbc, 0);
+                }
             }
         }
     }
diff --git a/tools/StubTool.cc b/tools/StubTool.cc
index b0f2e5c6d..1098312ca 100644
--- a/tools/StubTool.cc
+++ b/tools/StubTool.cc
@@ -13,8 +13,8 @@ void StubTool::Initialize()
 
     //we want to keep things simple, so lets get a pointer to a CBC and a pointer to a BeBoard
     //this will facilitate the code as we save a lot of looping
-    fBoard = this->fBoardVector.at (0);
-    fCbc = fBoard->fModuleVector.at (0)->fReadoutChipVector.at (0);
+    fBoard = static_cast<BeBoard*>(fDetectorContainer->at(0));
+    fCbc = static_cast<ReadoutChip*>(fBoard->at(0)->at(0)->at(0));
 
     //we also need a TCanvas
     //std::string cDirectory = ( cmd.foundOption ( "output" ) ) ? cmd.optionValue ( "output" ) : "Results/pulseshape";
@@ -54,7 +54,7 @@ void StubTool::Initialize()
     for (uint8_t iCh = 0; iCh < nChan; iCh++)
     {
         this->fReadoutChipInterface->WriteChipReg (fCbc, Form ("Channel%03d", iCh + 1), (fHoleMode) ? 0xaa : 0x50 );
-        fChannelVector.push_back(new Channel (fBoard->getBeId(), fCbc->getFeId(), fCbc->getChipId(), iCh));
+        fChannelVector.push_back(new Channel (fBoard->getId(), fBoard->at(0)->getId(), fCbc->getFeId(), fCbc->getId(), iCh));
         fChannelVector.back()->initializeHist (0, "VCth");
     } 
     
@@ -67,187 +67,194 @@ void StubTool::Initialize()
 void StubTool::scanStubs()
 {
    std::stringstream outp;
-   for (auto cBoard : fBoardVector)
+   for (auto cBoard : *fDetectorContainer)
    {
-      for (auto cFe : cBoard->fModuleVector)
+      BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+      for(auto cOpticalGroup : *cBoard)
       {
-         uint32_t cFeId = cFe->getFeId();
-         std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
-         const uint8_t nCBC = cCbcVector.size();
-         for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
-         {
-            configureTestPulse (cCbcVector.at(iCBC), 1);
-         }
-         //Uncoment for Bend uncoding 2
-         //hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nChan,0,nChan,16,0,8);
-         //hSTUB_SCAN_bend = new TH2F(stubscanname_bend.c_str(),stubscanname_bend.c_str(),nChan,0,nChan,16,-6.75,8.25);
-         //Comment for Bend uncoding 4
-         double actualbend = 3;
-         double binbend4[]= { -7.25, -6.25, -5.25, -4.25, -3.25, -2.25, -1.25, -0.25, 0.25, 1.25, 2.25, 3.25, 4.25, 5.25, 6.25, 7.25, 8.25};
-         std::string stubscanname_tg   = "StubsSCAN_TG_CBC";
-         std::string stubscanname_bend = "StubsSCAN_BEND_CBC";
-         hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nCBC*127,0,nCBC*127,16,0,8);
-         hSTUB_SCAN_bend = new TH2F(stubscanname_bend.c_str(),stubscanname_bend.c_str(),nCBC*127,0,nCBC*127,16,binbend4);
-         std::vector<std::string> vec_stubscanname_bend_offset(nCBC,"");
-         for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
-         {
-            vec_stubscanname_bend_offset[iCBC] = "StubsSCAN_BEND_OFF_CBC"+std::to_string(iCBC);
-            hSTUB_SCAN_bend_off[iCBC] = new TH2F(vec_stubscanname_bend_offset[iCBC].c_str(),vec_stubscanname_bend_offset[iCBC].c_str(),31,-8,8,16,binbend4);
-            //hSTUB_SCAN_bend_off[iCBC] = new TH2F(vec_stubscanname_bend_offset[iCBC].c_str(),vec_stubscanname_bend_offset[iCBC].c_str(),31,-7.5,7.5,16,-6.75,8.25);
-         }
-         for (uint8_t tg = 0; tg < 8; tg++)
-         {  
-            //LOG(DEBUG) << GREEN << "Test Group " << +tg << RESET;
+        for (auto cFe : *cOpticalGroup)
+        {
+          uint32_t cFeId = cFe->getId();
+          ModuleContainer& cCbcVector = *cFe;
+          const uint8_t nCBC = cCbcVector.size();
+          for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
+          {
+              configureTestPulse (static_cast<ReadoutChip*>(static_cast<ReadoutChip*>(cCbcVector.at(iCBC))), 1);
+          }
+          //Uncoment for Bend uncoding 2
+          //hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nChan,0,nChan,16,0,8);
+          //hSTUB_SCAN_bend = new TH2F(stubscanname_bend.c_str(),stubscanname_bend.c_str(),nChan,0,nChan,16,-6.75,8.25);
+          //Comment for Bend uncoding 4
+          double actualbend = 3;
+          double binbend4[]= { -7.25, -6.25, -5.25, -4.25, -3.25, -2.25, -1.25, -0.25, 0.25, 1.25, 2.25, 3.25, 4.25, 5.25, 6.25, 7.25, 8.25};
+          std::string stubscanname_tg   = "StubsSCAN_TG_CBC";
+          std::string stubscanname_bend = "StubsSCAN_BEND_CBC";
+          hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nCBC*127,0,nCBC*127,16,0,8);
+          hSTUB_SCAN_bend = new TH2F(stubscanname_bend.c_str(),stubscanname_bend.c_str(),nCBC*127,0,nCBC*127,16,binbend4);
+          std::vector<std::string> vec_stubscanname_bend_offset(nCBC,"");
+          for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
+          {
+              vec_stubscanname_bend_offset[iCBC] = "StubsSCAN_BEND_OFF_CBC"+std::to_string(iCBC);
+              hSTUB_SCAN_bend_off[iCBC] = new TH2F(vec_stubscanname_bend_offset[iCBC].c_str(),vec_stubscanname_bend_offset[iCBC].c_str(),31,-8,8,16,binbend4);
+              //hSTUB_SCAN_bend_off[iCBC] = new TH2F(vec_stubscanname_bend_offset[iCBC].c_str(),vec_stubscanname_bend_offset[iCBC].c_str(),31,-7.5,7.5,16,-6.75,8.25);
+          }
+          for (uint8_t tg = 0; tg < 8; tg++)
+          {  
+              //LOG(DEBUG) << GREEN << "Test Group " << +tg << RESET;
 
-            setInitialOffsets();
-            setSystemTestPulse (40, tg, true, 0 ); // (testPulseAmplitude, TestGroup, true, holemode )
+              setInitialOffsets();
+              setSystemTestPulse (40, tg, true, 0 ); // (testPulseAmplitude, TestGroup, true, holemode )
 
-            // get channels in test group
-            std::vector<uint8_t> cChannelVector;
-            cChannelVector.clear();
-            cChannelVector = findChannelsInTestGroup ( tg );
-         
-            // first, configure test pulse
-	    setDelayAndTestGroup(5030, tg);
-
-            //set the threshold, correlation window (pt), bend decoding in all chips!
-            uint16_t cVcth = 500;
-            uint8_t cVcth1 = cVcth & 0x00FF;
-            uint8_t cVcth2 = (cVcth & 0x0300) >> 8;
-            unsigned int Pipe_StubSel_Ptwidth = 14;
-            unsigned int BendReg[] = {153, 170, 187, 204, 221, 238, 255, 16, 33, 50, 67, 84, 101, 118, 135};
-            //unsigned int BendReg[] = {153, 170, 187, 204, 221, 238, 255, 16, 33, 50, 67, 84, 101, 118, 120};
-            for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
-            {
-              fReadoutChipInterface->WriteChipReg (cCbcVector.at(iCBC), "VCth1", cVcth1);
-              fReadoutChipInterface->WriteChipReg (cCbcVector.at(iCBC), "VCth2", cVcth2);
-              fReadoutChipInterface->WriteChipReg (cCbcVector.at(iCBC), "Pipe&StubInpSel&Ptwidth", Pipe_StubSel_Ptwidth );
-              for (int ireg = 0; ireg < 15; ireg ++)
+              // get channels in test group
+              std::vector<uint8_t> cChannelVector;
+              cChannelVector.clear();
+              cChannelVector = findChannelsInTestGroup ( tg );
+          
+              // first, configure test pulse
+        setDelayAndTestGroup(5030, tg);
+
+              //set the threshold, correlation window (pt), bend decoding in all chips!
+              uint16_t cVcth = 500;
+              uint8_t cVcth1 = cVcth & 0x00FF;
+              uint8_t cVcth2 = (cVcth & 0x0300) >> 8;
+              unsigned int Pipe_StubSel_Ptwidth = 14;
+              unsigned int BendReg[] = {153, 170, 187, 204, 221, 238, 255, 16, 33, 50, 67, 84, 101, 118, 135};
+              //unsigned int BendReg[] = {153, 170, 187, 204, 221, 238, 255, 16, 33, 50, 67, 84, 101, 118, 120};
+              for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
               {
-                fReadoutChipInterface->WriteChipReg (cCbcVector.at(iCBC), "Bend"+std::to_string(ireg),  BendReg[ireg] );
+                fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), "VCth1", cVcth1);
+                fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), "VCth2", cVcth2);
+                fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), "Pipe&StubInpSel&Ptwidth", Pipe_StubSel_Ptwidth );
+                for (int ireg = 0; ireg < 15; ireg ++)
+                {
+                  fReadoutChipInterface->WriteChipReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), "Bend"+std::to_string(ireg),  BendReg[ireg] );
+                }
               }
-            }
 
-            uint8_t cRegValue;
-            std::string cRegName;
+              uint8_t cRegValue;
+              std::string cRegName;
 
-            for (double offset = (actualbend); offset >= -(actualbend); offset -= 0.5){
-               //LOG(DEBUG) << GREEN << " !!!  Offset: " << offset << RESET;
-               for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
-               {
-                  setCorrelationWinodwOffsets(cCbcVector.at(iCBC), offset, offset, offset, offset);
-               }
-                   
-               //Unmasking desired channels
-               for (unsigned int iChan = 0; iChan < nChan; iChan++ ) 
-               {
-                  if (iChan % 48 != 0) continue;
-                  //LOG(DEBUG) << "Looking at Channel " << iChan;
-                  for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
-                  {
-                     for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
-                     {
-                        cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-                        cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
-                        cRegName =  fChannelMaskMapCBC3[i];
-                        fReadoutChipInterface->WriteChipReg ( cCbcVector.at(iCBC), cRegName,  cRegValue );
-                        //LOG (INFO) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
-                     }
-                     //for ( unsigned int smg = 0; smg < 6; smg+=2) //only using masks
-                     for ( unsigned int smg = 0; smg < 3; smg++)
-                     {  
-                        //if (tg > 3 && smg == 0) smg++; //only using masks
-                        //if ( (mg+smg) >= 32) continue;   
-                        for (int i = 1; i<=2; i++)
-                        {
-                           if ( (iChan+(smg*16)+(tg*2)+i) > nChan ) continue;
-                           maskChannel(cCbcVector.at(iCBC), (iChan+(smg*16)+(tg*2)+i), false);
-                           LOG (DEBUG) << "Unmasking : " << +(iChan+(smg*16)+(tg*2)+i) << " = " << +iChan << " + (" << +smg << ")*16 +" << +((tg*2)+i);
-                        }
-                     }
-
-                     // CHECKING CBC REGISTERS
-                     //CheckCbcReg(cCbcVector.at(iCBC));
-
-                     //now read Events
-                     ReadNEvents (fBoard, fNevents);
-                     const std::vector<Event*> cEvents = GetEvents (fBoard);
-                     int countEvent = 0;
-                     for (auto cEvent : cEvents)
-                     {
-                        ++countEvent;     
-                        LOG (DEBUG) << "Event : " << countEvent << " !";
-                        std::vector<uint32_t> cHits = cEvent->GetHits(cFeId, iCBC);
-                        unsigned nHits = 0;
-                        if (cHits.size() == nChan) LOG(INFO) << RED << "All channels firing in CBC"<< +iCBC <<"!!" << RESET;
-                        else
-                        {
-                           //LOG(DEBUG) << BLUE << "List of hits: " << RESET;
-                           for (uint32_t cHit : cHits )
-                           {   
-                              nHits ++;
-                              double HIT = cHit + 1;
-                              double STRIP = (HIT / 2);                             
-                              LOG (DEBUG) << BLUE << std::dec << cHit << " : " << HIT << " , " << STRIP << RESET;
-                              if (offset == 0 && (int)HIT % 2 != 0) hSTUB_SCAN_tg->Fill(STRIP+(iCBC*127), tg+0.5 , 0.5);
-                           }
-                        }
-                        if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
-                        {
-                           uint8_t stubCounter = 1;
-                           for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
-                           {
-                              double stub_position = cStub.getPosition();
-                              double stub_bend     = Decoding_stub4(cStub.getBend());
-                              double stub_strip    = cStub.getCenter();
-                                 
-                              double expect        = (iChan+tg*2+((stubCounter-1)*16));
-                              double expect_strip  = (((expect+2)/2)-1);
-                              LOG (DEBUG) << "CBC" << +iCBC << " , Stub: " << +stubCounter << " | Position: " << stub_position << " , EXPECT POS : " << +(expect+2) << " | Bend: " << std::bitset<4> (cStub.getBend()) << " -> " << stub_bend << " , EXPECT BEND: " << -(offset) << " || Strip: " << stub_strip << " , EXPECTED STRIP : " << +(expect_strip) << " , Filling STRIP: " << +(stub_strip+(iCBC*127));
-
-                              stubCounter++;
-                              hSTUB_SCAN_bend_off[iCBC]->Fill(offset, stub_bend);   
-                              hSTUB_SCAN_bend->Fill(stub_strip+(iCBC*127), stub_bend);
-                              fCanvas6->cd();
-                              hSTUB_SCAN_bend->Draw("COLZ");
-                              hSTUB_SCAN_bend->SetStats(0);
-                              fCanvas6->Update();
-                                 
-                              if (offset != 0) continue;      
-                              hSTUB_SCAN_tg->Fill(stub_strip+(iCBC*127), tg);
-                              fCanvas5->cd();
-                              hSTUB_SCAN_tg->Draw("COLZ");
-                              hSTUB_SCAN_tg->SetStats(0);
-                              fCanvas5->Update();
-                           }
-                        }
-                        else LOG (DEBUG) << RED << "!!!!! NO STUB in CBC"<< +iCBC << " | Event : " << +countEvent << " !!!!!!!!!" << RESET;
-                     }
-                  }
-               }
-            } //correlation window offset
-         }
-         
-         hSTUB_SCAN_tg->Write();
-         hSTUB_SCAN_bend->Write();
-         for (uint8_t iCBC = 0; iCBC < nCBC; iCBC++)
-         {
-            hSTUB_SCAN_bend_off[iCBC]->Write();
-         }
-         for (uint8_t iCBC = 0; iCBC < nCBC; iCBC++){configureTestPulse (cCbcVector.at(iCBC), 0);} 
+              for (double offset = (actualbend); offset >= -(actualbend); offset -= 0.5){
+                //LOG(DEBUG) << GREEN << " !!!  Offset: " << offset << RESET;
+                for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
+                {
+                    setCorrelationWinodwOffsets(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), offset, offset, offset, offset);
+                }
+                    
+                //Unmasking desired channels
+                for (unsigned int iChan = 0; iChan < nChan; iChan++ ) 
+                {
+                    if (iChan % 48 != 0) continue;
+                    //LOG(DEBUG) << "Looking at Channel " << iChan;
+                    for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
+                    {
+                      for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
+                      {
+                          static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+                          cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
+                          cRegName =  fChannelMaskMapCBC3[i];
+                          fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegName,  cRegValue );
+                          //LOG (INFO) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
+                      }
+                      //for ( unsigned int smg = 0; smg < 6; smg+=2) //only using masks
+                      for ( unsigned int smg = 0; smg < 3; smg++)
+                      {  
+                          //if (tg > 3 && smg == 0) smg++; //only using masks
+                          //if ( (mg+smg) >= 32) continue;   
+                          for (int i = 1; i<=2; i++)
+                          {
+                            if ( (iChan+(smg*16)+(tg*2)+i) > nChan ) continue;
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), (iChan+(smg*16)+(tg*2)+i), false);
+                            LOG (DEBUG) << "Unmasking : " << +(iChan+(smg*16)+(tg*2)+i) << " = " << +iChan << " + (" << +smg << ")*16 +" << +((tg*2)+i);
+                          }
+                      }
+
+                      // CHECKING CBC REGISTERS
+                      //CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)));
+
+                      //now read Events
+                      ReadNEvents (theBoard, fNevents);
+                      const std::vector<Event*> cEvents = GetEvents (theBoard);
+                      int countEvent = 0;
+                      for (auto cEvent : cEvents)
+                      {
+                          ++countEvent;     
+                          LOG (DEBUG) << "Event : " << countEvent << " !";
+                          std::vector<uint32_t> cHits = cEvent->GetHits(cFeId, iCBC);
+                          unsigned nHits = 0;
+                          if (cHits.size() == nChan) LOG(INFO) << RED << "All channels firing in CBC"<< +iCBC <<"!!" << RESET;
+                          else
+                          {
+                            //LOG(DEBUG) << BLUE << "List of hits: " << RESET;
+                            for (uint32_t cHit : cHits )
+                            {   
+                                nHits ++;
+                                double HIT = cHit + 1;
+                                double STRIP = (HIT / 2);                             
+                                LOG (DEBUG) << BLUE << std::dec << cHit << " : " << HIT << " , " << STRIP << RESET;
+                                if (offset == 0 && (int)HIT % 2 != 0) hSTUB_SCAN_tg->Fill(STRIP+(iCBC*127), tg+0.5 , 0.5);
+                            }
+                          }
+                          if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
+                          {
+                            uint8_t stubCounter = 1;
+                            for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
+                            {
+                                double stub_position = cStub.getPosition();
+                                double stub_bend     = Decoding_stub4(cStub.getBend());
+                                double stub_strip    = cStub.getCenter();
+                                  
+                                double expect        = (iChan+tg*2+((stubCounter-1)*16));
+                                double expect_strip  = (((expect+2)/2)-1);
+                                LOG (DEBUG) << "CBC" << +iCBC << " , Stub: " << +stubCounter << " | Position: " << stub_position << " , EXPECT POS : " << +(expect+2) << " | Bend: " << std::bitset<4> (cStub.getBend()) << " -> " << stub_bend << " , EXPECT BEND: " << -(offset) << " || Strip: " << stub_strip << " , EXPECTED STRIP : " << +(expect_strip) << " , Filling STRIP: " << +(stub_strip+(iCBC*127));
+
+                                stubCounter++;
+                                hSTUB_SCAN_bend_off[iCBC]->Fill(offset, stub_bend);   
+                                hSTUB_SCAN_bend->Fill(stub_strip+(iCBC*127), stub_bend);
+                                fCanvas6->cd();
+                                hSTUB_SCAN_bend->Draw("COLZ");
+                                hSTUB_SCAN_bend->SetStats(0);
+                                fCanvas6->Update();
+                                  
+                                if (offset != 0) continue;      
+                                hSTUB_SCAN_tg->Fill(stub_strip+(iCBC*127), tg);
+                                fCanvas5->cd();
+                                hSTUB_SCAN_tg->Draw("COLZ");
+                                hSTUB_SCAN_tg->SetStats(0);
+                                fCanvas5->Update();
+                            }
+                          }
+                          else LOG (DEBUG) << RED << "!!!!! NO STUB in CBC"<< +iCBC << " | Event : " << +countEvent << " !!!!!!!!!" << RESET;
+                      }
+                    }
+                }
+              } //correlation window offset
+          }
+          
+          hSTUB_SCAN_tg->Write();
+          hSTUB_SCAN_bend->Write();
+          for (uint8_t iCBC = 0; iCBC < nCBC; iCBC++)
+          {
+              hSTUB_SCAN_bend_off[iCBC]->Write();
+          }
+          for (uint8_t iCBC = 0; iCBC < nCBC; iCBC++){configureTestPulse (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 0);} 
+        }
       }
-   }
+    }
 }
 
 void StubTool::scanStubs_wNoise()
 {
   std::stringstream outp;
-  for (auto cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    for (auto cFe : cBoard->fModuleVector)
+    BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    for(auto cOpticalGroup : *cBoard)
+    {
+      for (auto cFe : *cOpticalGroup)
       {
-        uint32_t cFeId = cFe->getFeId();
-        std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
+        uint32_t cFeId = cFe->getId();
+        ModuleContainer& cCbcVector = *cFe;
         const uint8_t nCBC = cCbcVector.size();
         //Uncoment for Bend uncoding 2
         //hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nChan,0,nChan,16,0,8);
@@ -292,7 +299,7 @@ void StubTool::scanStubs_wNoise()
             {
               cRegVec.push_back ( std::make_pair ( "Bend"+std::to_string(ireg),  BendReg[ireg] ) );
             }
-            fReadoutChipInterface->WriteChipMultReg (cCbcVector.at(iCBC), cRegVec );
+            fReadoutChipInterface->WriteChipMultReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
             cRegVec.clear();
           }
 
@@ -313,13 +320,13 @@ void StubTool::scanStubs_wNoise()
                     cRegVec.clear();
                     for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
                     {
-                      cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-                      cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
+                      static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+                      cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
                       cRegName =  fChannelMaskMapCBC3[i];
                       cRegVec.push_back ( std::make_pair ( cRegName ,cRegValue ) );  
                       //LOG (DEBUG) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
                     }
-                    fReadoutChipInterface->WriteChipMultReg ( cCbcVector.at(iCBC), cRegVec );
+                    fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
                     cRegVec.clear();
                   }
   
@@ -338,12 +345,12 @@ void StubTool::scanStubs_wNoise()
                         int corrChan = nChan + (seedChan[smg] + bend + 1 );
                         if ((int)bend % 2 != 0) corrChan = nChan + (seedChan[smg] + bend); 
                         if (corrChan % 2 != 0 || corrChan <= 0) continue;
-                        maskChannel(cCbcVector.at(iCBC-1), corrChan, false);
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan, false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
                         LOG (DEBUG) << "Cond 1: Corr Chan (CBC"<< +(iCBC-1) << "): " << +corrChan << " (" << +(seedChan[smg] + bend - 1) << ")";
                         if ((int)bend % 2 != 0 && corrChan+2 > 0 ) 
                         {
-                          maskChannel(cCbcVector.at(iCBC-1), corrChan+2, false); 
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan+2, false); 
                           LOG (DEBUG) << "              , Corr Chan : " << (corrChan + 2);
                         }
                       }
@@ -354,18 +361,18 @@ void StubTool::scanStubs_wNoise()
                         int corrChan = (seedChan[smg] + bend + 1 ) - nChan;
                         if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend) - nChan;
                         if (corrChan % 2 != 0 ) continue;
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                        if (corrChan > 0 ) maskChannel(cCbcVector.at(iCBC+1), corrChan, false);
-                        else if (corrChan == 0 ) {corrChan = nChan; maskChannel(cCbcVector.at(iCBC), corrChan, false);}
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                        if (corrChan > 0 ) maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan, false);
+                        else if (corrChan == 0 ) {corrChan = nChan; maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false);}
                         LOG (DEBUG) << "Cond 2: Corr Chan (" << +(iCBC) <<"/"<< +(iCBC+1) << "): " << corrChan<< " (" << seedChan[smg] + bend + 1 << ")";
                         if (corrChan == nChan)
                         {              
-                          corrChan = 2; maskChannel(cCbcVector.at(iCBC+1), corrChan, false);
+                          corrChan = 2; maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan, false);
                           LOG (DEBUG) << "                 , Corr Chan " << +(iCBC+1) << ": " << (corrChan);
                         }
                         else if ((int)bend % 2 != 0 && corrChan+2 > 0)
                         {
-                          maskChannel(cCbcVector.at(iCBC+1), corrChan+2, false);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan+2, false);
                           LOG (DEBUG) << "                 , Corr Chan " << +(iCBC+1) << ": " << (corrChan + 2);
                         }
                       } 
@@ -375,40 +382,40 @@ void StubTool::scanStubs_wNoise()
                         int corrChan = (seedChan[smg] + bend + 1);
                         if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend);
                         if (corrChan % 2 != 0 || corrChan <= 0) continue;
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                        maskChannel(cCbcVector.at(iCBC), corrChan, false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false);
                         LOG (DEBUG) << "Cond 3: Corr Chan (CBC"<< +(iCBC) << "): " <<  corrChan << " (" << seedChan[smg] + bend + 1 << ")";
                         if ((int)bend % 2 != 0 && corrChan+2 >0 )
                         {
-                          maskChannel(cCbcVector.at(iCBC), corrChan+2, false); 
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan+2, false); 
                           LOG (DEBUG) << "         , Corr Chan : " << (corrChan + 2);
                         }
                       }
                       //MASKING BAD CHANNELS FOR CBC3.0
                       /*if (iCBC > 0)
                       {
-                        maskChannel(cCbcVector.at(iCBC-1), 107, true);
-                        maskChannel(cCbcVector.at(iCBC-1), 225, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 107, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 225, true);
                       }
-                      maskChannel(cCbcVector.at(iCBC), 107, true);
-                      maskChannel(cCbcVector.at(iCBC), 225, true);
+                      maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 107, true);
+                      maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 225, true);
                       */
                     }
                   }
   
                   // CHECKING CBC REGISTERS
-                  //for (uint8_t iCBC = 0; i< nCBC; iCBC++) {CheckCbcReg(cCbcVector.at(iCBC))};
+                  //for (uint8_t iCBC = 0; i< nCBC; iCBC++) {CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)))};
                 
                   //now read Events
-                  ReadNEvents (fBoard, fNevents);
-                  const std::vector<Event*> cEvents = GetEvents (fBoard);
+                  ReadNEvents (theBoard, fNevents);
+                  const std::vector<Event*> cEvents = GetEvents (theBoard);
                   int countEvent = 0;
                   for (auto cEvent : cEvents)
                   {
                     ++countEvent;
                     for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
                     {
-                      std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,cCbcVector.at(iCBC)->getChipId());
+                      std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
                       if (cHits.size() == nChan) LOG(INFO) << RED << "CBC "<< +iCBC << ": All channels firing!" << RESET;
                       else
                       {
@@ -425,10 +432,10 @@ void StubTool::scanStubs_wNoise()
                       {
                         if ( seedChan[smg] < 0 || seedChan[smg] > nChan ) continue;
                         if ( ((seedChan[smg]-1)/2)+(iCBC*127)+(bend/2) < 0 || ((seedChan[smg-1])/2)+(iCBC*127)+(bend/2) >= nChan ) continue;
-                        if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                        if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                         {
                           bool stubfinder = false;
-                          for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                          for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                           {
                             if (((seedChan[smg]-1)/2)+(iCBC*127)== (cStub.getCenter()+(iCBC*127)))
                             {
@@ -453,10 +460,10 @@ void StubTool::scanStubs_wNoise()
                           hSTUB_SCAN_error->Fill(((seedChan[smg]-1)/2)+(iCBC*127),(bend/2));
                         }
                       }
-                      if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                      if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                       {
                         uint8_t stubCounter = 0;
-                        for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                        for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                         {
                           stubCounter++;
                           double stub_position = cStub.getPosition();
@@ -494,18 +501,22 @@ void StubTool::scanStubs_wNoise()
           hSTUB_SCAN_bend_off[iCBC]->Write();
         } 
       }
-   }
+    }
+  }
 }
 
 void StubTool::scanStubs_swap()
 {
   std::stringstream outp;
-  for (auto cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    for (auto cFe : cBoard->fModuleVector)
+    BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    for(auto cOpticalGroup : *cBoard)
+    {
+      for (auto cFe : *cOpticalGroup)
       {
-        uint32_t cFeId = cFe->getFeId();
-        std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
+        uint32_t cFeId = cFe->getId();
+        ModuleContainer& cCbcVector = *cFe;
         const uint8_t nCBC = cCbcVector.size();
         //Uncoment for Bend uncoding 2
         //hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nChan,0,nChan,16,0,8);
@@ -553,7 +564,7 @@ void StubTool::scanStubs_swap()
             {
               cRegVec.push_back ( std::make_pair ( "Bend"+std::to_string(ireg),  BendReg[ireg] ) );
             }
-            fReadoutChipInterface->WriteChipMultReg (cCbcVector.at(iCBC), cRegVec );
+            fReadoutChipInterface->WriteChipMultReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
             cRegVec.clear();
           }
 
@@ -575,12 +586,12 @@ void StubTool::scanStubs_swap()
                     cRegVec.clear();
                     for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
                     {
-                      cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-                      cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
+                      static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+                      cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
                       cRegName =  fChannelMaskMapCBC3[i];
                       cRegVec.push_back ( std::make_pair ( cRegName ,cRegValue ) );  
                     }
-                    fReadoutChipInterface->WriteChipMultReg ( cCbcVector.at(iCBC), cRegVec );
+                    fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
                     cRegVec.clear();
                   }
   
@@ -600,12 +611,12 @@ void StubTool::scanStubs_swap()
                         int corrChan = nChan + (seedChan[smg] + bend - 1 );
                         if ((int)bend % 2 != 0) corrChan = nChan + (seedChan[smg] + bend); 
                         if (corrChan % 2 == 0 || corrChan <= 0) continue;
-                        maskChannel(cCbcVector.at(iCBC-1), corrChan, false);
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan, false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
                         LOG (DEBUG) << "Cond 1: Corr Chan (CBC"<< +(iCBC-1) << "): " << +corrChan;
                         if ((int)bend % 2 != 0 && corrChan-2 > 0 ) 
                         {
-                          maskChannel(cCbcVector.at(iCBC-1), corrChan-2, false); 
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan-2, false); 
                           LOG (DEBUG) << "              , Corr Chan : " << (corrChan - 2);
                         }
                       }
@@ -616,19 +627,19 @@ void StubTool::scanStubs_swap()
                         int corrChan = (seedChan[smg] + bend - 1 ) - nChan;
                         if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend) - nChan;
                         if (corrChan % 2 == 0 ) continue;
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                        if (corrChan > 0 ) { maskChannel(cCbcVector.at(iCBC+1), corrChan, false); LOG (DEBUG) << "Cond 2 v1: Corr Chan (CBC" << iCBC+1 << "): " << +corrChan;}
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                        if (corrChan > 0 ) { maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan, false); LOG (DEBUG) << "Cond 2 v1: Corr Chan (CBC" << iCBC+1 << "): " << +corrChan;}
                         if ((int)bend % 2 != 0) 
                         {
                           if (corrChan-2 > 0)
                           { 
-                            maskChannel(cCbcVector.at(iCBC+1), corrChan-2, false);
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan-2, false);
                             LOG (DEBUG) << "                 , Corr Chan (CBC" << +(iCBC+1) << "): " << +(corrChan - 2);
                           }
                           else
                           {
                             corrChan = nChan-1; 
-                            maskChannel(cCbcVector.at(iCBC), corrChan, false); 
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false); 
                             LOG (DEBUG) << "                 , Corr Chan (CBC" << +(iCBC) << "): " << +(corrChan);
                           }
                         }
@@ -639,40 +650,40 @@ void StubTool::scanStubs_swap()
                         int corrChan = (seedChan[smg] + bend - 1 );
                         if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend);
                         if (corrChan % 2 == 0 || corrChan <= 0) continue;
-                        maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                        maskChannel(cCbcVector.at(iCBC), corrChan, false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false);
                         LOG (DEBUG) << "Cond 3: Corr Chan (CBC"<< +(iCBC) << "): " <<  corrChan;
                         if ((int)bend % 2 != 0 && corrChan-2 > 0 )
                         {
-                          maskChannel(cCbcVector.at(iCBC), corrChan-2, false); 
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan-2, false); 
                           LOG (DEBUG) << "         , Corr Chan : " << (corrChan - 2);
                         }
                       }
                       //MASKING BAD CHANNELS FOR CBC3.0
                       /*if (iCBC > 0)
                       {
-                        maskChannel(cCbcVector.at(iCBC-1), 108, true);
-                        maskChannel(cCbcVector.at(iCBC-1), 226, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 108, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 226, true);
                       }
-                      maskChannel(cCbcVector.at(iCBC), 108, true);
-                      maskChannel(cCbcVector.at(iCBC), 226, true);
+                      maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 108, true);
+                      maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 226, true);
                       */
                     }
                   }
   
                   // CHECKING CBC REGISTERS
-                  //for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++) {CheckCbcReg(cCbcVector.at(iCBC));}
+                  //for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++) {CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)));}
                 
                   //now read Events
-                  ReadNEvents (fBoard, fNevents);
-                  const std::vector<Event*> cEvents = GetEvents (fBoard);
+                  ReadNEvents (theBoard, fNevents);
+                  const std::vector<Event*> cEvents = GetEvents (theBoard);
                   int countEvent = 0;
                   for (auto cEvent : cEvents)
                   {
                     ++countEvent;
                     for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
                     {
-                      std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,cCbcVector.at(iCBC)->getChipId());
+                      std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
                       if (cHits.size() == nChan) LOG(INFO) << RED << "CBC "<< +iCBC << ": All channels firing!" << RESET;
                       else
                       {
@@ -689,10 +700,10 @@ void StubTool::scanStubs_swap()
                       {
                         if ( seedChan[smg] < 0 || seedChan[smg] > nChan ) continue;
                         if ( ((seedChan[smg]-1)/2)+(iCBC*127)+(bend/2) < 0 || ((seedChan[smg-1])/2)+(iCBC*127)+(bend/2) >= nChan ) continue;
-                        if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                        if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                         {
                           bool stubfinder = false;
-                          for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                          for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                           {
                             if (((seedChan[smg]-1)/2)+(iCBC*127)== (cStub.getCenter()+(iCBC*127)))
                             {
@@ -717,10 +728,10 @@ void StubTool::scanStubs_swap()
                           hSTUB_SCAN_error->Fill(((seedChan[smg]-1)/2)+(iCBC*127),(bend/2));
                         }
                       }
-                      if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                      if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                       {
                         uint8_t stubCounter = 0;
-                        for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                        for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                         {
                           stubCounter++;
                           double stub_position = cStub.getPosition();
@@ -758,7 +769,8 @@ void StubTool::scanStubs_swap()
           hSTUB_SCAN_bend_off[iCBC]->Write();
         } 
       }
-   }
+    }
+  }
 }
 
 void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
@@ -770,12 +782,15 @@ void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
     LOG(INFO) << RED << "Strip range values are 0 to 127" << RESET;
     exit (EXIT_FAILURE);
   }
-  for (auto cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    for (auto cFe : cBoard->fModuleVector)
+    BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    for(auto cOpticalGroup : *cBoard)
+    {
+      for (auto cFe : *cOpticalGroup)
       {
-        uint32_t cFeId = cFe->getFeId();
-        std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
+        uint32_t cFeId = cFe->getId();
+        ModuleContainer& cCbcVector = *cFe;
         const uint8_t nCBC = cCbcVector.size();
         std::string stubscanname_cw   = "StubsSCAN_ClusterWidth";
         std::string stubscanname_cbc = "StubsSCAN_ClusterWidth_vs_Strips";
@@ -820,25 +835,25 @@ void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
               { 
                 cRegVec.push_back ( std::make_pair ( "Bend"+std::to_string(ireg),  BendReg[ireg] ) );
               }
-              //fReadoutChipInterface->WriteChipMultReg (cCbcVector.at(iCBC), cRegVec );
+              //fReadoutChipInterface->WriteChipMultReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
               //cRegVec.clear();
               //MASKING ALL CHANNELS
               for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
               {
-                cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-                cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
+                static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+                cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
                 cRegName =  fChannelMaskMapCBC3[i];
                 cRegVec.push_back ( std::make_pair ( cRegName ,cRegValue ) );  
                 //LOG (DEBUG) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
               }
-              fReadoutChipInterface->WriteChipMultReg ( cCbcVector.at(iCBC), cRegVec );
+              fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
               cRegVec.clear();
               if (teststrip+iClusterWidth>127)
               { 
                 for (uint8_t iChan = 0; iChan < (iClusterWidth*2); ++iChan)
                 {
                   LOG(DEBUG) << "CBC"<< +iCBC << " | RegClusterWidth = " << +regClusterWidth << " - Cluster Width = " << +iClusterWidth << " | Diff Chan = " << -iChan << " | Cond2: masking channel " << +((2*teststrip) - iChan ); 
-                  maskChannel(cCbcVector.at(iCBC), ((2*teststrip) - iChan ), false);
+                  maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), ((2*teststrip) - iChan ), false);
                   // exp_strip = teststrip-(iClusterWidth/2);
                 }
               }
@@ -847,25 +862,25 @@ void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
                 for (uint8_t iChan = 1; iChan <= (iClusterWidth*2); ++iChan)
                 {
                   LOG(DEBUG) << "CBC"<< +iCBC << " | RegClusterWidth = " << +regClusterWidth << " - Cluster Width = " << +iClusterWidth << " | Diff Chan = " << +iChan << " | Cond1: masking channel " << +((2*teststrip) + iChan ); 
-                  maskChannel(cCbcVector.at(iCBC), ((2*teststrip) + iChan ), false);
+                  maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), ((2*teststrip) + iChan ), false);
                   // exp_strip = teststrip+(iClusterWidth/2);
                 }
               }
 
               // CHECKING CBC REGISTERS
-              //CheckCbcReg(cCbcVector.at(iCBC));
+              //CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)));
             }  
             
             //now read Events
-            ReadNEvents (fBoard, fNevents);
-            const std::vector<Event*> cEvents = GetEvents (fBoard);
+            ReadNEvents (theBoard, fNevents);
+            const std::vector<Event*> cEvents = GetEvents (theBoard);
             int countEvent = 0;
             for (auto cEvent : cEvents)
             {
               ++countEvent;
               for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
               {
-                std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,cCbcVector.at(iCBC)->getChipId());
+                std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
                 if (cHits.size() == nChan) LOG(DEBUG) << RED << "CBC "<< +iCBC << ": All channels firing!" << RESET;
                 else
                 {
@@ -877,10 +892,10 @@ void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
                     LOG (DEBUG) << BLUE << std::dec << cHit << " : " << HIT << " , " << STRIP << RESET;
                   }
                 }
-                if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                 {
                   uint8_t stubCounter = 0;
-                  for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                  for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                   {
                     stubCounter++;
                     double stub_strip    = cStub.getCenter();
@@ -908,19 +923,23 @@ void StubTool::scanStubs_clusterWidth(unsigned int teststrip)
           hSTUB_SCAN_cw_cbc[iCBC]->Write();
         }
       }
-   }
+    }
+  }
 }
 
 
 void StubTool::scanStubs_ptWidth()
 {
   std::stringstream outp;
-  for (auto cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    for (auto cFe : cBoard->fModuleVector)
+    BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    for(auto cOpticalGroup : *cBoard)
+    {
+      for (auto cFe : *cOpticalGroup)
       {
-        uint32_t cFeId = cFe->getFeId();
-        std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
+        uint32_t cFeId = cFe->getId();
+        ModuleContainer& cCbcVector = *cFe;
         const uint8_t nCBC = cCbcVector.size();
         //Uncoment for Bend uncoding 2
         //hSTUB_SCAN_tg = new TH2F(stubscanname_tg.c_str(),stubscanname_tg.c_str(),nChan,0,nChan,16,0,8);
@@ -970,7 +989,7 @@ void StubTool::scanStubs_ptWidth()
               { 
                 cRegVec.push_back ( std::make_pair ( "Bend"+std::to_string(ireg),  BendReg[ireg] ) );
               }
-              fReadoutChipInterface->WriteChipMultReg (cCbcVector.at(iCBC), cRegVec );
+              fReadoutChipInterface->WriteChipMultReg (static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
               cRegVec.clear();
             }
 
@@ -991,13 +1010,13 @@ void StubTool::scanStubs_ptWidth()
 
                     for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
                     {
-                      cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-                      cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
+                      static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+                      cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
                       cRegName =  fChannelMaskMapCBC3[i];
                       cRegVec.push_back ( std::make_pair ( cRegName ,cRegValue ) );
                       //LOG (DEBUG) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
                     }
-                    fReadoutChipInterface->WriteChipMultReg ( cCbcVector.at(iCBC), cRegVec );
+                    fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
                     cRegVec.clear();
 
                   }
@@ -1017,12 +1036,12 @@ void StubTool::scanStubs_ptWidth()
                           int corrChan = nChan + (seedChan[smg] + bend + 1 );
                           if ((int)bend % 2 != 0) corrChan = nChan + (seedChan[smg] + bend); 
                           if (corrChan % 2 != 0 || corrChan <= 0) continue;
-                          maskChannel(cCbcVector.at(iCBC-1), corrChan, false);
-                          maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan, false);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
                           LOG (DEBUG) << "Cond 1: Corr Chan (CBC"<< +(iCBC-1) << "): " << +corrChan << " (" << +(seedChan[smg] + bend - 1) << ")";
                           if ((int)bend % 2 != 0 && corrChan+2 > 0 ) 
                           {
-                            maskChannel(cCbcVector.at(iCBC-1), corrChan+2, false); 
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), corrChan+2, false); 
                             LOG (DEBUG) << "              , Corr Chan : " << (corrChan + 2);
                           }
                         }
@@ -1033,18 +1052,18 @@ void StubTool::scanStubs_ptWidth()
                           int corrChan = (seedChan[smg] + bend + 1 ) - nChan;
                           if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend) - nChan;
                           if (corrChan % 2 != 0 ) continue;
-                          maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                          if (corrChan > 0 ) maskChannel(cCbcVector.at(iCBC+1), corrChan, false);
-                          else if (corrChan == 0 ) {corrChan = nChan; maskChannel(cCbcVector.at(iCBC), corrChan, false);}
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                          if (corrChan > 0 ) maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan, false);
+                          else if (corrChan == 0 ) {corrChan = nChan; maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false);}
                           LOG (DEBUG) << "Cond 2: Corr Chan (" << +(iCBC) <<"/"<< +(iCBC+1) << "): " << corrChan<< " (" << seedChan[smg] + bend + 1 << ")";
                           if (corrChan == nChan)
                           {              
-                            corrChan = 2; maskChannel(cCbcVector.at(iCBC+1), corrChan, false);
+                            corrChan = 2; maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan, false);
                             LOG (DEBUG) << "                 , Corr Chan " << +(iCBC+1) << ": " << (corrChan);
                           }
                           else if ((int)bend % 2 != 0 && corrChan+2 > 0)
                           {
-                            maskChannel(cCbcVector.at(iCBC+1), corrChan+2, false);
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC+1)), corrChan+2, false);
                             LOG (DEBUG) << "                 , Corr Chan " << +(iCBC+1) << ": " << (corrChan + 2);
                           }
                         } 
@@ -1054,40 +1073,40 @@ void StubTool::scanStubs_ptWidth()
                           int corrChan = (seedChan[smg] + bend + 1);
                           if ((int)bend % 2 != 0) corrChan = (seedChan[smg] + bend);
                           if (corrChan % 2 != 0 || corrChan <= 0) continue;
-                          maskChannel(cCbcVector.at(iCBC), seedChan[smg], false);
-                          maskChannel(cCbcVector.at(iCBC), corrChan, false);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), seedChan[smg], false);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan, false);
                           LOG (DEBUG) << "Cond 3: Corr Chan (CBC"<< +(iCBC) << "): " <<  corrChan << " (" << seedChan[smg] + bend + 1 << ")";
                           if ((int)bend % 2 != 0 && corrChan+2 >0 )
                           {
-                            maskChannel(cCbcVector.at(iCBC), corrChan+2, false); 
+                            maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), corrChan+2, false); 
                             LOG (DEBUG) << "         , Corr Chan : " << (corrChan + 2);
                           }
                         }
                         //MASKING BAD CHANNELS FOR CBC3.0
                         /*if (iCBC > 0)
                         {
-                          maskChannel(cCbcVector.at(iCBC-1), 107, true);
-                          maskChannel(cCbcVector.at(iCBC-1), 225, true);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 107, true);
+                          maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC-1)), 225, true);
                         }
-                        maskChannel(cCbcVector.at(iCBC), 107, true);
-                        maskChannel(cCbcVector.at(iCBC), 225, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 107, true);
+                        maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), 225, true);
                         */
                       }
                     }
     
                     // CHECKING CBC REGISTERS
-                    //for (uint8_t iCBC = 0; i< nCBC; iCBC++) {CheckCbcReg(cCbcVector.at(iCBC))};
+                    //for (uint8_t iCBC = 0; i< nCBC; iCBC++) {CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)))};
                   
                     //now read Events
-                    ReadNEvents (fBoard, fNevents);
-                    const std::vector<Event*> cEvents = GetEvents (fBoard);
+                    ReadNEvents (theBoard, fNevents);
+                    const std::vector<Event*> cEvents = GetEvents (theBoard);
                     int countEvent = 0;
                     for (auto cEvent : cEvents)
                     {
                       ++countEvent;
                       for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
                       {
-                        std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,cCbcVector.at(iCBC)->getChipId());
+                        std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
                         if (cHits.size() == nChan) LOG(INFO) << RED << "CBC "<< +iCBC << ": All channels firing!" << RESET;
                         else
                         {
@@ -1104,10 +1123,10 @@ void StubTool::scanStubs_ptWidth()
                         {
                           if ( seedChan[smg] < 0 || seedChan[smg] > nChan ) continue;
                           if ( ((seedChan[smg]-1)/2)+(iCBC*127)+(bend/2) < 0 || ((seedChan[smg]+1)/2)+(iCBC*127)+(bend/2) > nCBC*127 ) continue;
-                          if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                          if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                           {
                             bool stubfinder = false;
-                            for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                            for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                             {
                               if (((seedChan[smg]-1)/2)+(iCBC*127)== (cStub.getCenter()+(iCBC*127)))
                               {
@@ -1132,10 +1151,10 @@ void StubTool::scanStubs_ptWidth()
                             hSTUB_SCAN_error->Fill(((seedChan[smg]-1)/2)+(iCBC*127),(bend/2));
                           }
                         }
-                        if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                        if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                         {
                           uint8_t stubCounter = 1;
-                          for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                          for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                           {
                             double stub_position = cStub.getPosition();
                             double stub_bend     = Decoding_stub4(cStub.getBend());
@@ -1177,7 +1196,8 @@ void StubTool::scanStubs_ptWidth()
           hSTUB_SCAN_bend_off[iCBC]->Write();
         } 
       }
-   }
+    }
+  }
 }
 
 
@@ -1190,12 +1210,15 @@ void StubTool::scanStubs_SoF(unsigned int teststrip)
     LOG(INFO) << RED << "Strip range values are 0 to 127" << RESET;
     exit (EXIT_FAILURE);
   }
-  for (auto cBoard : fBoardVector)
+  for (auto cBoard : *fDetectorContainer)
   {
-    for (auto cFe : cBoard->fModuleVector)
+    BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+    for(auto cOpticalGroup : *cBoard)
+    {
+    for (auto cFe : *cOpticalGroup)
       {
-        uint32_t cFeId = cFe->getFeId();
-        std::vector < ReadoutChip* > cCbcVector = cFe->fReadoutChipVector;
+        uint32_t cFeId = cFe->getId();
+        ModuleContainer& cCbcVector = *cFe;
         const uint8_t nCBC = cCbcVector.size();
         std::string stubscanname_sof = "StubsSCAN_SoF";
         std::string stubscanname_cbc = "StubsSCAN_SoF_vs_Strips";
@@ -1240,21 +1263,21 @@ void StubTool::scanStubs_SoF(unsigned int teststrip)
             //MASKING ALL CHANNELS
             for ( unsigned int i = 0 ; i < fChannelMaskMapCBC3.size() ; i++ )
             {
-              cCbcVector.at(iCBC)->setReg (fChannelMaskMapCBC3[i], 0);
-              cRegValue = cCbcVector.at(iCBC)->getReg (fChannelMaskMapCBC3[i]);
+              static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->setReg (fChannelMaskMapCBC3[i], 0);
+              cRegValue = static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getReg (fChannelMaskMapCBC3[i]);
               cRegName =  fChannelMaskMapCBC3[i];
               cRegVec.push_back ( std::make_pair ( cRegName ,cRegValue ) );  
               //LOG (DEBUG) << fChannelMaskMapCBC3[i] << " " << std::bitset<8> (cRegValue);
             }
-            fReadoutChipInterface->WriteChipMultReg ( cCbcVector.at(iCBC), cRegVec );
+            fReadoutChipInterface->WriteChipMultReg ( static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), cRegVec );
             cRegVec.clear();
             if (teststrip+(8*5)>127)
             { 
               for (uint8_t istub = 0; istub < nstubs; ++istub)
               {
                 LOG(DEBUG) << "CBC"<< +iCBC << " | nstubs = " << +nstubs << " : Bend = " << +istub << " - Seed ch = " << +(teststrip - istub*16 + 1 ); 
-                maskChannel(cCbcVector.at(iCBC), (teststrip - istub*16 + 1 ), false);
-                maskChannel(cCbcVector.at(iCBC), (teststrip - istub*16 + 2 ), false);
+                maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), (teststrip - istub*16 + 1 ), false);
+                maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), (teststrip - istub*16 + 2 ), false);
               }
             }
             else
@@ -1262,25 +1285,25 @@ void StubTool::scanStubs_SoF(unsigned int teststrip)
               for (uint8_t istub = 0; istub < nstubs; ++istub)
               {
                 LOG(DEBUG) << "CBC"<< +iCBC << " | nstubs = " << +nstubs << " : Bend = " << +istub << " - Seed ch = " << +(teststrip + istub*16 + 1 );
-                maskChannel(cCbcVector.at(iCBC), (teststrip + istub*16 + 1 ), false);
-                maskChannel(cCbcVector.at(iCBC), (teststrip + istub*16 + 2 ), false);
+                maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), (teststrip + istub*16 + 1 ), false);
+                maskChannel(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)), (teststrip + istub*16 + 2 ), false);
               }
             }
 
             // CHECKING CBC REGISTERS
-            //CheckCbcReg(cCbcVector.at(iCBC));
+            //CheckCbcReg(static_cast<ReadoutChip*>(cCbcVector.at(iCBC)));
           }  
           
           //now read Events
-          ReadNEvents (fBoard, fNevents);
-          const std::vector<Event*> cEvents = GetEvents (fBoard);
+          ReadNEvents (theBoard, fNevents);
+          const std::vector<Event*> cEvents = GetEvents (theBoard);
           int countEvent = 0;
           for (auto cEvent : cEvents)
           {
             ++countEvent;
             for (uint8_t iCBC = 0; iCBC< nCBC; iCBC++)
             {
-              std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,cCbcVector.at(iCBC)->getChipId());
+              std::vector<uint32_t> cHits = cEvent->GetHits(cFeId,static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
               if (cHits.size() == nChan) LOG(DEBUG) << RED << "CBC "<< +iCBC << ": All channels firing!" << RESET;
               else
               {
@@ -1292,18 +1315,18 @@ void StubTool::scanStubs_SoF(unsigned int teststrip)
                   LOG (DEBUG) << BLUE << std::dec << cHit << " : " << HIT << " , " << STRIP << RESET;
                 }
               }
-              if (cEvent->StubBit (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+              if (cEvent->StubBit (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
               {
                 uint8_t stubCounter = 0;
-                uint8_t nstub = cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ).size();
-                for (auto& cStub : cEvent->StubVector (cFeId, cCbcVector.at(iCBC)->getChipId() ) )
+                uint8_t nstub = cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ).size();
+                for (auto& cStub : cEvent->StubVector (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId() ) )
                 {
                   stubCounter++;
                   double stub_position = cStub.getPosition();
                   double stub_bend     = Decoding_stub4(cStub.getBend());
                   double stub_strip    = cStub.getCenter();
                   LOG (DEBUG) << RED << "CBC" << +iCBC << " , Stub: " << +(stubCounter) << " | Position: " << stub_position << " | Bend: " << std::bitset<4> (cStub.getBend()) << " -> " << stub_bend << " || Strip: " << stub_strip << " , Filling STRIP: " << +(stub_strip+(iCBC*127)) << RESET;
-                  uint16_t cKey = encodeId (cFeId, cCbcVector.at(iCBC)->getChipId());
+                  uint16_t cKey = encodeId (cFeId, static_cast<ReadoutChip*>(cCbcVector.at(iCBC))->getChipId());
                   EventDataMap::const_iterator cData = cEvent->fEventDataMap.find (cKey);
                   if (cData != std::end (cEvent->fEventDataMap) )
                   {
@@ -1358,7 +1381,8 @@ void StubTool::scanStubs_SoF(unsigned int teststrip)
           hSTUB_SCAN_sof_cbc[iCBC]->Write();
         }
       }
-   }
+    }
+  }
 }
 
 
@@ -1405,37 +1429,41 @@ void StubTool::setInitialOffsets()
 {
     LOG (INFO) << "Re-applying the original offsets for all CBCs" ;
     
-    for ( auto cBoard : fBoardVector )
+    for ( auto cBoard : *fDetectorContainer )
     {
-        for ( auto cFe : cBoard->fModuleVector )
+      for(auto cOpticalGroup : *cBoard)
+      {
+        for ( auto cFe : *cOpticalGroup )
         {
-            for ( auto cCbc : cFe->fReadoutChipVector )
+            for ( auto cCbc : *cFe )
             {
+                ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
                 RegisterVector cRegVec;
 
                 for ( uint8_t cChan = 0; cChan < nChan; cChan++ )
                 {   
                     TString cRegName = Form ( "Channel%03d", cChan + 1 );
-                    uint8_t cOffset = cCbc->getReg ( cRegName.Data() );
-                    cCbc->setReg ( Form ( "Channel%03d", cChan + 1 ), cOffset );
+                    uint8_t cOffset = theCbc->getReg ( cRegName.Data() );
+                    theCbc->setReg ( Form ( "Channel%03d", cChan + 1 ), cOffset );
                     cRegVec.push_back ({ Form ( "Channel%03d", cChan + 1 ), cOffset } );
                     //LOG (DEBUG) << "Original Offset for CBC " << cCbcId << " channel " << +cChan << " " << +cOffset ;
                 }
 
-                if (cCbc->getFrontEndType() == FrontEndType::CBC3)
+                if (theCbc->getFrontEndType() == FrontEndType::CBC3)
                 {   
                     //LOG (INFO) << BOLDBLUE << "Chip Type = CBC3 - re-enabling stub logic to original value!" << RESET;
-                    fStubLogicValue[cCbc] = fReadoutChipInterface->ReadChipReg (cCbc, "Pipe&StubInpSel&Ptwidth");
-                    fHIPCountValue[cCbc] = fReadoutChipInterface->ReadChipReg (cCbc, "HIP&TestMode");
-                    cRegVec.push_back ({"Pipe&StubInpSel&Ptwidth", fStubLogicValue[cCbc]});
-                    cRegVec.push_back ({"HIP&TestMode", fHIPCountValue[cCbc]});
+                    fStubLogicValue[theCbc] = fReadoutChipInterface->ReadChipReg (theCbc, "Pipe&StubInpSel&Ptwidth");
+                    fHIPCountValue[theCbc] = fReadoutChipInterface->ReadChipReg (theCbc, "HIP&TestMode");
+                    cRegVec.push_back ({"Pipe&StubInpSel&Ptwidth", fStubLogicValue[theCbc]});
+                    cRegVec.push_back ({"HIP&TestMode", fHIPCountValue[theCbc]});
                 }
                 
-                fReadoutChipInterface->WriteChipMultReg (cCbc, cRegVec);
+                fReadoutChipInterface->WriteChipMultReg (theCbc, cRegVec);
                 cRegVec.clear();
             }
         }
-    }
+      }
+  }
 }
 
 void StubTool::configureTestPulse (Chip* pCbc, uint8_t pPulseState)
diff --git a/tools/StubTool.h b/tools/StubTool.h
index 9596ef813..a9328212d 100644
--- a/tools/StubTool.h
+++ b/tools/StubTool.h
@@ -84,7 +84,7 @@ class StubTool : public Tool
     std::vector<Channel *> fChannelVector;
 
     //for our convenience
-    Ph2_HwDescription::Chip* fCbc;
+    Ph2_HwDescription::ReadoutChip* fCbc;
     Ph2_HwDescription::BeBoard* fBoard;
 
     //root stuff
diff --git a/tools/TPCalibration.cc b/tools/TPCalibration.cc
index 1adfd2238..2def64b62 100644
--- a/tools/TPCalibration.cc
+++ b/tools/TPCalibration.cc
@@ -34,41 +34,44 @@ void TPCalibration::Init(int pStartAmp, int pEndAmp, int pStepsize)
   fStepsize = pStepsize;
   fEndAmp = pEndAmp;
   LOG(INFO) << "Initialise histograms" << RESET;
-  for(auto &cBoard : fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
-    int cBeId = cBoard->getBeId();
+    int cBeId = cBoard->getId();
     LOG(INFO) << "BeBoard" << cBeId << RESET;
-    for(auto &cFe : cBoard->fModuleVector)
+    for(auto cOpticalGroup : *cBoard)
     {
-      int cFeId = cFe->getFeId();
-      LOG(INFO) << "  FE" << cFeId << RESET;
-      for(auto &cCbc: cFe->fReadoutChipVector)
+      for(auto cFe : *cOpticalGroup)
       {
-        int cCbcId = cCbc->getChipId();
-        LOG(INFO) << "  - CBC" << cCbcId << RESET;
-
-        for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+        int cFeId = cFe->getId();
+        LOG(INFO) << "  FE" << cFeId << RESET;
+        for(auto cCbc: *cFe)
         {
-          TGraph* cChanCorr = new TGraph((fEndAmp-fStartAmp)/fStepsize + 1);
-          cChanCorr->SetTitle(Form("Correlation Channel %d", cChannel) );
-          cChanCorr->SetName(Form("CorrChannel%d", cChannel) );
-          cChanCorr->GetXaxis()->SetTitle("pedestal (VCth)");
-          cChanCorr->GetYaxis()->SetTitle("test pulse amplitude (ADC)");
-          bookHistogram(cCbc, Form("CorrChan%d", cChannel), cChanCorr);
-        }
-
-        TH1F* cChannelGain = new TH1F(Form("GainFe%dCbc%d",cFeId, cCbcId),
-                                      Form("GainFe%dCbc%d",cFeId, cCbcId),
-                                      NCHANNELS, -0.5, NCHANNELS - 0.5);
-        cChannelGain->GetXaxis()->SetTitle("channel");
-        cChannelGain->GetYaxis()->SetTitle("gain (Amp)");
-        bookHistogram(cCbc, "ChannelGain", cChannelGain);
-        TH1F* cChannelElGain = new TH1F(Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
-                                        Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
+          int cCbcId = cCbc->getId();
+          LOG(INFO) << "  - CBC" << cCbcId << RESET;
+
+          for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+          {
+            TGraph* cChanCorr = new TGraph((fEndAmp-fStartAmp)/fStepsize + 1);
+            cChanCorr->SetTitle(Form("Correlation Channel %d", cChannel) );
+            cChanCorr->SetName(Form("CorrChannel%d", cChannel) );
+            cChanCorr->GetXaxis()->SetTitle("pedestal (VCth)");
+            cChanCorr->GetYaxis()->SetTitle("test pulse amplitude (ADC)");
+            bookHistogram(cCbc, Form("CorrChan%d", cChannel), cChanCorr);
+          }
+
+          TH1F* cChannelGain = new TH1F(Form("GainFe%dCbc%d",cFeId, cCbcId),
+                                        Form("GainFe%dCbc%d",cFeId, cCbcId),
                                         NCHANNELS, -0.5, NCHANNELS - 0.5);
-        cChannelElGain->GetXaxis()->SetTitle("channel");
-        cChannelElGain->GetYaxis()->SetTitle("gain (electrons)");
-        bookHistogram(cCbc, "ChannelElectronsGain", cChannelElGain);
+          cChannelGain->GetXaxis()->SetTitle("channel");
+          cChannelGain->GetYaxis()->SetTitle("gain (Amp)");
+          bookHistogram(cCbc, "ChannelGain", cChannelGain);
+          TH1F* cChannelElGain = new TH1F(Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
+                                          Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
+                                          NCHANNELS, -0.5, NCHANNELS - 0.5);
+          cChannelElGain->GetXaxis()->SetTitle("channel");
+          cChannelElGain->GetYaxis()->SetTitle("gain (electrons)");
+          bookHistogram(cCbc, "ChannelElectronsGain", cChannelElGain);
+        }
       }
     }
   }
@@ -96,29 +99,32 @@ void TPCalibration::FillHistograms(int pTPAmp)
 {
   LOG(INFO) << "Fill the histogram with the measured pedestals" << RESET;
 
-  for(auto &cBoard : fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
-    int cBeId = cBoard->getBeId();
+    int cBeId = cBoard->getId();
     LOG(INFO) << "BeBoard" << cBeId << RESET;
-    for(auto &cFe : cBoard->fModuleVector)
+    for(auto cOpticalGroup : *cBoard)
     {
-      int cFeId = cFe->getFeId();
-      LOG(INFO) << "  FE" << cFeId << RESET;
-      for(auto &cCbc: cFe->fReadoutChipVector)
+      for(auto cFe : *cOpticalGroup)
       {
-        int cCbcId = cCbc->getChipId();
-        LOG(INFO) << "  - CBC" << cCbcId << RESET;
-        TH1F* cPedestalHist = dynamic_cast<TH1F*>(getHist(cCbc, "Cbc_Strippedestal"));
-        for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+        int cFeId = cFe->getId();
+        LOG(INFO) << "  FE" << cFeId << RESET;
+        for(auto cCbc: *cFe)
         {
-          TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
-          int bin = cChannel + 1;
-          float cPed = cPedestalHist->GetBinContent(bin);
-          cCorrGraph->SetPoint(fTPCount, cPed , pTPAmp);
-          //Reset the histograms, so that it can be refilled for the next
-          //test pulse amplitude
-          cPedestalHist->SetBinContent(bin, 0);
-          cPedestalHist->SetBinError(bin, 0);
+          int cCbcId = cCbc->getId();
+          LOG(INFO) << "  - CBC" << cCbcId << RESET;
+          TH1F* cPedestalHist = dynamic_cast<TH1F*>(getHist(cCbc, "Cbc_Strippedestal"));
+          for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+          {
+            TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
+            int bin = cChannel + 1;
+            float cPed = cPedestalHist->GetBinContent(bin);
+            cCorrGraph->SetPoint(fTPCount, cPed , pTPAmp);
+            //Reset the histograms, so that it can be refilled for the next
+            //test pulse amplitude
+            cPedestalHist->SetBinContent(bin, 0);
+            cPedestalHist->SetBinError(bin, 0);
+          }
         }
       }
     }
@@ -130,57 +136,60 @@ void TPCalibration::FillHistograms(int pTPAmp)
 void TPCalibration::FitCorrelations()
 {
   LOG(INFO) << BOLDBLUE << "Linear fit of the correlations" << RESET;
-  for(auto &cBoard : fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
-    int cBeId = cBoard->getBeId();
+    int cBeId = cBoard->getId();
     LOG(INFO) << "BeBoard" << cBeId << RESET;
-    for(auto &cFe : cBoard->fModuleVector)
+    for(auto cOpticalGroup : *cBoard)
     {
-      int cFeId = cFe->getFeId();
-      LOG(INFO) << "  FE" << cFeId << RESET;
-      std::vector<float> cGainVec;
-      for(auto &cCbc: cFe->fReadoutChipVector)
+      for(auto cFe : *cOpticalGroup)
       {
-        int cCbcId = cCbc->getChipId();
-        TH1F* cChannelGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelGain"));
-        TH1F* cChannelElGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelElectronsGain"));
-        for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+        int cFeId = cFe->getId();
+        LOG(INFO) << "  FE" << cFeId << RESET;
+        std::vector<float> cGainVec;
+        for(auto cCbc: *cFe)
         {
-          TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
-          cCorrGraph->Fit("pol1", "Q");
-          float cGain = cCorrGraph->GetFunction("pol1")->GetParameter(1);
-          float cGainErr = cCorrGraph->GetFunction("pol1")->GetParError(1);
-          cChannelGain->SetBinContent(cChannel + 1, cGain);
-          cChannelGain->SetBinError(cChannel + 1, cGainErr);
-          cChannelElGain->SetBinContent(cChannel + 1, ConvertAmpToElectrons(cGain, false));
-          cChannelElGain->SetBinError(cChannel + 1, ConvertAmpToElectrons(cGainErr, false));
-          cGainVec.push_back(cGain);
+          int cCbcId = cCbc->getId();
+          TH1F* cChannelGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelGain"));
+          TH1F* cChannelElGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelElectronsGain"));
+          for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+          {
+            TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
+            cCorrGraph->Fit("pol1", "Q");
+            float cGain = cCorrGraph->GetFunction("pol1")->GetParameter(1);
+            float cGainErr = cCorrGraph->GetFunction("pol1")->GetParError(1);
+            cChannelGain->SetBinContent(cChannel + 1, cGain);
+            cChannelGain->SetBinError(cChannel + 1, cGainErr);
+            cChannelElGain->SetBinContent(cChannel + 1, ConvertAmpToElectrons(cGain, false));
+            cChannelElGain->SetBinError(cChannel + 1, ConvertAmpToElectrons(cGainErr, false));
+            cGainVec.push_back(cGain);
+          }
+
+          //Make a histogram of the Gains in Amplitudes and Electrons
+          TString cHistName = Form("GainHistFe%dCbc%d", cFeId, cCbcId);
+          float cBinWidth = 0.005;
+          float cMin = cChannelGain->GetMinimum()*0.9;
+          float cMax = cChannelGain->GetMaximum()*1.1;
+          TH1F* cGainHist = new TH1F(cHistName, cHistName, (cMax-cMin)/cBinWidth, cMin, cMax);
+          cGainHist->GetXaxis()->SetTitle("gain (Amp/VCth)");
+
+          cHistName = Form("GainElectronsHistFe%dCbc%d", cFeId, cCbcId);
+          TH1F* cGainElHist = new TH1F(cHistName, cHistName,(cMax-cMin)/cBinWidth,
+                                    ConvertAmpToElectrons(cMin, false),
+                                    ConvertAmpToElectrons(cMax, false));
+          cGainElHist->GetXaxis()->SetTitle("gain (electrons/VCth)");
+
+          for(auto cGain : cGainVec)
+          {
+            cGainHist->Fill(cGain);
+            cGainElHist->Fill(ConvertAmpToElectrons(cGain, false));
+          }
+          LOG(INFO) << "  - CBC" << cCbcId << ": Gain = " << GREEN
+                    << cGainElHist->GetMean() << "+-" << cGainElHist->GetStdDev()
+                    << RESET;
+          bookHistogram(cCbc, "GainHist", cGainHist);
+          bookHistogram(cCbc, "GainElectronsHist", cGainElHist);
         }
-
-        //Make a histogram of the Gains in Amplitudes and Electrons
-        TString cHistName = Form("GainHistFe%dCbc%d", cFeId, cCbcId);
-        float cBinWidth = 0.005;
-        float cMin = cChannelGain->GetMinimum()*0.9;
-        float cMax = cChannelGain->GetMaximum()*1.1;
-        TH1F* cGainHist = new TH1F(cHistName, cHistName, (cMax-cMin)/cBinWidth, cMin, cMax);
-        cGainHist->GetXaxis()->SetTitle("gain (Amp/VCth)");
-
-        cHistName = Form("GainElectronsHistFe%dCbc%d", cFeId, cCbcId);
-        TH1F* cGainElHist = new TH1F(cHistName, cHistName,(cMax-cMin)/cBinWidth,
-                                  ConvertAmpToElectrons(cMin, false),
-                                  ConvertAmpToElectrons(cMax, false));
-        cGainElHist->GetXaxis()->SetTitle("gain (electrons/VCth)");
-
-        for(auto cGain : cGainVec)
-        {
-          cGainHist->Fill(cGain);
-          cGainElHist->Fill(ConvertAmpToElectrons(cGain, false));
-        }
-        LOG(INFO) << "  - CBC" << cCbcId << ": Gain = " << GREEN
-                  << cGainElHist->GetMean() << "+-" << cGainElHist->GetStdDev()
-                  << RESET;
-        bookHistogram(cCbc, "GainHist", cGainHist);
-        bookHistogram(cCbc, "GainElectronsHist", cGainElHist);
       }
     }
   }
@@ -190,38 +199,41 @@ void TPCalibration::SaveResults()
 {
   LOG(INFO) << BOLDGREEN << "Write results to file: " << fResultFile->GetName()
             << RESET;
-  for(auto &cBoard : fBoardVector)
+  for(auto cBoard : *fDetectorContainer)
   {
-    int cBeId = cBoard->getBeId();
+    int cBeId = cBoard->getId();
     TString cPath = Form("Be%d", cBeId);
     fResultFile->mkdir(cPath);
-    for(auto &cFe : cBoard->fModuleVector)
+    for(auto cOpticalGroup : *cBoard)
     {
-      int cFeId = cFe->getFeId();
-      cPath = Form("Be%d/Fe%d", cBeId, cFeId);
-      fResultFile->mkdir(cPath);
-      for(auto &cCbc: cFe->fReadoutChipVector)
+      for(auto cFe : *cOpticalGroup)
       {
-        int cCbcId = cCbc->getChipId();
-        cPath = Form("Be%d/Fe%d/Cbc%d", cBeId, cFeId, cCbcId);
-        fResultFile->mkdir(cPath);
-        fResultFile->cd(cPath);
-        TH1F* cChannelHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelGain"));
-        cChannelHist->Write();
-        TH1F* cChannelElHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelElectronsGain"));
-        cChannelElHist->Write();
-        TH1F* cGainHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainHist"));
-        cGainHist->Write();
-        TH1F* cGainElHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainElectronsHist"));
-        cGainElHist->Write();
-
-        cPath = Form("Be%d/Fe%d/Cbc%d/ChannelCorr", cBeId, cFeId, cCbcId);
+        int cFeId = cFe->getId();
+        cPath = Form("Be%d/Fe%d", cBeId, cFeId);
         fResultFile->mkdir(cPath);
-        fResultFile->cd(cPath);
-        for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+        for(auto cCbc: *cFe)
         {
-          TGraph* cChanCorr = dynamic_cast<TGraph*> (getHist(cCbc, Form("CorrChan%d", cChannel)));
-          cChanCorr->Write();
+          int cCbcId = cCbc->getId();
+          cPath = Form("Be%d/Fe%d/Cbc%d", cBeId, cFeId, cCbcId);
+          fResultFile->mkdir(cPath);
+          fResultFile->cd(cPath);
+          TH1F* cChannelHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelGain"));
+          cChannelHist->Write();
+          TH1F* cChannelElHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelElectronsGain"));
+          cChannelElHist->Write();
+          TH1F* cGainHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainHist"));
+          cGainHist->Write();
+          TH1F* cGainElHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainElectronsHist"));
+          cGainElHist->Write();
+
+          cPath = Form("Be%d/Fe%d/Cbc%d/ChannelCorr", cBeId, cFeId, cCbcId);
+          fResultFile->mkdir(cPath);
+          fResultFile->cd(cPath);
+          for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
+          {
+            TGraph* cChanCorr = dynamic_cast<TGraph*> (getHist(cCbc, Form("CorrChan%d", cChannel)));
+            cChanCorr->Write();
+          }
         }
       }
     }
diff --git a/tools/Tool.cc b/tools/Tool.cc
index 4867b1b7a..9b3eef4a4 100644
--- a/tools/Tool.cc
+++ b/tools/Tool.cc
@@ -74,7 +74,6 @@ Tool::Tool (const Tool& pTool)
 	fChipInterface               = pTool.fChipInterface;
     fCicInterface                = pTool.fCicInterface;
     fReadoutChipInterface        = pTool.fReadoutChipInterface;
-	fBoardVector                 = pTool.fBoardVector;
 	fBeBoardFWMap                = pTool.fBeBoardFWMap;
 	fSettingsMap                 = pTool.fSettingsMap;
 	fFileHandler                 = pTool.fFileHandler;
@@ -118,7 +117,6 @@ void Tool::Inherit (Tool* pTool)
 	fChipInterface               = pTool->fChipInterface;
 	fCicInterface                = pTool->fCicInterface;
 	fReadoutChipInterface        = pTool->fReadoutChipInterface;
-	fBoardVector                 = pTool->fBoardVector;
 	fBeBoardFWMap                = pTool->fBeBoardFWMap;
 	fSettingsMap                 = pTool->fSettingsMap;
 	fFileHandler                 = pTool->fFileHandler;
@@ -156,7 +154,6 @@ void Tool::Inherit (SystemController* pSystemController)
 	fReadoutChipInterface = pSystemController->fReadoutChipInterface;
 	fChipInterface        = pSystemController->fChipInterface;
 	fCicInterface         = pSystemController->fCicInterface;
-	fBoardVector          = pSystemController->fBoardVector;
 	fBeBoardFWMap         = pSystemController->fBeBoardFWMap;
 	fSettingsMap          = pSystemController->fSettingsMap;
 	fFileHandler          = pSystemController->fFileHandler;
@@ -244,7 +241,7 @@ void Tool::SoftDestroy()
 
 #ifdef __USE_ROOT__    
 
-	void Tool::bookHistogram ( Chip* pChip, std::string pName, TObject* pObject )
+	void Tool::bookHistogram ( ChipContainer* pChip, std::string pName, TObject* pObject )
 	{
 		TH1* tmpHistogramPointer = dynamic_cast<TH1*>(pObject);
 		if(tmpHistogramPointer != nullptr) tmpHistogramPointer->SetDirectory(0);
@@ -255,7 +252,7 @@ void Tool::SoftDestroy()
 		if ( cChipHistMap == std::end ( fChipHistMap ) )
 		{
 			//Fabio: CBC specific -> to be moved out from Tool
-			LOG (INFO) << "Histo Map for CBC " << int ( pChip->getChipId() ) <<  " (FE " << int ( pChip->getFeId() ) << ") does not exist - creating " ;
+			LOG (INFO) << "Histo Map for CBC " << int ( pChip->getId() ) <<  " (FE " << int ( static_cast<ReadoutChip*>(pChip)->getFeId() ) << ") does not exist - creating " ;
 			std::map<std::string, TObject*> cTempChipMap;
 
 			fChipHistMap[pChip] = cTempChipMap;
@@ -274,7 +271,7 @@ void Tool::SoftDestroy()
 		#endif
 	}
 
-	void Tool::bookHistogram ( Module* pModule, std::string pName, TObject* pObject )
+	void Tool::bookHistogram ( ModuleContainer* pModule, std::string pName, TObject* pObject )
 	{
 		TH1* tmpHistogramPointer = dynamic_cast<TH1*>(pObject);
 		if(tmpHistogramPointer != nullptr) tmpHistogramPointer->SetDirectory(0);
@@ -284,7 +281,7 @@ void Tool::SoftDestroy()
 
 		if ( cModuleHistMap == std::end ( fModuleHistMap ) )
 		{
-			LOG (INFO) << "Histo Map for Module " << int ( pModule->getFeId() ) << " does not exist - creating " ;
+			LOG (INFO) << "Histo Map for Module " << int ( pModule->getId() ) << " does not exist - creating " ;
 			std::map<std::string, TObject*> cTempModuleMap;
 
 			fModuleHistMap[pModule] = cTempModuleMap;
@@ -302,7 +299,7 @@ void Tool::SoftDestroy()
 		#endif
 	}
 
-	void Tool::bookHistogram ( BeBoard* pBeBoard, std::string pName, TObject* pObject )
+	void Tool::bookHistogram ( BoardContainer* pBeBoard, std::string pName, TObject* pObject )
 	{
 		TH1* tmpHistogramPointer = dynamic_cast<TH1*>(pObject);
 		if(tmpHistogramPointer != nullptr) tmpHistogramPointer->SetDirectory(0);
@@ -312,7 +309,7 @@ void Tool::SoftDestroy()
 
 		if ( cBeBoardHistMap == std::end ( fBeBoardHistMap ) )
 		{
-			LOG (INFO) << "Histo Map for Module " << int ( pBeBoard->getBeId() ) << " does not exist - creating " ;
+			LOG (INFO) << "Histo Map for Module " << int ( pBeBoard->getId() ) << " does not exist - creating " ;
 			std::map<std::string, TObject*> cTempModuleMap;
 
 			fBeBoardHistMap[pBeBoard] = cTempModuleMap;
@@ -330,14 +327,14 @@ void Tool::SoftDestroy()
 		#endif
 	}
 
-	TObject* Tool::getHist ( Chip* pChip, std::string pName )
+	TObject* Tool::getHist ( ChipContainer* pChip, std::string pName )
 	{
 		auto cChipHistMap = fChipHistMap.find ( pChip );
 
 		if ( cChipHistMap == std::end ( fChipHistMap ) )
 		{
 			//Fabio: CBC specific -> to be moved out from Tool
-			LOG (ERROR) << RED << "Error: could not find the Histograms for CBC " << int ( pChip->getChipId() ) <<  " (FE " << int ( pChip->getFeId() ) << ")" << RESET ;
+			LOG (ERROR) << RED << "Error: could not find the Histograms for CBC " << int ( pChip->getId() ) <<  " (FE " << int ( static_cast<ReadoutChip*>(pChip)->getFeId() ) << ")" << RESET ;
 			return nullptr;
 		}
 		else
@@ -354,13 +351,13 @@ void Tool::SoftDestroy()
 		}
 	}
 
-	TObject* Tool::getHist ( Module* pModule, std::string pName )
+	TObject* Tool::getHist ( ModuleContainer* pModule, std::string pName )
 	{
 		auto cModuleHistMap = fModuleHistMap.find ( pModule );
 
 		if ( cModuleHistMap == std::end ( fModuleHistMap ) )
 		{
-			LOG (ERROR) << RED << "Error: could not find the Histograms for Module " << int ( pModule->getFeId() ) << RESET ;
+			LOG (ERROR) << RED << "Error: could not find the Histograms for Module " << int ( pModule->getId() ) << RESET ;
 			return nullptr;
 		}
 		else
@@ -376,13 +373,13 @@ void Tool::SoftDestroy()
 		}
 	}
 
-	TObject* Tool::getHist ( BeBoard* pBeBoard, std::string pName )
+	TObject* Tool::getHist ( BoardContainer* pBeBoard, std::string pName )
 	{
 		auto cBeBoardHistMap = fBeBoardHistMap.find ( pBeBoard );
 
 		if ( cBeBoardHistMap == std::end ( fBeBoardHistMap ) )
 		{
-			LOG (ERROR) << RED << "Error: could not find the Histograms for Module " << int ( pBeBoard->getBeId() ) << RESET ;
+			LOG (ERROR) << RED << "Error: could not find the Histograms for Module " << int ( pBeBoard->getId() ) << RESET ;
 			return nullptr;
 		}
 		else
@@ -418,9 +415,9 @@ void Tool::SaveResults()
 		}
 
 		// Now per FE
-		for ( const auto& cFe : fModuleHistMap )
+		for ( const auto& cHybrid : fModuleHistMap )
 		{
-			TString cDirName = Form ( "FE%d", cFe.first->getFeId() );
+			TString cDirName = Form ( "FE%d", cHybrid.first->getFeId() );
 			TObject* cObj = gROOT->FindObject ( cDirName );
 
 			//if ( cObj ) delete cObj;
@@ -429,7 +426,7 @@ void Tool::SaveResults()
 
 			fResultFile->cd ( cDirName );
 
-			for ( const auto& cHist : cFe.second )
+			for ( const auto& cHist : cHybrid.second )
 				cHist.second->Write ( cHist.second->GetName(), TObject::kOverwrite );
 
 			fResultFile->cd();
@@ -603,70 +600,77 @@ void Tool::CloseResultFile()
 
 void Tool::dumpConfigFiles()
 {
-  if (!fDirectoryName.empty())
-    {
-      //Fabio: CBC specific -> to be moved out from Tool
-      for(auto board : *fDetectorContainer)
-        {
-          for(auto module : *board)
-            {
-              for(auto chip : *module)
-                {
-                  std::string cFilename = fDirectoryName + "/BE" + std::to_string(board->getId()) + "_FE" + std::to_string(module->getId()) + "_Chip" + std::to_string(chip->getId()) + ".txt";
-                	LOG (DEBUG) << BOLDBLUE << "Dumping readout chip configuration to " << cFilename << RESET;
-                  static_cast<ReadoutChip*>(chip)->saveRegMap ( cFilename.data() );
-                }
-                auto& cCic = static_cast<OuterTrackerModule*>(module)->fCic;
-                if( cCic != NULL ) 
-            	{
-            		std::string cFilename = fDirectoryName + "/BE" + std::to_string(board->getId()) + "_FE" + std::to_string(module->getId()) + ".txt";
-                	LOG (INFO) << BOLDBLUE << "Dumping CIC configuration to " << cFilename << RESET;
-                	cCic->saveRegMap ( cFilename.data() );
-                }
-            }
-        }
-      LOG (INFO) << BOLDBLUE << "Configfiles for all Chips written to " << fDirectoryName << RESET;
-    }
-  else LOG (ERROR) << "Error: no results Directory initialized" << RESET;
+	if (!fDirectoryName.empty())
+	{
+		//Fabio: CBC specific -> to be moved out from Tool
+		for(auto board : *fDetectorContainer)
+		{
+			for(auto opticalGroup : *board)
+			{
+				for(auto module : *opticalGroup)
+				{
+					for(auto chip : *module)
+					{
+						std::string cFilename = fDirectoryName + "/BE" + std::to_string(board->getId()) + "_OG" + std::to_string(opticalGroup->getId()) + "_FE" + std::to_string(module->getId()) + "_Chip" + std::to_string(chip->getId()) + ".txt";
+						LOG (DEBUG) << BOLDBLUE << "Dumping readout chip configuration to " << cFilename << RESET;
+						static_cast<ReadoutChip*>(chip)->saveRegMap ( cFilename.data() );
+					}
+					auto& cCic = static_cast<OuterTrackerModule*>(module)->fCic;
+					if( cCic != NULL ) 
+					{
+						std::string cFilename = fDirectoryName + "/BE" + std::to_string(board->getId()) + "_OG" + std::to_string(opticalGroup->getId()) + "_FE" + std::to_string(module->getId()) + ".txt";
+						LOG (INFO) << BOLDBLUE << "Dumping CIC configuration to " << cFilename << RESET;
+						cCic->saveRegMap ( cFilename.data() );
+					}
+				}
+			}
+		}
+		LOG (INFO) << BOLDBLUE << "Configfiles for all Chips written to " << fDirectoryName << RESET;
+	}
+	else LOG (ERROR) << "Error: no results Directory initialized" << RESET;
 }
 
 void Tool::setSystemTestPulse ( uint8_t pTPAmplitude, uint8_t pTestGroup, bool pTPState, bool pHoleMode )
 {
 
-	for (auto cBoard : this->fBoardVector)
+	for (auto cBoard : *fDetectorContainer)
 	{
-		for (auto cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
 		{
-			for (auto cChip : cFe->fReadoutChipVector)
+			for (auto cHybrid : *cOpticalGroup)
 			{
-				//Fabio: CBC specific but not used by common scans - BEGIN
-				//first, get the Amux Value
-				uint8_t cOriginalAmuxValue;
-				cOriginalAmuxValue = cChip->getReg ("MiscTestPulseCtrl&AnalogMux" );
-				//uint8_t cOriginalHitDetectSLVSValue = cChip->getReg ("HitDetectSLVS" );
+				for (auto cChip : *cHybrid)
+				{
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+					//Fabio: CBC specific but not used by common scans - BEGIN
+					//first, get the Amux Value
+					uint8_t cOriginalAmuxValue;
+					cOriginalAmuxValue = theChip->getReg ("MiscTestPulseCtrl&AnalogMux" );
+					//uint8_t cOriginalHitDetectSLVSValue = theChip->getReg ("HitDetectSLVS" );
 
-				std::vector<std::pair<std::string, uint16_t>> cRegVec;
-				uint8_t cRegValue =  to_reg ( 0, pTestGroup );
+					std::vector<std::pair<std::string, uint16_t>> cRegVec;
+					uint8_t cRegValue =  to_reg ( 0, pTestGroup );
 
-				if (cChip->getFrontEndType() == FrontEndType::CBC3)
-				{
-					uint8_t cTPRegValue;
+					if (theChip->getFrontEndType() == FrontEndType::CBC3)
+					{
+						uint8_t cTPRegValue;
 
-					if (pTPState) cTPRegValue  = (cOriginalAmuxValue |  0x1 << 6);
-					else if (!pTPState) cTPRegValue = (cOriginalAmuxValue & ~ (0x1 << 6) );
+						if (pTPState) cTPRegValue  = (cOriginalAmuxValue |  0x1 << 6);
+						else if (!pTPState) cTPRegValue = (cOriginalAmuxValue & ~ (0x1 << 6) );
 
-					//uint8_t cHitDetectSLVSValue = (cOriginalHitDetectSLVSValue & ~(0x1 << 6));
+						//uint8_t cHitDetectSLVSValue = (cOriginalHitDetectSLVSValue & ~(0x1 << 6));
 
-					//cRegVec.push_back ( std::make_pair ( "HitDetectSLVS", cHitDetectSLVSValue ) );
-					cRegVec.push_back ( std::make_pair ( "MiscTestPulseCtrl&AnalogMux",  cTPRegValue ) );
-					cRegVec.push_back ( std::make_pair ( "TestPulseDel&ChanGroup",  cRegValue ) );
-					cRegVec.push_back ( std::make_pair ( "TestPulsePotNodeSel", pTPAmplitude ) );
-					LOG (DEBUG) << BOLDBLUE << "Read original Amux Value to be: " << std::bitset<8> (cOriginalAmuxValue) << " and changed to " << std::bitset<8> (cTPRegValue) << " - the TP is bit 6!" RESET;
-				}
+						//cRegVec.push_back ( std::make_pair ( "HitDetectSLVS", cHitDetectSLVSValue ) );
+						cRegVec.push_back ( std::make_pair ( "MiscTestPulseCtrl&AnalogMux",  cTPRegValue ) );
+						cRegVec.push_back ( std::make_pair ( "TestPulseDel&ChanGroup",  cRegValue ) );
+						cRegVec.push_back ( std::make_pair ( "TestPulsePotNodeSel", pTPAmplitude ) );
+						LOG (DEBUG) << BOLDBLUE << "Read original Amux Value to be: " << std::bitset<8> (cOriginalAmuxValue) << " and changed to " << std::bitset<8> (cTPRegValue) << " - the TP is bit 6!" RESET;
+					}
 
-				this->fReadoutChipInterface->WriteChipMultReg (cChip, cRegVec);
-				//Fabio: CBC specific but not used by common scans - END
+					this->fReadoutChipInterface->WriteChipMultReg (theChip, cRegVec);
+					//Fabio: CBC specific but not used by common scans - END
 
+				}
 			}
 		}
 	}
@@ -675,13 +679,17 @@ void Tool::setSystemTestPulse ( uint8_t pTPAmplitude, uint8_t pTestGroup, bool p
 void Tool::enableTestPulse(bool enableTP)
 {
 	fTestPulse = enableTP;          
-	for (auto cBoard : this->fBoardVector)
+
+	for (auto cBoard : *fDetectorContainer)
 	{
-		for (auto cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
 		{
-			for (auto cChip : cFe->fReadoutChipVector)
+			for (auto cHybrid : *cOpticalGroup)
 			{
-				fReadoutChipInterface->enableInjection(cChip, enableTP);
+				for (auto cChip : *cHybrid)
+				{
+					fReadoutChipInterface->enableInjection(static_cast<ReadoutChip*>(cChip), enableTP);
+				}
 			}
 		}
 	}
@@ -716,11 +724,12 @@ void Tool::selectGroupTestPulse(Chip* cChip, uint8_t pTestGroup)
 
 void Tool::setFWTestPulse()
 {
-	for (auto& cBoard : fBoardVector)
+	for (auto& cBoard : *fDetectorContainer)
 	{
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
 		std::vector<std::pair<std::string, uint32_t> > cRegVec;
 
-		switch(cBoard->getBoardType())
+		switch(theBoard->getBoardType())
 		{
 		case BoardType::D19C :
 		{
@@ -731,14 +740,14 @@ void Tool::setFWTestPulse()
 
 		default :
 		{
-			LOG(ERROR) << BOLDRED << __PRETTY_FUNCTION__ << " BeBoard type not recognized for Bebord "<< cBoard->getBeId() << ", aborting" << RESET;
+			LOG(ERROR) << BOLDRED << __PRETTY_FUNCTION__ << " BeBoard type not recognized for Bebord "<< cBoard->getId() << ", aborting" << RESET;
 			throw ("[Tool::setFWTestPulse]\tError, BeBoard type not found");
 			break;
 		}
 
 		}
 
-		fBeBoardInterface->WriteBoardMultReg (cBoard, cRegVec);
+		fBeBoardInterface->WriteBoardMultReg (theBoard, cRegVec);
 	}
 }
 
@@ -791,7 +800,6 @@ std::pair<float,float> Tool::evalNoise(std::vector<float> pData, std::vector<flo
     std::transform(cWeights.begin(), cWeights.end(), pValues.begin(), pData.begin() , std::multiplies<float>()); 
     float cMean = std::accumulate(pData.begin(), pData.end() , 0.);
     cMean /= cSumOfWeights;
-    float cErrorOnMean = 1.0/std::sqrt(cSumOfWeights);
     //weighted sample variance of scan values to get noise
     std::transform(pValues.begin(), pValues.end(),  pData.begin() , [&](float el){ return (el - cMean)*(el-cMean);});
     std::transform(cWeights.begin(), cWeights.end(), pData.begin(), pData.begin() , std::multiplies<float>());
@@ -804,44 +812,6 @@ std::pair<float,float> Tool::evalNoise(std::vector<float> pData, std::vector<flo
 
 
 
-// //method to mask a channel list
-// void Tool::maskChannelFromOtherGroups (Chip* pChip, int pTestGroup){
-
-//     std::vector<uint8_t> chipMask;
-//     bool chipHasMaskedChannels = pChip->hasMaskedChannels();
-//     if(chipHasMaskedChannels) chipMask = pChip->getChipMask();
-//     const std::vector<uint8_t> &groupMask = fMaskForTestGroupChannelMap[pTestGroup];
-
-//     RegisterVector cRegVec; 
-//     cRegVec.clear(); 
-
-//     switch(pChip->getFrontEndType())
-//     {
-//         case FrontEndType::CBC3 :
-//         {   
-//             for(uint8_t i=0; i<chipMask.size(); ++i){
-//                 if(chipHasMaskedChannels) cRegVec.push_back ( {fChannelMaskMapCBC3[i], chipMask[i] & groupMask[i] } );
-//                 else cRegVec.push_back ( {fChannelMaskMapCBC3[i], groupMask[i] } );
-//             }
-//             break;
-//         }
-
-//         default :
-//         {
-//             LOG(ERROR) << BOLDRED << __PRETTY_FUNCTION__ << " FrontEnd type not recognized for Bebord "<< 
-//                 pChip->getBeId() << " Module " << pChip->getFeId() << " Chip " << pChip->getChipId() << ", aborting" << RESET;
-//             throw ("[Tool::SetMaskAllChannels]\tError, FrontEnd type not found");
-//             break;
-//         }
-//     }
-
-//     fReadoutChipInterface->WriteChipMultReg ( pChip , cRegVec );
-
-//     return;
-// }
-
-
-
 // then a method to un-mask pairs of channels on a given CBC
 void Tool::unmaskPair(Chip* cChip ,  std::pair<uint8_t,uint8_t> pPair)
 {
@@ -959,7 +929,7 @@ void Tool::bitWiseScanBeBoard(uint16_t boardIndex, const std::string &dacName, u
 
 	DetectorDataContainer *outputDataContainer = fDetectorDataContainer;
 
-	ReadoutChip *cChip = static_cast<BeBoard*>(fDetectorContainer->at(boardIndex))->fModuleVector.at(0)->fReadoutChipVector.at(0); //assumption: one BeBoard has only one type of chip;
+	ReadoutChip *cChip = static_cast<ReadoutChip*>(fDetectorContainer->at(boardIndex)->at(0)->at(0)->at(0)); //assumption: one BeBoard has only one type of chip;
 
 	bool localDAC = cChip->isDACLocal(dacName);
 	uint8_t numberOfBits = cChip->getNumberOfBits(dacName);
@@ -1016,27 +986,30 @@ void Tool::bitWiseScanBeBoard(uint16_t boardIndex, const std::string &dacName, u
 	for(int iBit = numberOfBits-1; iBit>=0; --iBit)
 	{
 		LOG (DEBUG) << BOLDBLUE << "Bit number " << +iBit << " of " << dacName << RESET;
-		for ( auto cFe : *(fDetectorContainer->at(boardIndex)))
+		for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)))
 		{
-			for ( auto cChip : *cFe )
+            for ( auto cHybrid : *cOpticalGroup )
 			{
-				if(localDAC)
+				for ( auto cChip : *cHybrid )
 				{
-					for(uint32_t iChannel=0; iChannel<cChip->size(); ++iChannel)
+					if(localDAC)
 					{
+						for(uint32_t iChannel=0; iChannel<cChip->size(); ++iChannel)
+						{
 
-						if(occupanyDirectlyProportionalToDAC) currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
-								= previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel) + (1<<iBit);
-						else currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
-								= previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel) & (0xFFFF - (1<<iBit));
+							if(occupanyDirectlyProportionalToDAC) currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
+									= previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel) + (1<<iBit);
+							else currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
+									= previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel) & (0xFFFF - (1<<iBit));
+						}
+					}
+					else
+					{
+						if(occupanyDirectlyProportionalToDAC) currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
+								= previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() + (1<<iBit);
+						else currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
+								= previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() & (0xFFFF - (1<<iBit));
 					}
-				}
-				else
-				{
-					if(occupanyDirectlyProportionalToDAC) currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
-							= previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() + (1<<iBit);
-					else currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
-							= previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() & (0xFFFF - (1<<iBit));
 				}
 			}
 		}
@@ -1048,31 +1021,34 @@ void Tool::bitWiseScanBeBoard(uint16_t boardIndex, const std::string &dacName, u
 		measureBeBoardData(boardIndex, numberOfEvents, numberOfEventsPerBurst);
 
 		//Determine if it is better or not
-		for ( auto cFe : *(fDetectorContainer->at(boardIndex)))
+		for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)))
 		{
-			for ( auto cChip : *cFe )
+            for ( auto cHybrid : *cOpticalGroup )
 			{
-				if(localDAC)
+				for ( auto cChip : *cHybrid )
 				{
-					for(uint32_t iChannel=0; iChannel<cChip->size(); ++iChannel)
+					if(localDAC)
 					{
-						if( currentStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy <= targetOccupancy )
+						for(uint32_t iChannel=0; iChannel<cChip->size(); ++iChannel)
 						{
-							previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
-									= currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel);
-							previousStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy
-									= currentStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
+							if( currentStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy <= targetOccupancy )
+							{
+								previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel)
+										= currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(iChannel);
+								previousStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy
+										= currentStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<Occupancy>(iChannel).fOccupancy;
+							}
 						}
 					}
-				}
-				else
-				{
-					if( currentStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy <= targetOccupancy )
+					else
 					{
-						previousDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
-								= currentDacList->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
-						previousStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy
-								= currentStepOccupancyContainer->at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy;
+						if( currentStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy <= targetOccupancy )
+						{
+							previousDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()
+									= currentDacList->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
+							previousStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy
+									= currentStepOccupancyContainer->at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<Occupancy,Occupancy>().fOccupancy;
+						}
 					}
 				}
 			}
@@ -1166,13 +1142,16 @@ void Tool::doScanOnAllGroupsBeBoard(uint16_t boardIndex, uint32_t numberOfEvents
 	    {
 	      if(fMaskChannelsFromOtherGroups || fTestPulse)
 	        {
-	            for ( auto cFe : *(fDetectorContainer->at(boardIndex)))
-	            {
-	                for ( auto cChip : *cFe )
-	                {
-						fReadoutChipInterface->maskChannelsAndSetInjectionSchema(static_cast<ReadoutChip*>(cChip), group,fMaskChannelsFromOtherGroups,fTestPulse);
-	                }
-	            }
+				for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)))
+				{
+					for ( auto cHybrid : *cOpticalGroup )
+					{
+						for ( auto cChip : *cHybrid )
+						{
+							fReadoutChipInterface->maskChannelsAndSetInjectionSchema(static_cast<ReadoutChip*>(cChip), group,fMaskChannelsFromOtherGroups,fTestPulse);
+						}
+					}
+				}
 	        }
 
 	        groupScan->setGroup(group);
@@ -1181,12 +1160,15 @@ void Tool::doScanOnAllGroupsBeBoard(uint16_t boardIndex, uint32_t numberOfEvents
 
 	    if(fMaskChannelsFromOtherGroups)//re-enable all the channels and evaluate
 	    {
-	        for ( auto cFe : *(fDetectorContainer->at(boardIndex)) )
+	        for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)) )
 	        {
-	            for ( auto cChip : *cFe )
-	            {
-	                fReadoutChipInterface->ConfigureChipOriginalMask ( static_cast<ReadoutChip*>(cChip) );
-	            }
+				for ( auto cHybrid : *cOpticalGroup )
+				{
+					for ( auto cChip : *cHybrid )
+					{
+						fReadoutChipInterface->ConfigureChipOriginalMask ( static_cast<ReadoutChip*>(cChip) );
+					}
+				}
 	        }
 	    }
 	}
@@ -1339,11 +1321,14 @@ void Tool::scanBeBoardDac(uint16_t boardIndex, const std::string &dacName, const
 //Set global DAC for all CBCs in the BeBoard
 void Tool::setAllGlobalDacBeBoard(uint16_t boardIndex, const std::string &dacName, DetectorDataContainer &globalDACContainer)
 {
-	for ( auto cFe : *(fDetectorContainer->at(boardIndex)) )
+	for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)) )
 	{
-		for ( auto cChip : *cFe )
+		for ( auto cHybrid : *cOpticalGroup )
 		{
-			fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), dacName, globalDACContainer.at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>());
+			for ( auto cChip : *cHybrid )
+			{
+				fReadoutChipInterface->WriteChipReg ( static_cast<ReadoutChip*>(cChip), dacName, globalDACContainer.at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>());
+			}
 		}
 	}
 	return;
@@ -1352,12 +1337,15 @@ void Tool::setAllGlobalDacBeBoard(uint16_t boardIndex, const std::string &dacNam
 // set local dac per BeBoard
 void Tool::setAllLocalDacBeBoard(uint16_t boardIndex, const std::string &dacName, DetectorDataContainer &globalDACContainer)
 {   
-	for ( auto cFe : *(fDetectorContainer->at(boardIndex)) )
+	for ( auto cOpticalGroup : *(fDetectorContainer->at(boardIndex)) )
 	{
-		for ( auto cChip : *cFe )
+		for ( auto cHybrid : *cOpticalGroup )
 		{
-			std::vector<uint16_t> dacVector ;//= dacList.at(cFe->getModuleId()).at(cChip->getChipId());
-			fReadoutChipInterface->WriteChipAllLocalReg ( static_cast<ReadoutChip*>(cChip), dacName, *globalDACContainer.at(boardIndex)->at(cFe->getIndex())->at(cChip->getIndex()));
+			for ( auto cChip : *cHybrid )
+			{
+				std::vector<uint16_t> dacVector ;//= dacList.at(cHybrid->getModuleId()).at(cChip->getChipId());
+				fReadoutChipInterface->WriteChipAllLocalReg ( static_cast<ReadoutChip*>(cChip), dacName, *globalDACContainer.at(boardIndex)->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex()));
+			}
 		}
 	}
 	return;
@@ -1366,33 +1354,36 @@ void Tool::setAllLocalDacBeBoard(uint16_t boardIndex, const std::string &dacName
 //Set same global DAC for all chips
 void Tool::setSameGlobalDac(const std::string &dacName, const uint16_t dacValue)
 {
-  for (auto& cBoard : fBoardVector)
-    setSameGlobalDacBeBoard(cBoard, dacName, dacValue);
+  for (auto cBoard : *fDetectorContainer)
+    setSameGlobalDacBeBoard(static_cast<BeBoard*>(cBoard), dacName, dacValue);
 }
 
 //Set same global DAC for all chips in the BeBoard
 void Tool::setSameGlobalDacBeBoard(BeBoard* pBoard, const std::string &dacName, const uint16_t dacValue)
 {
-  if (fDoBoardBroadcast == false)
-    {
-      for (auto cFe : pBoard->fModuleVector)
-        {
-          if (fDoModuleBroadcast == false)
-            for (auto cChip : cFe->fReadoutChipVector)
-              fReadoutChipInterface->WriteChipReg(cChip, dacName, dacValue);
-          else fReadoutChipInterface->WriteModuleBroadcastChipReg(cFe, dacName, dacValue);
-        }
-    }
-  else fReadoutChipInterface->WriteBoardBroadcastChipReg(pBoard, dacName, dacValue);
+	if (fDoBoardBroadcast == false)
+	{
+        for(auto cOpticalGroup : *pBoard)
+		{
+			for (auto cHybrid : *cOpticalGroup)
+			{
+				if (fDoModuleBroadcast == false)
+				for (auto cChip : *cHybrid)
+					fReadoutChipInterface->WriteChipReg(static_cast<ReadoutChip*>(cChip), dacName, dacValue);
+				else fReadoutChipInterface->WriteModuleBroadcastChipReg(static_cast<Module*>(cHybrid), dacName, dacValue);
+			}
+		}
+	}
+	else fReadoutChipInterface->WriteBoardBroadcastChipReg(pBoard, dacName, dacValue);
 }
 
 // set same local dac for all BeBoard
 void Tool::setSameLocalDac(const std::string &dacName, const uint16_t dacValue)
 {
 
-	for (auto& cBoard : fBoardVector)
+	for (auto cBoard : *fDetectorContainer)
 	{
-		setSameLocalDacBeBoard(cBoard, dacName, dacValue);
+		setSameLocalDacBeBoard(static_cast<BeBoard*>(cBoard), dacName, dacValue);
 	}
 
 	return;
@@ -1402,15 +1393,19 @@ void Tool::setSameLocalDac(const std::string &dacName, const uint16_t dacValue)
 // set same local dac per BeBoard
 void Tool::setSameLocalDacBeBoard(BeBoard* pBoard, const std::string &dacName, const uint16_t dacValue)
 {
-	for ( auto cFe : pBoard->fModuleVector )
-	{
-		for ( auto cChip : cFe->fReadoutChipVector )
+	for(auto cOpticalGroup : *pBoard)
+    {
+		for ( auto cHybrid : *cOpticalGroup )
 		{
-			ChannelContainer<uint16_t>* dacVector = new ChannelContainer<uint16_t>(cChip->getNumberOfChannels(),dacValue);
-			ChipContainer theChipContainer(cChip->getIndex(),cChip->getNumberOfRows(),cChip->getNumberOfCols());
-			theChipContainer.setChannelContainer(dacVector);
+			for ( auto cChip : *cHybrid )
+			{
+				ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+				ChannelContainer<uint16_t>* dacVector = new ChannelContainer<uint16_t>(theChip->getNumberOfChannels(),dacValue);
+				ChipContainer theChipContainer(cChip->getIndex(),cChip->getNumberOfRows(),cChip->getNumberOfCols());
+				theChipContainer.setChannelContainer(dacVector);
 
-			fReadoutChipInterface->WriteChipAllLocalReg ( cChip, dacName, theChipContainer);
+				fReadoutChipInterface->WriteChipAllLocalReg ( theChip, dacName, theChipContainer);
+			}
 		}
 	}
 	return;
@@ -1419,7 +1414,7 @@ void Tool::setSameLocalDacBeBoard(BeBoard* pBoard, const std::string &dacName, c
 void Tool::setSameDacBeBoard(BeBoard* pBoard, const std::string &dacName, const uint16_t dacValue)
 {
 	//Assumption: 1 BeBoard has only 1 chip flavor:
-	if(pBoard->fModuleVector.at(0)->fReadoutChipVector.at(0)->isDACLocal(dacName))
+	if(static_cast<ReadoutChip*>(pBoard->at(0)->at(0)->at(0))->isDACLocal(dacName))
 	{
 		setSameLocalDacBeBoard(pBoard, dacName, dacValue);
 	}
@@ -1432,9 +1427,9 @@ void Tool::setSameDacBeBoard(BeBoard* pBoard, const std::string &dacName, const
 void Tool::setSameDac(const std::string &dacName, const uint16_t dacValue)
 {
 
-	for (auto& cBoard : fBoardVector)
+	for (auto cBoard : *fDetectorContainer)
 	{
-		setSameDacBeBoard(cBoard, dacName, dacValue);
+		setSameDacBeBoard(static_cast<BeBoard*>(cBoard), dacName, dacValue);
 	}
 
 	return;
diff --git a/tools/Tool.h b/tools/Tool.h
index 9184d30fd..c939e2cf4 100644
--- a/tools/Tool.h
+++ b/tools/Tool.h
@@ -49,9 +49,9 @@ class Tool : public Ph2_System::SystemController
 {
 
     #ifdef __USE_ROOT__
-        using ChipHistogramMap = std::map<Ph2_HwDescription::Chip*, std::map<std::string, TObject*> >;
-        using ModuleHistogramMap = std::map<Ph2_HwDescription::Module*, std::map<std::string, TObject*> >;
-        using BeBoardHistogramMap = std::map<Ph2_HwDescription::BeBoard*, std::map<std::string, TObject*> >;
+        using ChipHistogramMap = std::map<ChipContainer*, std::map<std::string, TObject*> >;
+        using ModuleHistogramMap = std::map<ModuleContainer*, std::map<std::string, TObject*> >;
+        using BeBoardHistogramMap = std::map<BoardContainer*, std::map<std::string, TObject*> >;
         using CanvasMap = std::map<Ph2_HwDescription::FrontEndDescription*, TCanvas*>;
     #endif
 
@@ -82,17 +82,17 @@ class Tool : public Ph2_System::SystemController
     void SoftDestroy  ();
 
     #ifdef __USE_ROOT__
-        void bookHistogram ( Ph2_HwDescription::Chip* pChip, std::string pName, TObject* pObject );
+        void bookHistogram ( ChipContainer* pChip, std::string pName, TObject* pObject );
 
-        void bookHistogram ( Ph2_HwDescription::Module* pModule, std::string pName, TObject* pObject );
+        void bookHistogram ( ModuleContainer* pModule, std::string pName, TObject* pObject );
 
-        void bookHistogram ( Ph2_HwDescription::BeBoard* pBeBoard, std::string pName, TObject* pObject );
+        void bookHistogram ( BoardContainer* pBeBoard, std::string pName, TObject* pObject );
 
-        TObject* getHist ( Ph2_HwDescription::Chip* pChip, std::string pName );
+        TObject* getHist ( ChipContainer* pChip, std::string pName );
 
-        TObject* getHist ( Ph2_HwDescription::Module* pModule, std::string pName );
+        TObject* getHist ( ModuleContainer* pModule, std::string pName );
         
-        TObject* getHist ( Ph2_HwDescription::BeBoard* pBeBoard, std::string pName );
+        TObject* getHist ( BoardContainer* pBeBoard, std::string pName );
 
         void WriteRootFile();
     #endif
-- 
GitLab


From c1e9add57ebf47cf5312d6b3558b0bc81df84c0d Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 20:17:26 -0500
Subject: [PATCH 5/9] Solving compiler errors

---
 src/CMSITminiDAQ.cc      |   2 +-
 src/DAQWS.cc             |  30 +++--
 src/InjectedSCurve.cc    |  67 ++++++----
 src/MPA_sync_test.cc     |  10 +-
 src/NoiseSCurve.cc       |  24 ++--
 src/Pedagogical.cc       |  30 +++--
 src/SSALatencyScanner.cc |  40 +++---
 src/TwoStripAlignment.cc |  37 +++---
 src/d19c_test.cc         |  27 ++--
 src/datatest.cc          |   2 +-
 tools/AntennaTester.cc   |  10 +-
 tools/BiasSweep.cc       |  22 ++--
 tools/BiasSweep.h        |  11 +-
 tools/CMTester.cc        |  33 ++---
 tools/CMTester.h         |   4 +-
 tools/CicFEAlignment.cc  |  21 ++-
 tools/DataChecker.cc     | 115 +++++-----------
 tools/ExtraChecks.cc     | 276 ++++++++++++++++++---------------------
 tools/HybridTester.cc    |   3 +-
 tools/LatencyScan.cc     |  12 +-
 tools/LatencyScan.h      |   4 +-
 tools/PulseShape.cc      |  14 +-
 tools/SignalScanFit.cc   |   7 +-
 tools/StubSweep.cc       |   4 +-
 tools/StubSweep.h        |   4 +-
 tools/Tool.cc            |   4 +-
 tools/Tool.h             |   2 +-
 27 files changed, 390 insertions(+), 425 deletions(-)

diff --git a/src/CMSITminiDAQ.cc b/src/CMSITminiDAQ.cc
index ef8d3afdf..4bcad3138 100644
--- a/src/CMSITminiDAQ.cc
+++ b/src/CMSITminiDAQ.cc
@@ -298,7 +298,7 @@ int main (int argc, char** argv)
           mySysCntr.InitializeSettings(configFile, outp);
           if (reset == true)
             {
-              static_cast<RD53FWInterface*>(mySysCntr.fBeBoardFWMap[mySysCntr.fBoardVector[0]->getBeBoardId()])->ResetSequence();
+              static_cast<RD53FWInterface*>(mySysCntr.fBeBoardFWMap[static_cast<BeBoard*>(mySysCntr.fDetectorContainer->at(0))->getBeBoardId()])->ResetSequence();
               exit(EXIT_SUCCESS);
             }
           if (binaryFile != "") readBinaryData(binaryFile, mySysCntr, RD53FWInterface::decodedEvents);
diff --git a/src/DAQWS.cc b/src/DAQWS.cc
index b3845262b..5e08a4c66 100644
--- a/src/DAQWS.cc
+++ b/src/DAQWS.cc
@@ -46,34 +46,36 @@ int main( int argc, char* argv[] )
 	IB->ReadPower_SSA();
 	cTool.ConfigureHw();
 	
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	cTool.setFWTestPulse();
 	TH1I *h1 = new TH1I("h1", "S-CURVE", 256, 0, 256);
 	for (int thd = 0; thd<=256; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA : *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 30);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x1); // sync mode = 0
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "FE_Calibration", 1);
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 30);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x1); // sync mode = 0
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "FE_Calibration", 1);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				//cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 31);
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 5); // 17 = 10001 (enable strobe)
+				//cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 31);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 5); // 17 = 10001 (enable strobe)
 			}
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "L1-Latency_LSB", 0x44);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "L1-Latency_MSB", 0x0);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "L1-Latency_LSB", 0x44);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "L1-Latency_MSB", 0x0);
 		}
 		
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S18");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S18");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S18");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S18");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
diff --git a/src/InjectedSCurve.cc b/src/InjectedSCurve.cc
index 306667882..bcbb6162d 100644
--- a/src/InjectedSCurve.cc
+++ b/src/InjectedSCurve.cc
@@ -47,42 +47,45 @@ int main( int argc, char* argv[] )
 	D19cFWInterface* IB = dynamic_cast<D19cFWInterface*>(cTool.fBeBoardFWMap.find(0)->second); // There has to be a better way!
 
 	cTool.setFWTestPulse(); // turns on injections (in either mode)
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	TH1I *h1 = new TH1I("h1", "S-CURVE (trim 15);THDAC;number of hits", 80, 20, 100);
 	TH1I *h2 = new TH1I("h2", "S-CURVE (trim 20);THDAC;number of hits", 80, 20, 100);
 	TH1I *h3 = new TH1I("h3", "S-CURVE (trim 25);THDAC;number of hits", 80, 20, 100);
 	TH1I *h4 = new TH1I("h4", "S-CURVE (trim 30);THDAC;number of hits", 80, 20, 100);
 	for (int thd = 20; thd<=75; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 35);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x1); // sync mode = 0
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
-			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(cSSA, "Bias_THDAC");
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "FE_Calibration", 1);
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 35);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x1); // sync mode = 0
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
+			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(theSSA, "Bias_THDAC");
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "FE_Calibration", 1);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
 			}
 		}
 		// 15
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 15);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 15);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
@@ -91,21 +94,23 @@ int main( int argc, char* argv[] )
 
 
 		// 20
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 20);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 20);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
@@ -114,21 +119,23 @@ int main( int argc, char* argv[] )
 
 
 		// 25
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 25);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 25);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
@@ -137,21 +144,23 @@ int main( int argc, char* argv[] )
 
 
 		// 30
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 30);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 30);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
diff --git a/src/MPA_sync_test.cc b/src/MPA_sync_test.cc
index 53634bcdf..24cdf062c 100755
--- a/src/MPA_sync_test.cc
+++ b/src/MPA_sync_test.cc
@@ -48,11 +48,13 @@ int main( int argc, char* argv[] )
 	MPA* mpa1 = new MPA(0, 0, 0, 0,"settings/MPAFiles/MPA_default.txt");
 
 	mpa1->loadfRegMap("settings/MPAFiles/MPA_default.txt");
-	BeBoard* pBoard = mysyscontroller.fBoardVector.at( 0 );
+	BeBoard* pBoard = static_cast<BeBoard*>(mysyscontroller.fDetectorContainer->at(0));
 
-	OuterTrackerModule* MPAM = new OuterTrackerModule();
-	MPAM->addMPA(mpa1);
-	pBoard->addModule(MPAM);
+	// OuterTrackerModule* MPAM = new OuterTrackerModule();
+	// OpticalGroup* theOpticalGroup = new OpticalGroup();
+	// MPAM->emplace_back(mpa1);
+	// theOpticalGroup->emplace_back(MPAM);
+	// pBoard->emplace_back(theOpticalGroup);
 
 	std::chrono::milliseconds LongPOWait( 500 );
 	std::chrono::milliseconds ShortWait( 10 );
diff --git a/src/NoiseSCurve.cc b/src/NoiseSCurve.cc
index 42fb7a614..de1fbb832 100644
--- a/src/NoiseSCurve.cc
+++ b/src/NoiseSCurve.cc
@@ -46,20 +46,21 @@ int main( int argc, char* argv[] )
 	cTool.ConfigureHw();
 	D19cFWInterface* IB = dynamic_cast<D19cFWInterface*>(cTool.fBeBoardFWMap.find(0)->second); // There has to be a better way!
 
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	TH1I *h1 = new TH1I("h1", "S-CURVE;THDAC;number of hits", 100, 0, 100);
 	for (int thd = 0; thd<=75; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x1); // sync mode = 0
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
-			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(cSSA, "Bias_THDAC");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x1); // sync mode = 0
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
+			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(theSSA, "Bias_THDAC");
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 15);
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 5); // 17 = 10001 (enable strobe)
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 15);
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 5); // 17 = 10001 (enable strobe)
 			}
 		}
 		
@@ -67,10 +68,11 @@ int main( int argc, char* argv[] )
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP = (cRP2*256) + cRP1; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP << RESET;
diff --git a/src/Pedagogical.cc b/src/Pedagogical.cc
index fa9c7af3c..252a4de84 100644
--- a/src/Pedagogical.cc
+++ b/src/Pedagogical.cc
@@ -48,31 +48,33 @@ int main( int argc, char* argv[] )
 	//IB->PSInterfaceBoard_PowerOff_SSA();
 	cTool.ConfigureHw();
 	
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	TH2I *strip_v_thdac_31 = new TH2I("strip_v_thdac_31", "All TRIMDACs = 31;strip # ; THDAC (lsb)", 360, -60, 300, 25, 0, 25);
 	strip_v_thdac_31->SetStats(0);
-	for(auto cSSA: ChipVec)
+	for(auto cSSA: *ChipVec)
 	{
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x0); // sync mode = 0
+		ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x0); // sync mode = 0
 		for (int i = 1; i<=120;i++ ) // loop over all strips
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 31); // MAXIMIZE THE TRIM
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 1); // ENABLE THE STRIP
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 31); // MAXIMIZE THE TRIM
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 1); // ENABLE THE STRIP
 		}
 	}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S100", 0x1);}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S101", 0x1);}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S102", 0x1);}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S103", 0x1);}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S104", 0x1);}
-	// for(auto cSSA: ChipVec){cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S105", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S100", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S101", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S102", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S103", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S104", 0x1);}
+	// for(auto cSSA: *ChipVec){ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA); cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S105", 0x1);}
 	for (int thd = 10; thd<=20; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			std::cout<<"Setting threshold to " << thd << std::endl;
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
 		}
 	cTool.ReadNEvents(pBoard, 1);
 	const std::vector<Event*> &eventVector = cTool.GetEvents(pBoard);
diff --git a/src/SSALatencyScanner.cc b/src/SSALatencyScanner.cc
index 61eeed32e..366f298d3 100644
--- a/src/SSALatencyScanner.cc
+++ b/src/SSALatencyScanner.cc
@@ -45,32 +45,34 @@ int main( int argc, char* argv[] )
 	IB->ReadPower_SSA();
 	cTool.ConfigureHw();
 
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	cTool.setFWTestPulse();
 	cTool.setSystemTestPulse (200, 0, true, false);
 	TH1I *h1 = new TH1I("h1", ";Latency (lsb)", 256, 0, 256);
 
-	for(auto cSSA: ChipVec)
+	for(auto cSSA: *ChipVec)
 	{
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 100);
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x0); // sync mode = 0
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", 50);
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "FE_Calibration", 1);
+		ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 100);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x0); // sync mode = 0
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", 50);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "FE_Calibration", 1);
 		for (int i = 1; i<=120;i++ ) // loop over all strips
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 0);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 17); // 17 = 10001 (enable strobe)
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 0);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 17); // 17 = 10001 (enable strobe)
 		}
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "L1-Latency_MSB", 0x0);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "L1-Latency_MSB", 0x0);
 	}
 	int count_max = 0;
 	int BestLat = 0;
 	for (int lat = 0; lat<=255; lat++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "L1-Latency_LSB", lat);
+		ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "L1-Latency_LSB", lat);
 		}
 		cTool.ReadNEvents(pBoard, 50);
 		int thiscount = 0;
@@ -98,20 +100,22 @@ int main( int argc, char* argv[] )
 	h1->Draw("hist");
 	c1->Print("LATENCY_SCAN.png");
 	LOG (INFO) << BOLDRED << "THE LATENCY IS: " << BestLat << RESET;
-	for(auto cSSA: ChipVec)
+	for(auto cSSA: *ChipVec)
 	{
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "L1-Latency_LSB", BestLat);
-		cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 60);
+		ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "L1-Latency_LSB", BestLat);
+		cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 60);
 	}
 	TH1I *h2 = new TH1I("h2", "S-CURVE STRIP #7;THDAC (lsb)", 256, 0, 256);
 	for (int thd = 0; thd<=255; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
+		ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				if (i != 7)	cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 0);
+				if (i != 7)	cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 0);
 			}
 		}
 		cTool.ReadNEvents(pBoard, 100);
diff --git a/src/TwoStripAlignment.cc b/src/TwoStripAlignment.cc
index a723496cb..365bf90a8 100644
--- a/src/TwoStripAlignment.cc
+++ b/src/TwoStripAlignment.cc
@@ -47,49 +47,52 @@ int main( int argc, char* argv[] )
 	D19cFWInterface* IB = dynamic_cast<D19cFWInterface*>(cTool.fBeBoardFWMap.find(0)->second); // There has to be a better way!
 
 	cTool.setFWTestPulse(); // turns on injections (in either mode)
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	TH1I *h1 = new TH1I("h1", "S-CURVE (strip 12);THDAC;number of hits", 80, 20, 100);
 	TH1I *h2 = new TH1I("h2", "S-CURVE (strip 88);THDAC;number of hits", 80, 20, 100);
 	for (int thd = 20; thd<=75; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 35);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x1); // sync mode = 0
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
-			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(cSSA, "Bias_THDAC");
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "FE_Calibration", 1);
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 35);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x1); // sync mode = 0
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
+			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(theSSA, "Bias_THDAC");
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "FE_Calibration", 1);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
 			}
 		}
 		// 15
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				if (i != 88) cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 10);
-				else cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 31);
+				if (i != 88) cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 10);
+				else cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 31);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1_12 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2_12 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1_12 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2_12 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP_12 = (cRP2_12*256) + cRP1_12; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP_12 << RESET;
 			h1->Fill(thd, cRP_12);
 
 
-			uint8_t cRP1_88 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S88");
-			uint8_t cRP2_88 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S88");
+			uint8_t cRP1_88 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S88");
+			uint8_t cRP2_88 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S88");
 			uint16_t cRP_88 = (cRP2_88*256) + cRP1_88; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP_88 << RESET;
diff --git a/src/d19c_test.cc b/src/d19c_test.cc
index d385a5d0a..f822ae6fd 100644
--- a/src/d19c_test.cc
+++ b/src/d19c_test.cc
@@ -109,7 +109,7 @@ int main ( int argc, char** argv )
         }while(cIter < 100);
     #endif
 
-    BeBoard* pBoard = cTool.fBoardVector.at(0);
+    BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at ( 0 ));
     cTool.fBeBoardInterface->getBoardInfo(pBoard);
 
     bool cTestPulse = ( cmd.foundOption ( "testpulse" ) ) ? true : false;
@@ -163,7 +163,7 @@ int main ( int argc, char** argv )
 
 
             // be careful works only for one hybrid
-            std::vector < ReadoutChip* > &cCbcVector = pBoard->getModule(0)->fReadoutChipVector;
+            ModuleContainer* cCbcVector = pBoard->at(0)->at(0);
             /*for( auto cCbc : cCbcVector )
             {
                 static_cast<CbcInterface*>(cTool.fReadoutChipInterface)->enableHipSuppression( cCbc, false, true,0);
@@ -171,7 +171,7 @@ int main ( int argc, char** argv )
                 std::vector<int>     cBends_ph1( 2, static_cast<int>(1*2) ); 
                 static_cast<CbcInterface*>(cTool.fReadoutChipInterface)->injectStubs( cCbc , cSeeds_ph1 , cBends_ph1);
             }*/
-            uint32_t cNCbc = cCbcVector.size();
+            uint32_t cNCbc = cCbcVector->size();
 
             Timer t;
             t.start();
@@ -187,7 +187,7 @@ int main ( int argc, char** argv )
                     cN++;
 
                     double cAvgOccupancyHyb0 = 0;
-                    for(auto cCbc: cCbcVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cCbc->getChipId());
+                    for(auto cCbc: *cCbcVector) cAvgOccupancyHyb0 += ev->GetNHits(0,cCbc->getId());
                     cAvgOccupancy += (cAvgOccupancyHyb0/cNCbc);
 
                     if ( cmd.foundOption ( "dqm" ) )
@@ -247,7 +247,7 @@ int main ( int argc, char** argv )
             // init threshold visitior
             ThresholdVisitor cThresholdVisitor (cTool.fReadoutChipInterface, 0);
             cTool.accept (cThresholdVisitor);
-            auto cFe0 = pBoard->fModuleVector.at(0);
+            auto cFe0 = pBoard->at(0)->at(0);
 
             // hybrid mask
             uint32_t cHybridMask = ( cmd.foundOption ( "mask" ) ) ? convertAnyInt ( cmd.optionValue ( "mask" ).c_str() ) : 0xFFFFFFFF;;
@@ -285,9 +285,9 @@ int main ( int argc, char** argv )
                 for (uint32_t cThreshold = cThresholdMin; cThreshold < cThresholdMax; cThreshold++) {
 
                     // set threshold
-                    for(auto& cCbc : cFe0->fReadoutChipVector) {
+                    for(auto cCbc : *cFe0) {
                         cThresholdVisitor.setThreshold(cThreshold);
-                        cCbc->accept(cThresholdVisitor);
+                        static_cast<ReadoutChip*>(cCbc)->accept(cThresholdVisitor);
                     }
 
                     // measure (equvuvalient tasks)
@@ -297,11 +297,14 @@ int main ( int argc, char** argv )
                         cTool.ReadNEvents( pBoard, cNEventsToCollect );
                         const std::vector<Event*>& events = cTool.GetEvents ( pBoard );
                         for ( auto& ev : events ) {
-                            for(auto& cFe : pBoard->fModuleVector) {
-                                for(auto& cCbc : cFe->fReadoutChipVector) {
-                                    for(uint8_t ch = 0; ch < NCHANNELS; ch++) {
-                                        if (ev->DataBit(cFe->getFeId(), cCbc->getChipId(), ch))
-                                            cChannelCounters[cFe->getFeId()][cCbc->getChipId()][ch]++;
+                            for(auto cOpticalGroup : *pBoard)
+                            {
+                                for(auto& cFe : *cOpticalGroup) {
+                                    for(auto& cCbc : *cFe) {
+                                        for(uint8_t ch = 0; ch < NCHANNELS; ch++) {
+                                            if (ev->DataBit(cFe->getId(), cCbc->getId(), ch))
+                                                cChannelCounters[cFe->getId()][cCbc->getId()][ch]++;
+                                        }
                                     }
                                 }
                             }
diff --git a/src/datatest.cc b/src/datatest.cc
index 6d9514cb8..4c4c516e4 100644
--- a/src/datatest.cc
+++ b/src/datatest.cc
@@ -148,7 +148,7 @@ int main ( int argc, char* argv[] )
         t.show ( "Time for changing VCth on all CBCs:" );
     }
 
-    BeBoard* pBoard = cSystemController.fBoardVector.at ( 0 );
+    BeBoard* pBoard = static_cast<BeBoard*>(cSystemController.fDetectorContainer->at ( 0 ));
     t.start();
     // make event counter start at 1 as does the L1A counter
     uint32_t cN = 1;
diff --git a/tools/AntennaTester.cc b/tools/AntennaTester.cc
index b3645c62f..93180cd5c 100644
--- a/tools/AntennaTester.cc
+++ b/tools/AntennaTester.cc
@@ -118,7 +118,7 @@ void AntennaTester::InitialiseSettings()
     for (auto cBoard : *fDetectorContainer)
     {
 
-        BeBoard *theBoard = static_cast<BeBoard*>(cBoard)
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
         trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
          LOG (INFO)  <<int (trigSource);
     }
@@ -187,7 +187,7 @@ void AntennaTester::ReconfigureCBCRegisters (std::string pDirectoryName )
 {
     for (auto cBoard : *fDetectorContainer)
     {
-        BeBoard *theBoard = static_cast<BeBoard*>(cBoard)
+        BeBoard *theBoard = static_cast<BeBoard*>(cBoard);
         fBeBoardInterface->ChipReset ( theBoard );
 
         trigSource = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.fast_command_block.trigger_source" );
@@ -202,7 +202,7 @@ void AntennaTester::ReconfigureCBCRegisters (std::string pDirectoryName )
             {
                 for (auto cCbc : *cHybrid)
                 {
-                    Cbc* theCBC = static_cast<Cbc*>(cCbc);
+                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
                     std::string pRegFile ;
                     char buffer[120];
 
@@ -212,8 +212,8 @@ void AntennaTester::ReconfigureCBCRegisters (std::string pDirectoryName )
                         sprintf (buffer, "%s/FE%dCBC%d.txt", pDirectoryName.c_str(), cHybrid->getId(), cCbc->getId() );
 
                     pRegFile = buffer;
-                    Cbc->loadfRegMap (pRegFile);
-                    fReadoutChipInterface->ConfigureChip ( Cbc );
+                    theCbc->loadfRegMap (pRegFile);
+                    fReadoutChipInterface->ConfigureChip ( theCbc );
                     LOG (INFO)  << GREEN << "\t\t Successfully reconfigured CBC" << int ( cCbc->getId() ) << "'s regsiters from " << pRegFile << " ." << RESET;
                 }
             }
diff --git a/tools/BiasSweep.cc b/tools/BiasSweep.cc
index f03421f26..4b4554036 100644
--- a/tools/BiasSweep.cc
+++ b/tools/BiasSweep.cc
@@ -1,5 +1,5 @@
 #include "BiasSweep.h"
-#ifdef __USE_ROOT__
+// #ifdef __USE_ROOT__
 
 void BiasSweep::InitializeAmuxMap()
 {
@@ -160,7 +160,7 @@ void BiasSweep::Initialize()
     this->InitializeAmuxMap();
 }
 
-void BiasSweep::MeasureMinPower (BeBoard* pBoard, Chip* pCbc)
+void BiasSweep::MeasureMinPower (BeBoard* pBoard, ReadoutChip* pCbc)
 {
     LOG (INFO) << std::endl;
     LOG (INFO) << BOLDBLUE << "*****************************************" << RESET;
@@ -260,7 +260,7 @@ void BiasSweep::MeasureMinPower (BeBoard* pBoard, Chip* pCbc)
     LOG (INFO) << "Finished measuring minimal power consumption, results saved!";
 }
 
-void BiasSweep::SweepBias (std::string pBias, Chip* pCbc)
+void BiasSweep::SweepBias (std::string pBias, ReadoutChip* pCbc)
 {
     auto cAmuxValue = fAmuxSettings.find (pBias);
 
@@ -712,12 +712,12 @@ void BiasSweep::DAQloop()
     //while (fDAQrunning.load() )
     //{
     //std::unique_lock<std::mutex> cLock (fHWMutex);
-    //this->ReadData (fBoardVector.at (0) );
+    //this->ReadData (static_cast<BeBoard*>(fDetectorContainer->at(0)));
     //cLock.unlock();
 
     //if (!fDAQrunning.load() )
     //{
-    //this->Stop (fBoardVector.at (0) );
+    //this->Stop (static_cast<BeBoard*>(fDetectorContainer->at(0)));
     //break;
     //}
     //else
@@ -728,14 +728,14 @@ void BiasSweep::DAQloop()
 void BiasSweep::StartDAQ()
 {
     //1st method
-    this->fBeBoardInterface->WriteBoardReg (fBoardVector.at (0), "cbc_system_cnfg.global.misc.trigger_master_external", 0x1);
-    this->Start (fBoardVector.at (0) );
+    this->fBeBoardInterface->WriteBoardReg (static_cast<BeBoard*>(fDetectorContainer->at(0)), "cbc_system_cnfg.global.misc.trigger_master_external", 0x1);
+    this->Start (static_cast<BeBoard*>(fDetectorContainer->at(0)));
 
     //2nd method
     //if (!fDAQrunning.load() )
     //{
     //std::unique_lock<std::mutex> cLock (fHWMutex);
-    //this->Start (fBoardVector.at (0) );
+    //this->Start (static_cast<BeBoard*>(fDetectorContainer->at(0)));
     //fDAQrunning = true;
     //cLock.unlock();
     //fThread = std::thread (&BiasSweep::DAQloop, this);
@@ -745,8 +745,8 @@ void BiasSweep::StartDAQ()
 void BiasSweep::StopDAQ()
 {
     //1st method
-    this->Stop (fBoardVector.at (0) );
-    this->fBeBoardInterface->WriteBoardReg (fBoardVector.at (0), "cbc_system_cnfg.global.misc.trigger_master_external", 0x0);
+    this->Stop (static_cast<BeBoard*>(fDetectorContainer->at(0)));
+    this->fBeBoardInterface->WriteBoardReg (static_cast<BeBoard*>(fDetectorContainer->at(0)), "cbc_system_cnfg.global.misc.trigger_master_external", 0x0);
 
     //2nd method
     //if (fDAQrunning.load() )
@@ -760,4 +760,4 @@ void BiasSweep::StopDAQ()
     //}
 }
 
-#endif
\ No newline at end of file
+// #endif
\ No newline at end of file
diff --git a/tools/BiasSweep.h b/tools/BiasSweep.h
index 9ec4ea9a0..0355ba122 100644
--- a/tools/BiasSweep.h
+++ b/tools/BiasSweep.h
@@ -13,7 +13,7 @@
 #ifndef __BIASSWEEP_H__
 #define __BIASSWEEP_H__
 
-#ifdef __USE_ROOT__
+// #ifdef __USE_ROOT__
 
 #include "Tool.h"
 #include <map>
@@ -24,6 +24,9 @@
 #include "TObject.h"
 #include "TAxis.h"
 #include "TTree.h"
+#include "../HWDescription/ReadoutChip.h"
+#include "../Utils/Container.h"
+#include "../Utils/DataContainer.h"
 #include "TString.h"
 #include "../Utils/CommonVisitors.h"
 
@@ -85,8 +88,8 @@ class BiasSweep : public Tool
     ~BiasSweep();
     void Initialize();
     // *******
-    void SweepBias (std::string pBias, Ph2_HwDescription::Chip* pCbc);
-    void MeasureMinPower (Ph2_HwDescription::BeBoard* pBoard, Ph2_HwDescription::Chip* pCbc);
+    void SweepBias (std::string pBias, Ph2_HwDescription::ReadoutChip* pCbc);
+    void MeasureMinPower (Ph2_HwDescription::BeBoard* pBoard, Ph2_HwDescription::ReadoutChip* pCbc);
 
 
 
@@ -128,4 +131,4 @@ class BiasSweep : public Tool
 
 
 #endif
-#endif
+// #endif
diff --git a/tools/CMTester.cc b/tools/CMTester.cc
index e09a7658d..76a4892eb 100644
--- a/tools/CMTester.cc
+++ b/tools/CMTester.cc
@@ -145,7 +145,7 @@ void CMTester::Initialize()
                 }
 
                 // PER MODULE PLOTS
-                uint32_t cNCbc = cFe->getNChip();
+                uint32_t cNCbc = cHybrid->size();
 
                 // 2D profile for the combined odccupancy
                 TString cName =  Form ( "p_module_combinedoccupancy_Fe%d", cHybridId ) ;
@@ -154,7 +154,7 @@ void CMTester::Initialize()
                 if ( cObj ) delete cObj;
 
                 TProfile2D* c2DProfile = new TProfile2D ( cName, Form ( "Combined Occupancy FE%d; Strip; Strip; Occupancy", cHybridId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-                bookHistogram ( cFe, "module_combinedoccupancy", c2DProfile );
+                bookHistogram ( cHybrid, "module_combinedoccupancy", c2DProfile );
 
                 // 2D Hist for correlation coefficient
                 cName =  Form ( "p_module_correlation_Fe%d", cHybridId );
@@ -163,7 +163,7 @@ void CMTester::Initialize()
                 if ( cObj ) delete cObj;
 
                 TH2F* c2DHist = new TH2F ( cName, Form ( "Correlation FE%d; Strip; Strip; Correlation coefficient", cHybridId  ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5, cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
-                bookHistogram ( cFe, "module_correlation", c2DHist );
+                bookHistogram ( cHybrid, "module_correlation", c2DHist );
 
                 // 1D projection of the combined odccupancy
                 cName =  Form ( "p_module_occupancyprojection_Fe%d", cHybridId );
@@ -174,7 +174,7 @@ void CMTester::Initialize()
                 TProfile* cProfile = new TProfile ( cName, Form ( "Projection of combined Occupancy FE%d;  NNeighbors; Probability", cHybridId ), cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
                 cProfile->SetLineColor ( 9 );
                 cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cFe, "module_occupancyprojection", cProfile );
+                bookHistogram ( cHybrid, "module_occupancyprojection", cProfile );
 
                 // 1D projection of the uncorrelated occupancy
                 cName = Form ( "p_module_uncorr_occupancyprojection_Fe%d", cHybridId );
@@ -185,7 +185,7 @@ void CMTester::Initialize()
                 cProfile = new TProfile ( cName, Form ( "Projection of uncorrelated Occupancy FE%d;  NNeighbors; Probability", cHybridId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
                 cProfile->SetLineColor ( 2 );
                 cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cFe, "module_uncorr_occupancyprojection", cProfile );
+                bookHistogram ( cHybrid, "module_uncorr_occupancyprojection", cProfile );
 
                 // 1D projection of the correlation
                 cName =  Form ( "p_module_correlationprojection_Fe%d", cHybridId );
@@ -196,7 +196,7 @@ void CMTester::Initialize()
                 cProfile = new TProfile ( cName, Form ( "Projection of Correlation FE%d;  NNeighbors; Correlation", cHybridId ),  cNCbc * NCHANNELS + 1, -.5, cNCbc * NCHANNELS + 0.5 );
                 cProfile->SetLineColor ( 9 );
                 cProfile->SetLineWidth ( 2 );
-                bookHistogram ( cFe, "module_correlationprojection", cProfile );
+                bookHistogram ( cHybrid, "module_correlationprojection", cProfile );
             }
         }
     }
@@ -249,6 +249,7 @@ void CMTester::ScanNoiseChannels()
                         }
                     }
                 }
+            }
 
             if ( cN % 100 == 0 )
                 // updateHists();
@@ -369,7 +370,7 @@ void CMTester::FinishRun()
     int iCbc = 0;
     for ( auto cCbc : fChipHistMap )
     {
-        cCbc.first->accept (cVisitor);
+        static_cast<ReadoutChip*>(cCbc.first)->accept (cVisitor);
         uint32_t cVcth = cVisitor.getThreshold();
 
         TH1F* cTmpNHits = dynamic_cast<TH1F*> ( getHist ( cCbc.first, "nhits" ) );
@@ -387,9 +388,9 @@ void CMTester::FinishRun()
 	float CMnoiseFrac = fabs ( cNHitsFit->GetParameter ( 1 ) );
 	float CMnoiseFracErr = fabs ( cNHitsFit->GetParError ( 1 ) );
 	if (fTotalNoise[iCbc]>0) 
-	    LOG (INFO) << BOLDRED << "Average noise on FE " << +cCbc.cHybrid->getId() << " CBC " << +cCbc.first->getId() << " : " << fTotalNoise[iCbc] << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%, so "<<CMnoiseFrac*fTotalNoise[iCbc]<<" VCth." << RESET ;
+	    LOG (INFO) << BOLDRED << "Average noise on FE " << +static_cast<ReadoutChip*>(cCbc.first)->getFeId() << " CBC " << +cCbc.first->getId() << " : " << fTotalNoise[iCbc] << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%, so "<<CMnoiseFrac*fTotalNoise[iCbc]<<" VCth." << RESET ;
 	else 
-	    LOG (INFO) << BOLDRED << "FE " << +cCbc.cHybrid->getId() << " CBC " << +cCbc.first->getId() << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%" << RESET ;
+	    LOG (INFO) << BOLDRED << "FE " << +static_cast<ReadoutChip*>(cCbc.first)->getFeId() << " CBC " << +cCbc.first->getId() << " . At Vcth " << cVcth << " CM is " << CMnoiseFrac << "+/-" <<  CMnoiseFracErr << "%" << RESET ;
 
 
         // now compute the correlation coefficient and the uncorrelated probability
@@ -428,7 +429,7 @@ void CMTester::FinishRun()
     // now module wise
     for ( auto& cFe : fModuleHistMap )
     {
-        TString cName = Form ( "FE%d", cFe.cHybrid->getId() );
+        TString cName = Form ( "FE%d", cFe.first->getId() );
 
         // get histograms
         TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cFe.first, "module_combinedoccupancy" ) );
@@ -518,11 +519,11 @@ void CMTester::analyze ( BeBoard* pBoard, const Event* pEvent )
                     cModuleData.push_back ( chit );
 
                     //  count hits/event
-                    if ( chit  && !isMasked ( cCbc, cChan ) )
+                    if ( chit  && !isMasked ( static_cast<ReadoutChip*>(cCbc), cChan ) )
                         cNHits++;
 
                     // Fill Single Strip Efficiency
-                    if ( !isMasked ( cCbc, cChan ) ) cTmpHitProb->Fill ( cChan, int ( chit ) );
+                    if ( !isMasked ( static_cast<ReadoutChip*>(cCbc), cChan ) ) cTmpHitProb->Fill ( cChan, int ( chit ) );
 
                     // For combined occupancy 1D projection & 2D profile
                     for ( int cChan2 = 0; cChan2 < 254; cChan2++ )
@@ -536,7 +537,7 @@ void CMTester::analyze ( BeBoard* pBoard, const Event* pEvent )
 
                         if ( chit && chit2 ) cfillValue = 1;
 
-                        if ( !isMasked ( cCbc, cChan ) && !isMasked ( cCbc, cChan2 ) )
+                        if ( !isMasked ( static_cast<ReadoutChip*>(cCbc), cChan ) && !isMasked ( static_cast<ReadoutChip*>(cCbc), cChan2 ) )
                         {
                             // Fill 2D occupancy
                             cTmpOccProfile->Fill ( cChan, cChan2, cfillValue );
@@ -556,8 +557,8 @@ void CMTester::analyze ( BeBoard* pBoard, const Event* pEvent )
             }
 
             // Here deal with per-module Histograms
-            TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cFe,  "module_combinedoccupancy" ) );
-            TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cFe, "module_occupancyprojection" ) );
+            TProfile2D* cTmpOccProfile = dynamic_cast<TProfile2D*> ( getHist ( cHybrid,  "module_combinedoccupancy" ) );
+            TProfile* cTmpCombinedOcc = dynamic_cast<TProfile*> ( getHist ( cHybrid, "module_occupancyprojection" ) );
 
             uint32_t cChanCt1 = 0;
 
@@ -678,7 +679,7 @@ bool CMTester::randHit ( float pProbability )
     else return false;
 }
 
-bool CMTester::isMasked ( Chip* pCbc, int pChannel )
+bool CMTester::isMasked ( ReadoutChip* pCbc, int pChannel )
 {
     auto cNoiseStripSet = fNoiseStripMap.find ( pCbc );
 
diff --git a/tools/CMTester.h b/tools/CMTester.h
index 35c2e85cf..2c392e8d0 100644
--- a/tools/CMTester.h
+++ b/tools/CMTester.h
@@ -63,14 +63,14 @@ class CMTester : public Tool
     void parseSettings();
     void analyze ( Ph2_HwDescription::BeBoard* pBoard, const Ph2_HwInterface::Event* pEvent );
     bool randHit ( float pProbability );
-    bool isMasked ( Ph2_HwDescription::Chip* pCbc, int pChan );
+    bool isMasked ( Ph2_HwDescription::ReadoutChip* pCbc, int pChan );
     bool isMasked ( int pGlobalChannel );
 
     uint32_t fNevents, fDoSimulate, fSimOccupancy;
      std::vector<double> fTotalNoise;
     uint32_t fVcth;
 
-    std::map<Ph2_HwDescription::Chip*, std::set<int> > fNoiseStripMap;
+    std::map<ChipContainer*, std::set<int> > fNoiseStripMap;
 
 };
 
diff --git a/tools/CicFEAlignment.cc b/tools/CicFEAlignment.cc
index eda6d33df..5f0f913f0 100644
--- a/tools/CicFEAlignment.cc
+++ b/tools/CicFEAlignment.cc
@@ -85,9 +85,9 @@ void CicFEAlignment::Initialise ()
         auto& cPhaseAlignmentThisBoard = fPhaseAlignmentValues.at(cBoard->getIndex());
         auto& cWordAlignmentThisBoard = fWordAlignmentValues.at(cBoard->getIndex());
 
-        for(auto cHybrid : *cBoard)
+        for(auto cOpticalGroup : *cBoard)
         {
-            for (auto cHybrid : *cHybrid)
+            for (auto cHybrid : *cOpticalGroup)
             {
                 auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
                 auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
@@ -328,11 +328,11 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
                     //first pattern - stubs lines 0,1,3
                     theCbcInterface->injectStubs( theChip , cSeeds , cBends, false );
                     // switch off HitOr
-                    fReadoutChipInterface->WriteChipReg ( theChip "HitOr", 0);
+                    fReadoutChipInterface->WriteChipReg ( theChip, "HitOr", 0);
                     //enable stub logic
-                    theCbcInterface->selectLogicMode( theChip "Sampled", true, true); 
+                    theCbcInterface->selectLogicMode( theChip, "Sampled", true, true); 
                     // set pT cut to maximum 
-                    fReadoutChipInterface->WriteChipReg( theChip "PtCut", 14); 
+                    fReadoutChipInterface->WriteChipReg( theChip, "PtCut", 14); 
                 }
                 // configure Bx0 alignment patterns in CIC 
                 if( theOuterTrackerHybrid->fCic != NULL ) 
@@ -445,10 +445,10 @@ bool CicFEAlignment::Bx0Alignment(uint8_t pFe, uint8_t pLine , uint16_t pDelay,
         {
             for (auto cHybrid : *cOpticalGroup)
             {
-                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-                auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cFe->getIndex());
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cHybrid->getIndex());
+                auto& cPtCutThisHybrid = cPtCutThisBoard->at(cHybrid->getIndex());
                 static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
                 //configure CBCs 
                 for (auto cChip : *cHybrid)
@@ -588,7 +588,6 @@ bool CicFEAlignment::PhaseAlignment(uint16_t pWait_ms)
                     cPhaseTapsFEs = this->SortOptimalTaps( cPhaseTaps ); 
                     for (auto& cChip : *cHybrid)
                     {
-                        ReadoutChip* theReadoutChip = static_cast<ReadoutChip*>(cChip);
                         std::string cOutput;
                         for(uint8_t cInput = 0 ; cInput < 6 ; cInput+=1)
                         {
@@ -614,7 +613,7 @@ bool CicFEAlignment::PhaseAlignment(uint16_t pWait_ms)
         {
             for (auto cHybrid : *cOpticalGroup)
             {
-                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cHybrid->getLinkId());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
                 
                 auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cHybrid->getIndex());
                 auto& cLogicThisHybrid = cLogicThisBoard->at(cHybrid->getIndex());
diff --git a/tools/DataChecker.cc b/tools/DataChecker.cc
index 44d74303d..10eae74fa 100644
--- a/tools/DataChecker.cc
+++ b/tools/DataChecker.cc
@@ -183,9 +183,10 @@ void DataChecker::Initialise ()
             {
                 for(auto cChip : *cHybrid)
                 {
-                    fThresholds        .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "VCth" );
-                    fLogic             .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "Pipe&StubInpSel&Ptwidth" );
-                    fHIPs              .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(cChip, "HIP&TestMode" );
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    fThresholds        .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(theChip, "VCth" );
+                    fLogic             .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(theChip, "Pipe&StubInpSel&Ptwidth" );
+                    fHIPs              .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() = static_cast<CbcInterface*>(fReadoutChipInterface)->ReadChipReg(theChip, "HIP&TestMode" );
                 }
             }
         }
@@ -261,7 +262,6 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
             auto& cHybridStubCheck = cThisStubCheckContainer->at(cHybrid->getIndex());  
         
 
-            auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
             auto cHybridId = cHybrid->getId();
             TH2D* cMatchedStubs = static_cast<TH2D*> ( getHist ( cHybrid, "MatchedStubs" ) );
             TH2D* cAllStubs = static_cast<TH2D*> ( getHist ( cHybrid, "Stubs" ) );
@@ -278,7 +278,6 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
                 TH2D* cAllHits = static_cast<TH2D*> ( getHist ( cChip, "Hits_perFe" ) );
                 TH2D* cMatchedHits = static_cast<TH2D*> ( getHist ( cChip, "MatchedHits_perFe" ) );
                 TProfile2D* cMatchedHitsEye = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_eye" ) );
-                TProfile2D* cMatchedHitsTP = static_cast<TProfile2D*> ( getHist ( cChip, "MatchedHits_TestPulse" ) );
                 
                 TH1D* cFlaggedEvents = static_cast<TH1D*> ( getHist ( cChip, "FlaggedEvents" ) );
                 
@@ -294,7 +293,6 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
                 for(auto cHitExpected : cExpectedHits )
                     LOG (INFO) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
                 auto cEventIterator = cEvents.begin();
-                size_t cEventCounter=0;
                 LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
                 for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
                 {
@@ -306,8 +304,6 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
                     {
                         auto cEvent = *cEventIterator;
                         auto cBxId = cEvent->BxId(cHybrid->getId());
-                        auto cErrorBit = cEvent->Error( cHybridId , cChipId );
-                        uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
                         uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
                         cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
                         cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
@@ -378,12 +374,10 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
         
                 std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
                 // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                uint8_t cBendCode = cBendLUT[ (cBend/2. - (-7.0))/0.5 ]; 
                 std::vector<uint8_t> cExpectedHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, cSeed, cBend ); 
                 auto cHybridId = cHybrid->getId();
                 
                 auto cEventIterator = cEvents.begin();
-                size_t cEventCounter=0;
                 LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
                 for( size_t cEventIndex=0; cEventIndex < cEventsPerPoint ; cEventIndex++) // for each event 
                 {
@@ -395,8 +389,6 @@ void DataChecker::matchEvents(BeBoard* pBoard, std::vector<uint8_t>pChipIds , st
                     {
                         auto cEvent = *cEventIterator;
                         auto cBxId = cEvent->BxId(cHybrid->getId());
-                        auto cErrorBit = cEvent->Error( cHybridId , cChipId );
-                        uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
                         uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
                         cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
                         cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
@@ -601,8 +593,7 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
     //get number of events from xml
     auto cSetting = fSettingsMap.find ( "Nevents" );
     uint32_t cEventsPerPoint = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
-    uint16_t cDefaultStubLatency=50;
-
+    
     // get trigger multiplicity from xml 
     cSetting = fSettingsMap.find ( "TriggerMultiplicity" );
     bool cConfigureTriggerMult = ( cSetting != std::end ( fSettingsMap ) );
@@ -615,20 +606,16 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
 
     // get target threshold 
     cSetting = fSettingsMap.find ( "Threshold" );
-    uint16_t cTargetThreshold = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 580  ; 
 
     // get number of attempts 
     cSetting = fSettingsMap.find ( "Attempts" );
-    size_t cAttempts = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 10  ; 
     // get mode
     cSetting = fSettingsMap.find ( "Mode" );
     uint8_t cMode = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 0  ; 
     // get latency offset
     cSetting = fSettingsMap.find ( "LatencyOffset" );
-    int cLatencyOffset = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 0  ; 
     // resync between attempts 
     cSetting = fSettingsMap.find ( "ReSync" );
-    bool cResync = ( cSetting != std::end ( fSettingsMap ) ) ? (cSetting->second==1) : false  ; 
     
     // if TP is used - enable it 
     cSetting = fSettingsMap.find ( "PulseShapePulseAmplitude" );
@@ -636,12 +623,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
 
     // get TP amplitude range 
     // get threshold range  
-    cSetting = fSettingsMap.find ( "PulseShapeInitialPulseAmplitude" );
-    uint16_t cInitialAmpl = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 400;
-    cSetting = fSettingsMap.find ( "PulseShapeFinalPulseAmplitude" );
-    uint16_t cFinalAmpl = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 600;
-    cSetting = fSettingsMap.find ( "PulseShapeAmplitudeStep" );
-    uint16_t cAmplStep = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 5;
     
     // get threshold range  
     cSetting = fSettingsMap.find ( "PulseShapeInitialVcth" );
@@ -662,13 +643,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
     uint16_t cTPdelayStep = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 3;
     
 
-    // get offset range 
-    cSetting = fSettingsMap.find ( "WindowOffsetInitial" );
-    uint16_t cInitialWindowOffset = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 0;
-    cSetting = fSettingsMap.find ( "WindowOffsetFinal" );
-    uint16_t cFinalWindowOffset = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 25;
-    
-
     // get injected stub from xmls 
     std::pair<uint8_t, int> cStub;
     cSetting = fSettingsMap.find ( "StubSeed" );
@@ -677,12 +651,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
     cStub.second = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 0; 
     LOG (DEBUG) << BOLDBLUE << "Injecting a stub in position " << +cStub.first << " with bend " << cStub.second << " to test data integrity..." << RESET;
 
-    // latency range 
-    cSetting = fSettingsMap.find ( "LatencyStart" );
-    int cLatencyOffsetStart = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 0;
-    cSetting = fSettingsMap.find ( "LatencyStop" );
-    int cLatencyOffsetStop = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 25;
-    
     // set-up for TP
     fAllChan = true;
     fMaskChannelsFromOtherGroups = !this->fAllChan;
@@ -717,7 +685,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
     }
 
     // generate stubs in exactly chips with IDs that match pChipIds
-    size_t cSeedIndex=0;
     std::vector<int> cExpectedHits(0);
     for(auto cBoard : *fDetectorContainer)
     {
@@ -732,13 +699,11 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                     {
                         std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
                         // both stub and bend are in units of half strips 
-                        double cBend_strips = cStub.second/2.;
                         // if using TP then always inject a stub with bend 0 .. 
                         // later will use offset window to modify bend [ should probably put this in inject stub ]
                         uint8_t cBend_halfStrips = cStub.second ; 
                         static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {cStub.first} , {cBend_halfStrips}, false );
                         // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                        uint8_t cBendCode = cBendLUT[ (cStub.second/2. - (-7.0))/0.5 ]; 
                         // set offsets
                         // needs to be fixed 
                         /*
@@ -844,7 +809,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                                 LOG (DEBUG) << BOLDMAGENTA << "\t.. expect a hit in channel " << +cHitExpected << RESET;
                             
                             auto cEventIterator = cEvents.begin();
-                            size_t cEventCounter=0;
                             LOG (DEBUG) << BOLDMAGENTA << "CBC" << +cChip->getId() << RESET;
                             size_t cMatchedStubs=0;
                             // vector to keep track of number of matches
@@ -853,8 +817,7 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                             {
                                 uint32_t cPipeline_first=0; 
                                 uint32_t cBxId_first=0; 
-                                bool cMissedEvent=false;
-
+                                
                                 if( cEventIndex == 0 )
                                     LOG (DEBUG) << BOLDMAGENTA << "'\tEvent " << +cEventIndex << RESET;
                                 bool cIncorrectPipeline=false;
@@ -862,8 +825,6 @@ void DataChecker::TestPulse(std::vector<uint8_t> pChipIds)
                                 {
                                     auto cEvent = *cEventIterator;
                                     auto cBxId = cEvent->BxId(cHybrid->getId());
-                                    auto cErrorBit = cEvent->Error( cHybridId , cChipId );
-                                    uint32_t cL1Id = cEvent->L1Id( cHybridId, cChipId );
                                     uint32_t cPipeline = cEvent->PipelineAddress( cHybridId, cChipId );
                                     cBxId_first = (cTriggerIndex == 0 ) ? cBxId : cBxId_first;
                                     cPipeline_first = (cTriggerIndex == 0 ) ? cPipeline : cPipeline_first;
@@ -1315,8 +1276,7 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     //get number of events from xml
     cSetting = fSettingsMap.find ( "Nevents" );
     uint32_t cEventsPerPoint = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
-    uint16_t cDefaultStubLatency=50;
-
+    
     // get trigger rate from xml
     cSetting = fSettingsMap.find ( "TriggerRate" );
     bool cConfigureTrigger = ( cSetting != std::end ( fSettingsMap ) );
@@ -1350,23 +1310,23 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     cSetting = fSettingsMap.find ( "ManualPhaseAlignment" );
     if( ( cSetting != std::end ( fSettingsMap ) ) )
     {
-        fPhaseTap = cSetting->second ; 
+        // fPhaseTap = cSetting->second ; 
         for (auto cBoard : *fDetectorContainer)
         {
-            for(auto cOpticalGroup : *cBoard)
-            {
-                for (auto cHybrid : *cOpticalGroup)
-                {
-                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
-                    if( cCic != NULL )
-                    {
-                        for(auto cChipId : pChipIds )
-                        {
-                            bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , fPhaseTap);
-                        }
-                    }
-                }
-            }
+        //     for(auto cOpticalGroup : *cBoard)
+        //     {
+        //         for (auto cHybrid : *cOpticalGroup)
+        //         {
+        //             auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+        //             if( cCic != NULL )
+        //             {
+        //                 for(auto cChipId : pChipIds )
+        //                 {
+        //                     // bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , fPhaseTap);
+        //                 }
+        //             }
+        //         }
+        //     }
             fBeBoardInterface->ChipReSync (static_cast<BeBoard*>(cBoard));
         }
     }
@@ -1431,7 +1391,6 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
     }
 
     // generate stubs in exactly chips with IDs that match pChipIds
-    size_t cSeedIndex=0;
     std::vector<int> cExpectedHits(0);
     for (auto cBoard : *fDetectorContainer)
     {
@@ -1446,13 +1405,11 @@ void DataChecker::DataCheck(std::vector<uint8_t> pChipIds, uint8_t pSeed , int p
                     {
                         std::vector<uint8_t> cBendLUT = static_cast<CbcInterface*>(fReadoutChipInterface)->readLUT( theChip );
                         // both stub and bend are in units of half strips 
-                        double cBend_strips = cStub.second/2.;
                         // if using TP then always inject a stub with bend 0 .. 
                         // later will use offset window to modify bend [ should probably put this in inject stub ]
                         uint8_t cBend_halfStrips = (pWithNoise) ? cStub.second : 0 ; 
                         static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , {cStub.first} , {cBend_halfStrips}, pWithNoise );
                         // each bend code is stored in this vector - bend encoding start at -7 strips, increments by 0.5 strips
-                        uint8_t cBendCode = cBendLUT[ (pBend/2. - (-7.0))/0.5 ]; 
                         // set offsets
                         // needs to be fixed 
                         /*
@@ -1608,20 +1565,20 @@ void DataChecker::L1Eye(std::vector<uint8_t> pChipIds )
         LOG (INFO) << BOLDBLUE << "Setting optimal phase tap in CIC to " << +cPhase << RESET;
         for (auto cBoard : *fDetectorContainer)
         {
-            for (auto cOpticalGroup : *cBoard)
-            {
-                for (auto& cHybrid : *cOpticalGroup)
-                {
-                    auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
-                    //fCicInterface->ResetPhaseAligner(cCic);
-                    for(auto cChipId : pChipIds )
-                    {
-                        bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
-                        // check if a resync is needed
-                        //fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cHybrid)->fCic); 
-                    }
-                }
-            }
+            // for (auto cOpticalGroup : *cBoard)
+            // {
+            //     for (auto& cHybrid : *cOpticalGroup)
+            //     {
+            //         auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
+            //         //fCicInterface->ResetPhaseAligner(cCic);
+            //         for(auto cChipId : pChipIds )
+            //         {
+            //             // bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
+            //             // check if a resync is needed
+            //             //fCicInterface->CheckReSync( static_cast<OuterTrackerModule*>(cHybrid)->fCic); 
+            //         }
+            //     }
+            // }
             // send a resync
             fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
             // re-do back-end alignment
diff --git a/tools/ExtraChecks.cc b/tools/ExtraChecks.cc
index 5ee6a8eac..c56353a0d 100644
--- a/tools/ExtraChecks.cc
+++ b/tools/ExtraChecks.cc
@@ -239,7 +239,7 @@ void ExtraChecks::Initialise ()
         {
             for (auto cHybrid : *cOpticalGroup)
             {
-                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cHybrid->getLinkId());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
                 //configure CBCs 
                 for (auto& cChip : *cHybrid)
                 {
@@ -310,7 +310,7 @@ void ExtraChecks::FindOpens()
         std::generate(cListOfLatencies.begin(), cListOfLatencies.end(), [&](){ return cValue+=cStep; });
         // prepare container 
         std::vector<DetectorDataContainer*> cContainerVector(0);
-        for( auto cLatency : cListOfLatencies)
+        for(  __attribute__((unused)) auto cLatency : cListOfLatencies)
         {
             cContainerVector.emplace_back(new DetectorDataContainer());
             ContainerFactory::copyAndInitStructure<Occupancy>(*fDetectorContainer, *cContainerVector.back() ); 
@@ -357,7 +357,6 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
     size_t cAttempts = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 10  ; 
 
     LOG (INFO) << BOLDBLUE << "Quick [manual] check of noise and pedetal of the FE ASICs  ..." << RESET;
-    uint16_t cDefaultStubLatency=50;
     for (auto cBoard : *fDetectorContainer)
     {
         for (auto cOpticalGroup : *cBoard)
@@ -382,13 +381,9 @@ void ExtraChecks::Evaluate(int pSigma, uint16_t pTriggerRate, bool pDisableStubs
 
     // get trigger rate from xml
     cSetting = fSettingsMap.find ( "TriggerRate" );
-    bool cConfigureTrigger = ( cSetting != std::end ( fSettingsMap ) );
-    uint16_t cTriggerRate = cConfigureTrigger ? cSetting->second : 100;
     // get trigger multiplicity from xml 
     cSetting = fSettingsMap.find ( "TriggerMultiplicity" );
-    bool cConfigureTriggerMult = ( cSetting != std::end ( fSettingsMap ) );
-    uint16_t cTriggerMult = cConfigureTriggerMult ? cSetting->second : 0;
-
+    
     //static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,pTriggerRate,3,0,cDefaultStubLatency);
     // scan threshold and look at events (checking pipeline errors , L1 counters ,etc. )
     // extract pedestal and noise .. store in histogram
@@ -629,8 +624,6 @@ void ExtraChecks::OccupancyCheck(uint16_t pTriggerRate, bool pDisableStubs)
 }
 void ExtraChecks::ExternalTriggers(uint16_t pNconsecutive, const std::string& pSource)
 {
-    auto cSetting = fSettingsMap.find ( "Nevents" );
-    uint32_t cNevents = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
     std::stringstream outp;
     static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTriggerFSM(0,10,4,0);
     for(auto cBoard : *fDetectorContainer)
@@ -755,7 +748,6 @@ void ExtraChecks::MonitorAmux(bool pAll)
     {
         BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // get result of pedestal and noise 
-        auto& cThisNoiseContainer = fNoiseContainer.at(cBoard->getIndex());
         auto& cThisPedestalContiner = fPedestalContainer.at(cBoard->getIndex());
             
         //one chip at a time 
@@ -776,8 +768,6 @@ void ExtraChecks::MonitorAmux(bool pAll)
                     for (auto cFe : *cOpticalGroup)
                     {
                         TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
-                        TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
-                        TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
                         for (auto cChip : *cFe) 
                         {
                             std::vector<float> cValues(0);
@@ -831,8 +821,6 @@ void ExtraChecks::MonitorAmux(bool pAll)
                     {
                         auto& cHybridPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex());  
                         TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan" ) );
-                        TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan" ) );
-                        TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan" ) );
                         for (auto cChip : *cFe) 
                         {
                             auto& cReadoutChipPedestal = cHybridPedestal->at(cChip->getIndex());
@@ -871,8 +859,6 @@ void ExtraChecks::MonitorAmux(bool pAll)
                     auto& cHybridPedestal = cThisPedestalContiner->at(cOpticalGroup->getIndex())->at(cFe->getIndex());  
                     LOG (INFO) << BOLDBLUE << "Scanning threshold on chips [one at a time] - and recording AMUX voltages..." << RESET;
                     TProfile2D* cScan = static_cast<TProfile2D*> ( getHist ( cFe , "VcthScan_perChip" ) );
-                    TProfile2D* cScanVBGbias = static_cast<TProfile2D*> ( getHist ( cFe , "VBGbiasScan_perChip" ) );
-                    TProfile2D* cScanVBGldo = static_cast<TProfile2D*> ( getHist ( cFe , "VBGldoScan_perChip" ) );
                     for(uint8_t cChipIndex=0; cChipIndex < cFe->size(); cChipIndex++)
                     {
                         auto& cReadoutChipPedestal = cHybridPedestal->at(cChipIndex);
@@ -947,54 +933,60 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
     uint32_t cEventsPerAttempt = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            //configure CBCs 
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                // switch off HitOr
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
-                //enable stub logic
-                static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
-                static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                //configure CBCs 
+                for (auto& cChip : *cFe)
+                {
+                    // switch off HitOr
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg ( static_cast<ReadoutChip*>(cChip), "HitOr", 0);
+                    //enable stub logic
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->selectLogicMode( static_cast<ReadoutChip*>(cChip), "Sampled", true, true); 
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->enableHipSuppression( static_cast<ReadoutChip*>(cChip), false, false, 0);
+                }
             }
         }
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
 
     // generate stubs in exactly one chip 
-    size_t cSeedIndex=0;
     int cBend=0;
     // seeds and bends needed to generate fixed pattern on SLVS lines carrying stub information from CBCs --> CICs
     std::vector<uint8_t> cSeeds{ static_cast<uint8_t>((pTPgroup*2 + 16*0+1)*2) };
     std::vector<int>     cBends( cSeeds.size(), cBend );
     SetStubWindowOffsets( pBendCode , cBend);
     std::vector<int> cExpectedHits(0);
-    for (auto cBoard : this->fBoardVector)
-    {   
-        for (auto& cFe : cBoard->fModuleVector)
+    for (auto cBoard : *fDetectorContainer)
+    {
+        for(auto cOpticalGroup : *cBoard)
         {
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                for (auto cChip : *cFe)
                 {
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( cChip , cSeeds , cBends, false );
-                    for( size_t cIndex=0; cIndex < cSeeds.size(); cIndex++)
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) != pChipIds.end()  ) 
                     {
-                        std::vector<uint8_t> cHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( cChip, cSeeds[cIndex], cBends[cIndex] ); 
-                        for( auto& cHit : cHits )
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->injectStubs( theChip , cSeeds , cBends, false );
+                        for( size_t cIndex=0; cIndex < cSeeds.size(); cIndex++)
                         {
-                            if( std::find(cExpectedHits.begin(), cExpectedHits.end(), cHit) == cExpectedHits.end() )
-                                cExpectedHits.push_back( cHit );
+                            std::vector<uint8_t> cHits = static_cast<CbcInterface*>(fReadoutChipInterface)->stubInjectionPattern( theChip, cSeeds[cIndex], cBends[cIndex] ); 
+                            for( auto& cHit : cHits )
+                            {
+                                if( std::find(cExpectedHits.begin(), cExpectedHits.end(), cHit) == cExpectedHits.end() )
+                                    cExpectedHits.push_back( cHit );
+                            }
                         }
                     }
+                    else
+                        static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, true);
                 }
-                else
-                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, true);
             } 
         }
     }
@@ -1012,88 +1004,89 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
     setSameGlobalDac("TestPulsePotNodeSel",  pTPamplitude );
     uint16_t cTPdelay=0;
     // check that the hits are there... so find test pulse
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // configure test pulse trigger 
         uint16_t cFirmwareTPdelay = 100 ;
         uint16_t cDelay = 100 ;
         uint16_t cTPsequence = 1000 ;
         uint16_t cFastReset = 0 ;
         static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureTestPulseFSM(cFirmwareTPdelay,cDelay,cTPsequence, cFastReset);
-        this->setSameDacBeBoard(cBoard, "TestPulseDelay", cTPdelay);
+        this->setSameDacBeBoard(theBoard, "TestPulseDelay", cTPdelay);
         for( int cLatencyOffset = -1 ; cLatencyOffset < 0; cLatencyOffset++)
         {
             uint16_t cLatency = cDelay+cLatencyOffset;
             LOG (INFO) << BOLDBLUE << "Latency set to " << +cLatency << RESET;
-            this->setSameDacBeBoard(cBoard, "TriggerLatency", cLatency);
-            fBeBoardInterface->ChipReSync ( cBoard );
+            this->setSameDacBeBoard(theBoard, "TriggerLatency", cLatency);
+            fBeBoardInterface->ChipReSync ( theBoard );
             
-            uint16_t cStubLatency = fBeBoardInterface->ReadBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay");
+            uint16_t cStubLatency = fBeBoardInterface->ReadBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay");
             uint16_t cStartScanRange = (pScan) ? 0 : cStubLatency;
             uint16_t cStopScanRange = (pScan) ? 100 : cStubLatency+1;
             
             for( uint16_t cStubLatency = cStartScanRange ; cStubLatency < cStopScanRange ; cStubLatency++ )//for( uint16_t cStubLatency = (cDelay-85) ; cStubLatency < (cDelay-59) ; cStubLatency++ )
             {
-                fBeBoardInterface->WriteBoardReg (cBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
+                fBeBoardInterface->WriteBoardReg (theBoard, "fc7_daq_cnfg.readout_block.global.common_stubdata_delay", cStubLatency);
                 LOG (INFO) << BOLDBLUE << "Stub latency set to " << +cStubLatency << RESET;
-                //fBeBoardInterface->ChipReSync ( cBoard );
+                //fBeBoardInterface->ChipReSync ( theBoard );
         
-                this->ReadNEvents ( cBoard , cEventsPerAttempt );
-                const std::vector<Event*>& cEvents = this->GetEvents ( cBoard );
-                for (auto& cFe : cBoard->fModuleVector)
+                this->ReadNEvents ( theBoard , cEventsPerAttempt );
+                const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+                for(auto cOpticalGroup : *cBoard)
                 {
-                    int cNstubs=0;
-                    TProfile2D* cMatchedBends = static_cast<TProfile2D*> ( getHist ( cFe, "CorrectBend_TP" ) );
-                    TProfile2D* cMatchedSeeds = static_cast<TProfile2D*> ( getHist ( cFe, "CorrectSeed_TP" ) );
-                    TProfile2D* cStubsFound = static_cast<TProfile2D*> ( getHist ( cFe, "Nstubs_TP" ) );
-                    TProfile* cMatchedHits = static_cast<TProfile*> ( getHist ( cFe, "MatchedHits" ) );
-                    //debug information
-                    for( auto cEvent : cEvents ) 
-                    { 
-                        auto cBxId = cEvent->BxId(cFe->getId());
-                        auto cEventCount = cEvent->GetEventCount(); 
-                        LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << " - BxId - " << +cBxId <<  RESET; 
-                    }
-                    int cNmatchedHits=0;
-                    for (auto& cChip : cFe->fReadoutChipVector) 
+                    for (auto cFe : *cOpticalGroup)
                     {
-                        if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end()  ) 
-                            continue;
-                        
-                        int cNstubsCBC=0;
-                        // check stubs + hits
+                        int cNstubs=0;
+                        TProfile2D* cMatchedBends = static_cast<TProfile2D*> ( getHist ( cFe, "CorrectBend_TP" ) );
+                        TProfile2D* cMatchedSeeds = static_cast<TProfile2D*> ( getHist ( cFe, "CorrectSeed_TP" ) );
+                        TProfile2D* cStubsFound = static_cast<TProfile2D*> ( getHist ( cFe, "Nstubs_TP" ) );
+                        //debug information
                         for( auto cEvent : cEvents ) 
+                        { 
+                            auto cBxId = cEvent->BxId(cFe->getId());
+                            auto cEventCount = cEvent->GetEventCount(); 
+                            LOG (INFO) << BOLDBLUE << "Event " << +cEventCount << " - BxId - " << +cBxId <<  RESET; 
+                        }
+                        int cNmatchedHits=0;
+                        for (auto cChip : *cFe) 
                         {
-                            //debug information
-                            uint32_t cL1Id =  cEvent->L1Id( cFe->getId(), cChip->getId() );
-                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
-                            auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
-                            for( auto cHit : cHits ) 
+                            if( std::find(pChipIds.begin(), pChipIds.end(), cChip->getId()) == pChipIds.end()  ) 
+                                continue;
+                            
+                            int cNstubsCBC=0;
+                            // check stubs + hits
+                            for( auto cEvent : cEvents ) 
                             {
-                                if( std::find(  cExpectedHits.begin(), cExpectedHits.end(), cHit) != cExpectedHits.end() ) 
+                                //debug information
+                                auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
+                                for( auto cHit : cHits ) 
                                 {
-                                    cNmatchedHits+=1;
+                                    if( std::find(  cExpectedHits.begin(), cExpectedHits.end(), cHit) != cExpectedHits.end() ) 
+                                    {
+                                        cNmatchedHits+=1;
+                                    }
                                 }
-                            }
 
-                            auto cStubs = cEvent->StubVector( cFe->getId(), cChip->getId() );
-                            for( auto cStub : cStubs )
-                            {
-                                cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, cStub.getPosition() == cSeeds[0] );
-                                cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency , cStub.getBend() == pBendCode );
-                                LOG (DEBUG) << BOLDMAGENTA << "Stub with seed " << +cStub.getPosition() << " with bend " << +cStub.getBend() << RESET;
-                            }
-                            if( cStubs.size() == 0 ) 
-                            {
-                                cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
-                                cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
+                                auto cStubs = cEvent->StubVector( cFe->getId(), cChip->getId() );
+                                for( auto cStub : cStubs )
+                                {
+                                    cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, cStub.getPosition() == cSeeds[0] );
+                                    cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency , cStub.getBend() == pBendCode );
+                                    LOG (DEBUG) << BOLDMAGENTA << "Stub with seed " << +cStub.getPosition() << " with bend " << +cStub.getBend() << RESET;
+                                }
+                                if( cStubs.size() == 0 ) 
+                                {
+                                    cMatchedBends->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
+                                    cMatchedSeeds->Fill( cChip->getId() , cDelay - cStubLatency, 0 );
+                                }
+                                cNstubs+= cStubs.size();
+                                cNstubsCBC += cStubs.size();
                             }
-                            cNstubs+= cStubs.size();
-                            cNstubsCBC += cStubs.size();
+                            cStubsFound->Fill( cChip->getId(), cDelay - cStubLatency, cNstubsCBC );
                         }
-                        cStubsFound->Fill( cChip->getId(), cDelay - cStubLatency, cNstubsCBC );
+                        LOG (INFO) << BOLDBLUE << "Stub latency of " << +cStubLatency << " FE" << +cFe->getId() << " : " << cNstubs << " stubs and " << +cNmatchedHits << " matched hits." << RESET;
                     }
-                    LOG (INFO) << BOLDBLUE << "Stub latency of " << +cStubLatency << " FE" << +cFe->getId() << " : " << cNstubs << " stubs and " << +cNmatchedHits << " matched hits." << RESET;
                 }
             }
         }
@@ -1106,35 +1099,40 @@ void ExtraChecks::DataCheckTP( std::vector<uint8_t> pChipIds,  uint8_t pTPamplit
     //unmask all channels and reset offsets 
     // also re-configure thresholds + hit/stub detect logic to original values 
     // and re-load configuration of fast command block from register map loaded from xml file 
-    for (auto cBoard : this->fBoardVector)
+    for (auto cBoard : *fDetectorContainer)
     {   
+        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         auto& cThresholdsThisBoard = fThresholds.at(cBoard->getIndex());
         auto& cLogicThisBoard = fLogic.at(cBoard->getIndex());
         auto& cHIPsThisBoard = fHIPs.at(cBoard->getIndex());
-        for (auto& cFe : cBoard->fModuleVector)
+        for(auto cOpticalGroup : *cBoard)
         {
-            auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cFe->getIndex());
-            auto& cLogicThisHybrid = cLogicThisBoard->at(cFe->getIndex());
-            auto& cHIPsThisHybrid = cHIPsThisBoard->at(cFe->getIndex());
-            static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (cFe->getLinkId());
-            for (auto& cChip : cFe->fReadoutChipVector)
+            for (auto cFe : *cOpticalGroup)
             {
-                static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( cChip, false);
-                // set offsets back to default value 
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
-                fReadoutChipInterface->WriteChipReg ( cChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-
-                LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
-                static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( cChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                auto& cThresholdsThisHybrid = cThresholdsThisBoard->at(cOpticalGroup->getIndex())->at(cFe->getIndex());
+                auto& cLogicThisHybrid = cLogicThisBoard->at(cOpticalGroup->getIndex())->at(cFe->getIndex());
+                auto& cHIPsThisHybrid = cHIPsThisBoard->at(cOpticalGroup->getIndex())->at(cFe->getIndex());
+                static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
+                for (auto cChip : *cFe)
+                {
+                    ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->MaskAllChannels( theChip, false);
+                    // set offsets back to default value 
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
+                    fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
+
+                    LOG (DEBUG) << BOLDBLUE << "Setting threshold on CBC" << +cChip->getId() << " back to " << +cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() << RESET ;
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cThresholdsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , cLogicThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                    static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "HIP&TestMode" , cHIPsThisHybrid->at(cChip->getIndex())->getSummary<uint16_t>() );
+                }
             }
         }
         //
         LOG (INFO) << BOLDBLUE << "Re-loading original coonfiguration of fast command block from hardware description file [.xml] " << RESET;
-        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(cBoard);
+        static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->ConfigureFastCommandBlock(theBoard);
         //
-        fBeBoardInterface->ChipReSync ( cBoard );
+        fBeBoardInterface->ChipReSync ( theBoard );
     }
 
 }
@@ -1166,7 +1164,6 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
     {
         BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         //this->setSameDacBeBoard(cBoard, "TestPulseGroup", pGroup);
-        uint16_t cMinValue=0;
         int cDelayAfterTPfastCommand = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         for( int cSamplingTime = 50 ; cSamplingTime <= 75 ; cSamplingTime += static_cast<int>(pStep) )
         {
@@ -1218,7 +1215,6 @@ void ExtraChecks::ReconstructTP(uint8_t pTPamplitude , uint8_t pGroup , uint8_t
                 fDetectorDataContainer = cContainerVector.at( cContainerVector.size()-1);
                 measureBeBoardData( cBoard->getIndex(), cEventsPerPoint);
                 // look at result 
-                auto& cExample = fDetectorDataContainer->at(cBoard->getIndex())->at(0)->at(0)->getSummary<Occupancy,Occupancy>();
                 LOG (INFO) << BOLDMAGENTA << "\t\t...Scanning " << cDacName << " to reconstruct TP - threshold now set to " << cListOfThresholds.at(cIndex) << RESET;
                 //" found average occupancy on chip0 to be : " << cExample.fOccupancy << RESET;
             }
@@ -1289,7 +1285,6 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
     }
 
     // generate stubs in exactly N chip(s)
-    size_t cSeedIndex=0;
     uint8_t cBendCode = 0x00;
     for (auto cBoard : *fDetectorContainer)
     {
@@ -1341,7 +1336,6 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
                 static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cFe)->getLinkId());
                 TH2D* cBxCounter = static_cast<TH2D*> ( getHist ( cFe, "BxCounter" ) );
                 TProfile* cMatchedStubs = static_cast<TProfile*> ( getHist ( cFe, "MatchedStubs" ) );
-                TProfile* cMatchedHits = static_cast<TProfile*> ( getHist ( cFe, "MatchedHits" ) );
                 TProfile* cMatchedBends = static_cast<TProfile*> ( getHist ( cFe, "CorrectBend" ) );
                 TProfile* cMatchedSeeds = static_cast<TProfile*> ( getHist ( cFe, "CorrectSeed" ) );
                 for (auto cChip : *cFe) 
@@ -1358,8 +1352,6 @@ void ExtraChecks::QuickStubCheck(std::vector<uint8_t> pChipIds, uint16_t pTrigge
                         //debug information
                         auto cBxId = cEvent->BxId(cFeId );
                         auto cEventCount = cEvent->GetEventCount(); 
-                        uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                        uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
                         LOG (INFO) << BOLDBLUE << "\t\t... Event " << +cEventCount << " FE" << +cFeId << " - Bx " << +cBxId  << RESET;
                         
                         cBxCounter->Fill( static_cast<float>(cEventCount) , cChipId , cBxId );
@@ -1449,7 +1441,6 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
         fBeBoardInterface->ChipReSync ( static_cast<BeBoard*>(cBoard) );
     }
     // generate stubs in exactly one chip 
-    size_t cSeedIndex=0;
     uint8_t cBendCode = 0x00;
     std::vector<int> cExpectedHits(0);
     for (auto cBoard : *fDetectorContainer)
@@ -1460,7 +1451,6 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
             {
 
                 static_cast<D19cFWInterface*>(fBeBoardInterface->getFirmwareInterface())->selectLink (static_cast<OuterTrackerModule*>(cHybrid)->getLinkId());
-                auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
                 for (auto cChip : *cHybrid)
                 {
                     ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
@@ -1522,7 +1512,6 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
                     for (auto cFe : *cOpticalGroup)
                     {
                         
-                        auto& cCic = static_cast<OuterTrackerModule*>(cFe)->fCic;
                         auto cFeId = cFe->getId();
                         auto cBxId = cEvent->BxId(cFe->getId());
                         LOG (DEBUG) << BOLDBLUE << "Link Id : " << +static_cast<OuterTrackerModule*>(cFe)->getLinkId() <<  " FE " << +cFeId << " - Bx Id " << +cBxId << RESET;
@@ -1541,7 +1530,6 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
                             cL1Status->Fill( cEventCount , cChipId, cErrorBit );
 
                             uint32_t cL1Id = cEvent->L1Id( cFeId, cChipId );
-                            uint32_t cPipeline = cEvent->PipelineAddress( cFeId, cChipId );
                             LOG (DEBUG) << BOLDBLUE << "Chip" << +cChipId << " : L1 counter " << +cL1Id << " error bits " << +cErrorBit << RESET;
                             //hits
                             auto cHits = cEvent->GetHits( cFeId, cChipId ) ;
@@ -1615,9 +1603,6 @@ void ExtraChecks::DataCheck(std::vector<uint8_t> pChipIds, uint16_t pTriggerRate
                     // set offsets back to default value 
                     fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset12", (0 << 4) | (0 << 0) );
                     fReadoutChipInterface->WriteChipReg ( theChip, "CoincWind&Offset34", (0 << 4) | (0 << 0) );
-                    fThresholds
-                    fLogic
-                    fHIPs
                     static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "VCth"                    , fThresholds.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
                     static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "Pipe&StubInpSel&Ptwidth" , fLogic     .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
                     static_cast<CbcInterface*>(fReadoutChipInterface)->WriteChipReg( theChip, "HIP&TestMode"            , fHIPs      .at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() );
@@ -1640,7 +1625,7 @@ void ExtraChecks::L1Eye()
                 for ( auto cHybrid : *cOpticalGroup )
                 {
                     auto& cCic = static_cast<OuterTrackerModule*>(cHybrid)->fCic;
-                    bool cConfigured = fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
+                    fCicInterface->SetStaticPhaseAlignment(  cCic , cChipId ,  0 , cPhase);
                 }
             }
         }
@@ -1770,7 +1755,7 @@ void ExtraChecks::StubCheck(uint8_t pChipId, bool pUseNoise, uint8_t pTestPulseA
                         // set DAC .. read events
                         this->setSameDacBeBoard(theBoard, "VCth", cVcth);
                         this->ReadNEvents ( theBoard , cEventsPerAttempt );
-                        const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
+                        // const std::vector<Event*>& cEvents = this->GetEvents ( theBoard );
                         /*for (auto& cFe : cBoard->fModuleVector)
                         {
                             for (auto& cChip : cFe->fReadoutChipVector) 
@@ -1894,7 +1879,6 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
     uint32_t cEventsPerAttempt = ( cSetting != std::end ( fSettingsMap ) ) ? cSetting->second : 100;
     uint8_t cFirmwareTPdelay=100;
     uint8_t cFirmwareTriggerDelay=200;
-    uint16_t cDefaultStubLatency=50; 
     
     // configure FE chips so that stubs are detected [i.e. make sure HIP
     // suppression is off ] 
@@ -1939,7 +1923,6 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
         //first, set VCth to the target value for each CBC
         this->setSameDacBeBoard(theBoard , "VCth", pThreshold);
         auto& cThisShortsContainer = fShortsContainer.at(cBoard->getIndex());
-        uint16_t cMinValue=0;
         uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         this->setSameDacBeBoard(theBoard, "TriggerLatency", cDelay-1);
         this->setSameDacBeBoard(theBoard, "TestPulseDelay", cTPdelay);
@@ -1962,13 +1945,10 @@ void ExtraChecks::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
                     {
                         auto cReadoutChipShorts = cHybridShorts->at(cChip->getIndex());
                         int cNhits=0;
-                        int cEventCounter=0;
                         for( auto cEvent : cEvents ) 
                         {
                             //debug information
                             auto cEventCount = cEvent->GetEventCount(); 
-                            uint32_t cL1Id = cEvent->L1Id( cFe->getId(), cChip->getId() );
-                            uint32_t cPipeline = cEvent->PipelineAddress( cFe->getId(), cChip->getId() );
                             //hits
                             auto cHits = cEvent->GetHits( cFe->getId(), cChip->getId() ) ;
                             LOG (INFO) << BOLDBLUE << "\t\tGroup " << +cTestGroup << " FE" << +cFe->getId() << " .. CBC" << +cChip->getId() << "...Event " << +cEventCount << " FE" << +cFe->getId() << " - " << +cHits.size() << " hits found/" << +cBitset.count() << " channels in test group" << RESET;
@@ -2074,21 +2054,21 @@ void ExtraChecks::SetStubWindowOffsets(uint8_t pBendCode , int pBend)
 std::pair<uint16_t,float> ExtraChecks::ReadAmux(uint8_t pFeId , uint8_t pChipId , std::string pValueToRead, bool pOptical )
 {
     // select AMUX output on one of the CBCs 
-    for (auto cBoard : *fDetectorContainer)
-    {
-        for(auto cOpticalGroup : *cBoard)
-        {
-            for ( auto cHybrid : *cOpticalGroup )
-            {
-                for ( auto cChip : *cHybrid )
-                {
-                    // select AMUX output 
-                    //this->fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip),  "AmuxOutput", ((cChip->getId() != pChipId ) ? fAmuxMap["Floating"]: fAmuxMap[pValueToRead]) );
-                    // now read voltage from the right source .
-                }
-            }
-        }
-    }
+    // for (auto cBoard : *fDetectorContainer)
+    // {
+    //     for(auto cOpticalGroup : *cBoard)
+    //     {
+    //         for ( auto cHybrid : *cOpticalGroup )
+    //         {
+    //             for ( auto cChip : *cHybrid )
+    //             {
+    //                 // select AMUX output 
+    //                 //this->fReadoutChipInterface->WriteChipReg( static_cast<ReadoutChip*>(cChip),  "AmuxOutput", ((cChip->getId() != pChipId ) ? fAmuxMap["Floating"]: fAmuxMap[pValueToRead]) );
+    //                 // now read voltage from the right source .
+    //             }
+    //         }
+    //     }
+    // }
     // read voltage using ADC [ either ADC on GBT-SCA .. or on plug-in card]
     std::pair<uint16_t,float> cReading;
     if( pOptical  )
diff --git a/tools/HybridTester.cc b/tools/HybridTester.cc
index 54be8203e..bbea4596d 100644
--- a/tools/HybridTester.cc
+++ b/tools/HybridTester.cc
@@ -164,7 +164,6 @@ void HybridTester::InitializeHists()
 
                 for ( auto cCbc : *cFe )
                 {
-                    ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
                     uint32_t cCbcId = cCbc->getId();
 
                     TString cName = Form ( "SCurve_Fe%d_Cbc%d", cFeId, cCbcId );
@@ -1081,7 +1080,7 @@ void HybridTester::Measure()
 
     for ( auto pBoard : *fDetectorContainer )
     {
-        BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+        BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
         uint32_t cN = 1;
         uint32_t cNthAcq = 0;
 
diff --git a/tools/LatencyScan.cc b/tools/LatencyScan.cc
index 7ff652eee..1780c3083 100644
--- a/tools/LatencyScan.cc
+++ b/tools/LatencyScan.cc
@@ -120,7 +120,7 @@ void LatencyScan::MeasureTriggerTDC()
     return;
 }
 
-std::map<Module*, uint8_t> LatencyScan::ScanLatency ( uint8_t pStartLatency, uint8_t pLatencyRange)
+std::map<ModuleContainer*, uint8_t> LatencyScan::ScanLatency ( uint8_t pStartLatency, uint8_t pLatencyRange)
 {    
 
     LOG (INFO) << "Scanning Latency ... " ;
@@ -158,14 +158,14 @@ std::map<Module*, uint8_t> LatencyScan::ScanLatency ( uint8_t pStartLatency, uin
 
 
     // analyze the Histograms
-    std::map<Module*, uint8_t> cLatencyMap;
+    std::map<ModuleContainer*, uint8_t> cLatencyMap;
 
     updateHists ( "module_latency", true );
 
     return cLatencyMap;
 }
 
-std::map<Module*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency, uint8_t pLatencyRange )
+std::map<ModuleContainer*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency, uint8_t pLatencyRange )
 {
     // This is not super clean but should work
     // Take the default VCth which should correspond to the pedestal and add 8 depending on the mode to exclude noise
@@ -250,7 +250,7 @@ std::map<Module*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency,
     }
 
     // analyze the Histograms
-    std::map<Module*, uint8_t> cStubLatencyMap;
+    std::map<ModuleContainer*, uint8_t> cStubLatencyMap;
 
     LOG (INFO) << "Identified the Latency with the maximum number of Stubs at: " ;
 
@@ -267,7 +267,7 @@ std::map<Module*, uint8_t> LatencyScan::ScanStubLatency ( uint8_t pStartLatency,
 
         //this->accept ( cLatWriter );
 
-        LOG (INFO) << "Stub Latency FE " << +cFe.first->getModuleId()  << ": " << +cStubLatency << " clock cycles!" ;
+        LOG (INFO) << "Stub Latency FE " << +cFe.first->getId()  << ": " << +cStubLatency << " clock cycles!" ;
     }
 
     return cStubLatencyMap;
@@ -424,7 +424,7 @@ void LatencyScan::ScanLatency2D(uint8_t pStartLatency, uint8_t pLatencyRange)
                 // }
 
                 LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
-                LOG (INFO) << BOLDRED << "For FE" << +cFe->getFeId() << " found optimal latencies to be : " << RESET ; 
+                LOG (INFO) << BOLDRED << "For FE" << +cFe->getId() << " found optimal latencies to be : " << RESET ; 
                 LOG (INFO) << BOLDRED << "........ Stub Latency of " << +cOptimalLatencies.first << " and a Trigger Latency of " << +cOptimalLatencies.second << RESET; 
                 LOG (INFO) << BOLDRED << "************************************************************************************" << RESET ;
             }
diff --git a/tools/LatencyScan.h b/tools/LatencyScan.h
index 600c22420..e9aec9b0b 100644
--- a/tools/LatencyScan.h
+++ b/tools/LatencyScan.h
@@ -48,8 +48,8 @@ class LatencyScan : public Tool
     LatencyScan();
     ~LatencyScan();
     void Initialize (uint32_t pStartLatency, uint32_t pLatencyRange);
-    std::map<Ph2_HwDescription::Module*, uint8_t> ScanLatency ( uint8_t pStartLatency = 0, uint8_t pLatencyRange = 20);
-    std::map<Ph2_HwDescription::Module*, uint8_t> ScanStubLatency ( uint8_t pStartLatency = 0, uint8_t pLatencyRange = 20 );
+    std::map<ModuleContainer*, uint8_t> ScanLatency ( uint8_t pStartLatency = 0, uint8_t pLatencyRange = 20);
+    std::map<ModuleContainer*, uint8_t> ScanStubLatency ( uint8_t pStartLatency = 0, uint8_t pLatencyRange = 20 );
     void MeasureTriggerTDC();
     void ScanLatency2D(uint8_t pStartLatency = 0, uint8_t pLatencyRange = 20);
 
diff --git a/tools/PulseShape.cc b/tools/PulseShape.cc
index 23ea51fe5..e701b8cc6 100644
--- a/tools/PulseShape.cc
+++ b/tools/PulseShape.cc
@@ -244,7 +244,7 @@ void PulseShape::fitGraph ( int pLow )
     {
         for ( auto& cChannel : cCbc.second )
         {
-            TString cName = Form ( "f_cbc_pulse_Fe%dCbc%d_Channel%d", cCbc.first->getFeId(), cCbc.first->getChipId(), cChannel->fChannelId );
+            TString cName = Form ( "f_cbc_pulse_Fe%dCbc%d_Channel%d", static_cast<ReadoutChip*>(cCbc.first)->getFeId(), static_cast<ReadoutChip*>(cCbc.first)->getChipId(), cChannel->fChannelId );
             TObject* cObj = gROOT->FindObject ( cName );
 
             if ( cObj ) delete cObj;
@@ -587,7 +587,7 @@ void PulseShape::updateHists ( std::string pHistName, bool pFinal )
         if ( pHistName == "" )
         {
             // now iterate over the channels in the channel map and draw
-            auto cChannelVector = fChannelMap.find ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ) );
+            auto cChannelVector = fChannelMap.find ( static_cast<ChipContainer*>(cCanvas.first) );
 
             if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel mapped to this CBC ( " << +cCanvas.first << " )" ;
             else
@@ -606,7 +606,7 @@ void PulseShape::updateHists ( std::string pHistName, bool pFinal )
         if ( pHistName == "" && pFinal )
         {
             // now iterate over the channels in the channel map and draw
-            auto cChannelVector = fChannelMap.find ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ) );
+            auto cChannelVector = fChannelMap.find (static_cast<ChipContainer*>(cCanvas.first) );
 
             if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel mapped to this CBC ( " << +cCanvas.first << " )" ;
             else
@@ -626,12 +626,12 @@ void PulseShape::updateHists ( std::string pHistName, bool pFinal )
         }
         else if ( pHistName == "cbc_pulseshape" )
         {
-            auto cChannelVector = fChannelMap.find ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ) );
+            auto cChannelVector = fChannelMap.find ( static_cast<ChipContainer*>(cCanvas.first) );
 
             if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel mapped to this CBC ( " << +cCanvas.first << " )" ;
             else
             {
-                TH2I* cTmpFrame = static_cast<TH2I*> ( getHist ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ), "frame" ) );
+                TH2I* cTmpFrame = static_cast<TH2I*> ( getHist ( static_cast<ChipContainer*>(cCanvas.first), "frame" ) );
                 cCanvas.second->cd ( 2 );
                 cTmpFrame->Draw( );
                 TString cOption = "P same";
@@ -647,13 +647,13 @@ void PulseShape::updateHists ( std::string pHistName, bool pFinal )
         }
         else if ( pHistName == "cbc_pulseshape" && pFinal )
         {
-            auto cChannelVector = fChannelMap.find ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ) );
+            auto cChannelVector = fChannelMap.find ( static_cast<ChipContainer*>(cCanvas.first) );
 
             if ( cChannelVector == std::end ( fChannelMap ) ) LOG (INFO) << "Error, no channel mapped to this CBC ( " << +cCanvas.first << " )" ;
             else
             {
                 cCanvas.second->cd ( 2 );
-                TMultiGraph* cMultiGraph = static_cast<TMultiGraph*> ( getHist ( static_cast<Ph2_HwDescription::Chip*> ( cCanvas.first ), "cbc_pulseshape" ) );
+                TMultiGraph* cMultiGraph = static_cast<TMultiGraph*> ( getHist ( static_cast<ChipContainer*>(cCanvas.first), "cbc_pulseshape" ) );
                 cMultiGraph->Draw ( "A" );
                 cCanvas.second->Modified();
             }
diff --git a/tools/SignalScanFit.cc b/tools/SignalScanFit.cc
index 94b964814..540f3c8b3 100644
--- a/tools/SignalScanFit.cc
+++ b/tools/SignalScanFit.cc
@@ -138,7 +138,7 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
         // Take Data for all Boards
         for ( auto pBoard : *fDetectorContainer )
         {
-            BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+            BeBoard* theBoard = static_cast<BeBoard*>(pBoard);
             uint32_t cTotalEvents = 0;
             uint32_t cTriggerSource = fBeBoardInterface->ReadBoardReg( theBoard , "fc7_daq_cnfg.fast_command_block.trigger_source"); // check trigger source
             double cTime=0;
@@ -182,7 +182,6 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
             double   cTriggerRate = (cEvents.size())/cTime; 
             cTotalEvents = cEvents.size();
             LOG (INFO) << BOLDBLUE << "Vcth: " << +cVCth << ". Recorded " << cTotalEvents << " Events [ average trigger rate " << cTriggerRate << " ]"<< RESET;
-            uint32_t cMaxEvents_toProcess=10000;
             //cTotalEvents = std::min(cMaxEvents_toProcess, (uint32_t)cEvents.size());
             int cEventHits = 0;
             int cEventClusters = 0;
@@ -192,7 +191,7 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
             {
                 //if( (uint32_t)cEventCounter > cMaxEvents_toProcess ) 
                 //    continue;
-                for(auto cOpticalGroup : *cBoard)
+                for(auto cOpticalGroup : *pBoard)
                 {
                     for ( auto cFe : *cOpticalGroup )
                     {
@@ -218,7 +217,7 @@ void SignalScanFit::ScanSignal ( int pSignalScanLength )
                             TH2D* cClusters2DEvenHist     = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_even" ) );
                             TH2D* cClusters2DOddHist      = dynamic_cast<TH2D*> ( getHist ( cCbc, "Cbc_Clusters2D_odd" ) );
                             std::vector<uint32_t> cHits = cEvent->GetHits( cFe->getId(), cCbc->getId() );
-                            LOG (DEBUG) << BOLDBLUE << "Found " << +cHits.size() << " hits in CBC" << +cCbc->getChipId() << RESET;
+                            LOG (DEBUG) << BOLDBLUE << "Found " << +cHits.size() << " hits in CBC" << +cCbc->getId() << RESET;
                             for ( auto cId : cHits ) 
                             {
                                 LOG (DEBUG) << BOLDBLUE << "\t.... Hit found in channel " << +cId << " i.e. sensor " << (int)(cId%2) << RESET;
diff --git a/tools/StubSweep.cc b/tools/StubSweep.cc
index 10a093f12..19c41c010 100644
--- a/tools/StubSweep.cc
+++ b/tools/StubSweep.cc
@@ -260,13 +260,13 @@ void StubSweep::SweepStubs (uint32_t pNEvents )
 
     this->writeObjects();
 }
-void StubSweep::fillStubSweepHist ( Chip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubPosition )
+void StubSweep::fillStubSweepHist ( ReadoutChip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubPosition )
 {
     // Find the Occupancy histogram for the current Chip
     TProfile* cTmpProfile = static_cast<TProfile*> ( getHist ( pCbc, "StubAddresses" ) );
     cTmpProfile->Fill ( pChannelPair[1], pStubPosition );
 }
-void StubSweep::fillStubBendHist ( Chip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubBend )
+void StubSweep::fillStubBendHist ( ReadoutChip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubBend )
 {
     // Find the Occupancy histogram for the current Chip
     TProfile* cTmpProfile = static_cast<TProfile*> ( getHist ( pCbc, "StubBends" ) );
diff --git a/tools/StubSweep.h b/tools/StubSweep.h
index f1967448c..a5b326443 100644
--- a/tools/StubSweep.h
+++ b/tools/StubSweep.h
@@ -52,8 +52,8 @@ class StubSweep : public Tool
 
     // methods to fill/update histograms
     void updateHists ( std::string pHistname );
-    void fillStubBendHist ( Ph2_HwDescription::Chip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubBend );
-    void fillStubSweepHist ( Ph2_HwDescription::Chip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubPosition );
+    void fillStubBendHist ( Ph2_HwDescription::ReadoutChip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubBend );
+    void fillStubSweepHist ( Ph2_HwDescription::ReadoutChip* pCbc, std::vector<uint8_t> pChannelPair, uint8_t pStubPosition );
 
     // method to configure test pulse on the CBC
     void configureTestPulse (Ph2_HwDescription::Chip* pCbc, uint8_t pPulseState);
diff --git a/tools/Tool.cc b/tools/Tool.cc
index 9b3eef4a4..b4ac330f9 100644
--- a/tools/Tool.cc
+++ b/tools/Tool.cc
@@ -417,7 +417,7 @@ void Tool::SaveResults()
 		// Now per FE
 		for ( const auto& cHybrid : fModuleHistMap )
 		{
-			TString cDirName = Form ( "FE%d", cHybrid.first->getFeId() );
+			TString cDirName = Form ( "FE%d", cHybrid.first->getId() );
 			TObject* cObj = gROOT->FindObject ( cDirName );
 
 			//if ( cObj ) delete cObj;
@@ -435,7 +435,7 @@ void Tool::SaveResults()
 		for ( const auto& cChip : fChipHistMap )
 		{
 			//Fabio: CBC specific -> to be moved out from Tool
-			TString cDirName = Form ( "FE%dCBC%d", cChip.first->getFeId(), cChip.first->getChipId() );
+			TString cDirName = Form ( "FE%dCBC%d", static_cast<ReadoutChip*>(cChip.first)->getFeId(), cChip.first->getId() );
 			TObject* cObj = gROOT->FindObject ( cDirName );
 
 			//if ( cObj ) delete cObj;
diff --git a/tools/Tool.h b/tools/Tool.h
index c939e2cf4..2ae70e64d 100644
--- a/tools/Tool.h
+++ b/tools/Tool.h
@@ -52,7 +52,7 @@ class Tool : public Ph2_System::SystemController
         using ChipHistogramMap = std::map<ChipContainer*, std::map<std::string, TObject*> >;
         using ModuleHistogramMap = std::map<ModuleContainer*, std::map<std::string, TObject*> >;
         using BeBoardHistogramMap = std::map<BoardContainer*, std::map<std::string, TObject*> >;
-        using CanvasMap = std::map<Ph2_HwDescription::FrontEndDescription*, TCanvas*>;
+        using CanvasMap = std::map<BaseContainer*, TCanvas*>;
     #endif
 
     using TestGroupChannelMap =  std::map< int, std::vector<uint8_t> >;
-- 
GitLab


From 3091f3725627af5f1bebd3212222d55eafe9194f Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 21:29:28 -0500
Subject: [PATCH 6/9] Working in standAlone

---
 CMakeLists.txt                 |  2 +-
 HWInterface/D19cFWInterface.cc | 21 ++++++-----------
 src/TwoStripAlignment_done.cc  | 37 ++++++++++++++++--------------
 src/WhatIsGoingOn.cc           |  4 +---
 src/cbc3irrad.cc               | 33 ++++++++++++++-------------
 src/cic_datatest.cc            | 15 ++++++++-----
 src/cic_test.cc                | 41 +++++++++++++++-------------------
 src/cmtest.cc                  |  9 ++++----
 src/convertSLink.cc            |  7 ++----
 src/d19c_test.cc               | 11 +++++----
 src/eudaqproducer.cc           |  4 +---
 src/feh_2s_test.cc             |  2 --
 src/fpgaconfig.cc              |  2 +-
 src/miniDAQ.cc                 |  2 +-
 src/mux_setup.cc               |  3 +--
 tools/BackEndAlignment.cc      |  3 +--
 tools/ShortFinder.cc           |  2 --
 tools/StubQuickCheck.cc        |  2 --
 18 files changed, 92 insertions(+), 108 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 579f10a92..7339bb4ad 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,7 +74,7 @@ if(NOT DEFINED ENV{OTSDAQ_CMSOUTERTRACKER_DIR})
     # If it's a recent gcc compiler, then let's add some
     # compiler options to avoid warnings promoted to errors
 
-    set (GCC_NOERROR_FLAGS "-Wno-error=maybe-uninitialized -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=unused-result -Wno-error=deprecated-declarations")
+    set (GCC_NOERROR_FLAGS " -Wno-error=unused-result -Wno-error=deprecated-declarations")
     set (GCC_6_NOERROR_FLAGS "-Wno-error=misleading-indentation")
     set (GCC_7_NOERROR_FLAGS "-Wno-expansion-to-defined")
     set (GCC_8_NOERROR_FLAGS "-Wno-error=catch-value -Wno-error=class-memaccess -Wno-error=format-overflow")
diff --git a/HWInterface/D19cFWInterface.cc b/HWInterface/D19cFWInterface.cc
index 68f6de6a7..2384c6ef3 100755
--- a/HWInterface/D19cFWInterface.cc
+++ b/HWInterface/D19cFWInterface.cc
@@ -2492,9 +2492,7 @@ uint32_t D19cFWInterface::computeEventSize ( BeBoard* pBoard )
     uint32_t cFrontEndTypeCode = ReadReg("fc7_daq_stat.general.info.chip_type");
     fFirmwareFrontEndType = getFrontEndType(cFrontEndTypeCode);
     uint32_t cNFe = pBoard->getNFe();
-    uint32_t cNCbc = 0;
-    uint32_t cNMPA = 0;
-    uint32_t cNSSA = 0;
+    uint32_t cNChips = 0;
 
     uint32_t cNEventSize32 = 0;
 
@@ -2502,25 +2500,20 @@ uint32_t D19cFWInterface::computeEventSize ( BeBoard* pBoard )
     {
         for (const auto cHybrid : *cOpticalGroup)
         {
-            cNCbc += cHybrid->size();
-            cNMPA += cHybrid->size();
-            cNSSA += cHybrid->size();
+            cNChips += cHybrid->size();
         }
     }
+    FrontEndType theFrontEndType = static_cast<ReadoutChip*>(pBoard->at(0)->at(0)->at(0))->getFrontEndType();
     if( fNCic != 0 ) 
     {
         uint32_t cSparsified = ReadReg( "fc7_daq_cnfg.physical_interface_block.cic.2s_sparsified_enable" ) ;
         LOG (DEBUG) << BOLDBLUE << "CIC sparsification expected to be : " << +cSparsified << RESET;
     }
     else
-    if (cNCbc>0) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNCbc * D19C_EVENT_SIZE_32_CBC3;
-    if (cNMPA>0) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32 + cNFe * D19C_EVENT_HEADER2_SIZE_32 + cNMPA * D19C_EVENT_SIZE_32_MPA;
-    if (cNSSA>0) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32 + cNFe * D19C_EVENT_HEADER2_SIZE_32 + cNSSA * D19C_EVENT_SIZE_32_SSA;
-    if (cNCbc>0 && cNMPA>0)
-    {
-        LOG(INFO) << "Not configurable for multiple chips";
-        exit (1);
-    }
+    if (theFrontEndType==FrontEndType::CBC3) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32_CBC3 + cNChips * D19C_EVENT_SIZE_32_CBC3;
+    if (theFrontEndType==FrontEndType::MPA ) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32 + cNFe * D19C_EVENT_HEADER2_SIZE_32 + cNChips * D19C_EVENT_SIZE_32_MPA;
+    if (theFrontEndType==FrontEndType::SSA ) cNEventSize32 = D19C_EVENT_HEADER1_SIZE_32 + cNFe * D19C_EVENT_HEADER2_SIZE_32 + cNChips * D19C_EVENT_SIZE_32_SSA;
+    
     if (fIsDDR3Readout) 
     {
         uint32_t cNEventSize32_divided_by_8 = ((cNEventSize32 >> 3) << 3);
diff --git a/src/TwoStripAlignment_done.cc b/src/TwoStripAlignment_done.cc
index 5d6981d23..c3a50c9d9 100644
--- a/src/TwoStripAlignment_done.cc
+++ b/src/TwoStripAlignment_done.cc
@@ -47,49 +47,52 @@ int main( int argc, char* argv[] )
 	D19cFWInterface* IB = dynamic_cast<D19cFWInterface*>(cTool.fBeBoardFWMap.find(0)->second); // There has to be a better way!
 
 	cTool.setFWTestPulse(); // turns on injections (in either mode)
-	BeBoard* pBoard = cTool.fBoardVector.at(0);
-	std::vector < ReadoutChip* > &ChipVec = pBoard->getModule(0)->fReadoutChipVector;
+	BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at(0));
+	ModuleContainer* ChipVec = pBoard->at(0)->at(0);
 	TH1I *h1 = new TH1I("h1", "S-CURVE (strip 12);THDAC;number of hits", 80, 20, 100);
 	TH1I *h2 = new TH1I("h2", "S-CURVE (strip 88);THDAC;number of hits", 80, 20, 100);
 	for (int thd = 20; thd<=75; thd++)
 	{
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_CALDAC", 35);
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ReadoutMode", 0x1); // sync mode = 0
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "Bias_THDAC", thd);
-			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(cSSA, "Bias_THDAC");
-			cTool.fReadoutChipInterface->WriteChipReg(cSSA, "FE_Calibration", 1);
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_CALDAC", 35);
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ReadoutMode", 0x1); // sync mode = 0
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "Bias_THDAC", thd);
+			LOG (INFO) << BOLDGREEN << "THD = " << cTool.fReadoutChipInterface->ReadChipReg(theSSA, "Bias_THDAC");
+			cTool.fReadoutChipInterface->WriteChipReg(theSSA, "FE_Calibration", 1);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				cTool.fReadoutChipInterface->WriteChipReg(cSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
+				cTool.fReadoutChipInterface->WriteChipReg(theSSA, "ENFLAGS_S" + std::to_string(i), 21); // 17 = 10001 (enable strobe)
 			}
 		}
 		// 15
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
 			for (int i = 1; i<=120;i++ ) // loop over all strips
 			{
-				if (i != 88) cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 15);
-				else cTool.fReadoutChipInterface->WriteChipReg(cSSA, "THTRIMMING_S" + std::to_string(i), 15);
+				if (i != 88) cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 15);
+				else cTool.fReadoutChipInterface->WriteChipReg(theSSA, "THTRIMMING_S" + std::to_string(i), 15);
 			}
 		}
 		IB->PS_Clear_counters();
 		cTool.Start(0);
 		std::this_thread::sleep_for (std::chrono::milliseconds(50));
 		cTool.Stop();
-		for(auto cSSA: ChipVec)
+		for(auto cSSA: *ChipVec)
 		{
-			uint8_t cRP1_12 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S12");
-			uint8_t cRP2_12 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S12");
+			ReadoutChip* theSSA = static_cast<ReadoutChip*>(cSSA);
+			uint8_t cRP1_12 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S12");
+			uint8_t cRP2_12 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S12");
 			uint16_t cRP_12 = (cRP2_12*256) + cRP1_12; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP_12 << RESET;
 			h1->Fill(thd, cRP_12);
 
 
-			uint8_t cRP1_88 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_LSB_S88");
-			uint8_t cRP2_88 = cTool.fReadoutChipInterface->ReadChipReg(cSSA, "ReadCounter_MSB_S88");
+			uint8_t cRP1_88 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_LSB_S88");
+			uint8_t cRP2_88 = cTool.fReadoutChipInterface->ReadChipReg(theSSA, "ReadCounter_MSB_S88");
 			uint16_t cRP_88 = (cRP2_88*256) + cRP1_88; 
 
 			LOG (INFO) << BOLDRED << "THDAC = " << thd << ", HITS = " << cRP_88 << RESET;
diff --git a/src/WhatIsGoingOn.cc b/src/WhatIsGoingOn.cc
index d786dfe26..b4141a07d 100644
--- a/src/WhatIsGoingOn.cc
+++ b/src/WhatIsGoingOn.cc
@@ -46,8 +46,6 @@ int main( int argc, char* argv[] )
 	LOG (INFO) << BOLDRED << "== 3 =============" << RESET;
 	cTool.InitializeSettings ( cHWFile, outp );
 	LOG (INFO) << BOLDRED << "== 4 =============" << RESET;
-	D19cFWInterface* IB = dynamic_cast<D19cFWInterface*>(cTool.fBeBoardFWMap.find(0)->second); // There has to be a better way!
-	LOG (INFO) << BOLDRED << "== 5 =============" << RESET;
 	cTool.ConfigureHw();	
-	LOG (INFO) << BOLDRED << "== 6 =============" << RESET;
+	LOG (INFO) << BOLDRED << "== 5 =============" << RESET;
 }
diff --git a/src/cbc3irrad.cc b/src/cbc3irrad.cc
index 46f6859c8..d63650aab 100644
--- a/src/cbc3irrad.cc
+++ b/src/cbc3irrad.cc
@@ -240,26 +240,27 @@ int main ( int argc, char* argv[] )
                 cDog.Reset (5);
                 std::vector<std::string> cBiases{"VCth", "CAL_Vcasc", "VPLUS1", "VPLUS2", "VBGbias", "VBG_LDO", "Vpafb", "VDDA", "Nc50", "Ipa", "Ipre1", "Ipre2", "CAL_I", "Ibias", "Ipsf", "Ipaos", "Icomp", "Ihyst"};
 
-                for (auto cBoard : cBiasSweep.fBoardVector)
+                for (auto cBoard : *cBiasSweep.fDetectorContainer)
                 {
-                    for (auto cFe : cBoard->fModuleVector)
-                    {
-                        for (auto cCbc : cFe->fReadoutChipVector)
+                    for (auto cOpticalGroup : *cBoard)
+                        for (auto cFe : *cOpticalGroup)
                         {
-
-                            for (auto cBias : cBiases)
+                            for (auto cCbc : *cFe)
                             {
-                                cDog.Reset (160);
-                                t.start();
-                                cBiasSweep.SweepBias (cBias, cCbc);
-                                t.stop();
-                                t.show ("Time for this bias");
-                            }
 
-                            cDog.Reset (25);
-                            cBiasSweep.MeasureMinPower (cBoard, cCbc);
+                                for (auto cBias : cBiases)
+                                {
+                                    cDog.Reset (160);
+                                    t.start();
+                                    cBiasSweep.SweepBias (cBias, static_cast<ReadoutChip*>(cCbc));
+                                    t.stop();
+                                    t.show ("Time for this bias");
+                                }
+
+                                cDog.Reset (25);
+                                cBiasSweep.MeasureMinPower (static_cast<BeBoard*>(cBoard), static_cast<ReadoutChip*>(cCbc));
+                            }
                         }
-                    }
                 }
             #endif
         }
@@ -333,7 +334,7 @@ int main ( int argc, char* argv[] )
             cTool.addFileHandler (cBinaryDataFileName, 'w');
             cTool.initializeFileHandler();
             cTool.ConfigureHw();
-            BeBoard* pBoard = cTool.fBoardVector.at ( 0 );
+            BeBoard* pBoard = static_cast<BeBoard*>(cTool.fDetectorContainer->at ( 0 ));
             uint32_t cN = 1;
             uint32_t cNthAcq = 0;
             uint32_t count = 0;
diff --git a/src/cic_datatest.cc b/src/cic_datatest.cc
index 120a59818..5c75a94ae 100644
--- a/src/cic_datatest.cc
+++ b/src/cic_datatest.cc
@@ -86,7 +86,7 @@ int main ( int argc, char* argv[] )
     CicFEAlignment cCicAligner;
     cCicAligner.Inherit (&cTool);
     cCicAligner.Initialise ( );
-    BeBoard* pBoard = cCicAligner.fBoardVector.at(0);
+    BeBoard* pBoard = static_cast<BeBoard*>(cCicAligner.fDetectorContainer->at(0));
 
     bool cPhaseAligned = cCicAligner.PhaseAlignment();
     if( cPhaseAligned )
@@ -108,14 +108,17 @@ int main ( int argc, char* argv[] )
                     cCicAligner.accept (cThresholdVisitor);
                 else
                 {
-                    for (auto& cFe : pBoard->fModuleVector)
+                    for(auto cOpticalGroup : *pBoard)
                     {
-                        for (auto& cChip : cFe->fReadoutChipVector)
+                        for (auto cFe : *cOpticalGroup)
                         {
-                            if( cChip->getChipId() == cFeChip )
+                            for (auto cChip : *cFe)
                             {
-                                cThresholdVisitor.setThreshold(cVcth);
-                                cChip->accept (cThresholdVisitor);
+                                if( cChip->getId() == cFeChip )
+                                {
+                                    cThresholdVisitor.setThreshold(cVcth);
+                                    static_cast<ReadoutChip*>(cChip)->accept (cThresholdVisitor);
+                                }
                             }
                         }
                     }
diff --git a/src/cic_test.cc b/src/cic_test.cc
index 19bfe906d..13efb3562 100644
--- a/src/cic_test.cc
+++ b/src/cic_test.cc
@@ -114,21 +114,13 @@ int main ( int argc, char* argv[] )
     bool cAllChannels = ( cmd.foundOption ( "allChan" ) ) ? true : false;
     int cTriggerRate = ( cmd.foundOption ( "triggerRate" ) ) ? convertAnyInt ( cmd.optionValue ( "triggerRate" ).c_str() ) : 10;
     bool cDisableStubLogic = ( cmd.foundOption ( "disableStubs" ) ) ;
-    uint8_t cTPamplitude = ( cmd.foundOption ( "testPulse" ) ) ?  (0xFF-convertAnyInt ( cmd.optionValue ( "testPulse" ).c_str() )) : 0 ;
     bool cDAQ =  cmd.foundOption ( "daq" );
     bool cDoCicAlignment =  cmd.foundOption ( "cicAlignment" );
-    bool cExternal =  cmd.foundOption ( "externalTriggers" );
-    uint16_t cNconsecutiveTriggers = ( cmd.foundOption ( "externalTriggers" ) ) ? convertAnyInt ( cmd.optionValue ( "externalTriggers" ).c_str() ) : 0;
-    bool cLatency = cmd.foundOption ( "latency" );
-    uint16_t cStartLatency = ( cmd.foundOption ( "minimum" ) ) ? convertAnyInt ( cmd.optionValue ( "minimum" ).c_str() ) :  10;
-    uint16_t cLatencyRange = ( cmd.foundOption ( "range" ) )   ?  convertAnyInt ( cmd.optionValue ( "range" ).c_str() ) :  10;
     int cSigma = cmd.foundOption ( "evaluate" ) ?  convertAnyInt ( cmd.optionValue ( "evaluate" ).c_str() ) :  3;
     bool cCheckOccupancy = cmd.foundOption ( "occupancyCheck" );
     bool cScopeL1A = cmd.foundOption ( "scopeL1Alignment" );
     bool cScopeStubs = cmd.foundOption ( "scopeStubAlignment" );
     
-    int cVcth = ( cmd.foundOption ( "vcth" ) ) ? convertAnyInt ( cmd.optionValue ( "vcth" ).c_str() ) : 550;
-
     cDirectory += Form("Cic_%s",cSerial.c_str());
     bool batchMode = ( cmd.foundOption ( "batch" ) ) ? true : false;
     TApplication cApp ( "Root Application", &argc, argv );
@@ -257,27 +249,30 @@ int main ( int argc, char* argv[] )
     if(cDataTest)
     {
         // data check with noise injection 
-        uint8_t cSeed=10;
-        uint8_t cBendCode=0;
-
+        
         t.start();
-        for( auto& cBoard : cExtra.fBoardVector )
+        for( auto& cBoard : *cExtra.fDetectorContainer )
         {
-            for (auto& cFe : cBoard->fModuleVector)
+            BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
+            for(auto cOpticalGroup : *cBoard)
             {
-                // matching 
-                uint16_t cTh1 = (cFe->getFeId()%2==0) ? 900 : 1; 
-                uint16_t cTh2 = (cFe->getFeId()%2==0) ? 1 : 900; 
-                for (auto& cChip : cFe->fReadoutChipVector) 
+                for (auto cFe : *cOpticalGroup)
                 {
-                    if( cChip->getChipId()%2 == 0 )
-                        static_cast<CbcInterface*>(cExtra.fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cTh1);
-                    else
-                        static_cast<CbcInterface*>(cExtra.fReadoutChipInterface)->WriteChipReg( cChip, "VCth" , cTh2);
+                    // matching 
+                    uint16_t cTh1 = (cFe->getId()%2==0) ? 900 : 1; 
+                    uint16_t cTh2 = (cFe->getId()%2==0) ? 1 : 900; 
+                    for (auto& cChip : *cFe) 
+                    {
+                        ReadoutChip* theChip = static_cast<ReadoutChip*>(cChip);
+                        if( cChip->getId()%2 == 0 )
+                            static_cast<CbcInterface*>(cExtra.fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cTh1);
+                        else
+                            static_cast<CbcInterface*>(cExtra.fReadoutChipInterface)->WriteChipReg( theChip, "VCth" , cTh2);
+                    }
                 }
             }
-            cExtra.ReadNEvents ( cBoard , 1);
-            const std::vector<Event*>& cEvents = cExtra.GetEvents ( cBoard );
+            cExtra.ReadNEvents ( theBoard , 1);
+            const std::vector<Event*>& cEvents = cExtra.GetEvents ( theBoard );
             uint32_t cN=0;
             for ( auto& cEvent : cEvents )
             {
diff --git a/src/cmtest.cc b/src/cmtest.cc
index 1784863b6..34ded602b 100644
--- a/src/cmtest.cc
+++ b/src/cmtest.cc
@@ -124,9 +124,9 @@ int main ( int argc, char* argv[] )
     // Set Vcth to pedestal, or overload with manual setting
     std::vector<double_t> cNoiseV;
     ThresholdVisitor cVisitor (cTool.fReadoutChipInterface, 0);
-    Module* cFe = cPedeNoise.fBoardVector.at (0)->fModuleVector.at (0);
+    ModuleContainer* cFe = cPedeNoise.fDetectorContainer->at(0)->at(0)->at(0);
     int i = 0;
-    for (auto cCbc : cFe->fReadoutChipVector)
+    for (auto cCbc : *cFe)
     {
 	uint16_t cPedestal = 0; //round (cPedeNoise.getPedestal (cCbc) );
 	double   cNoise    = 0.; //cPedeNoise.getNoise (cCbc);
@@ -134,9 +134,10 @@ int main ( int argc, char* argv[] )
 	
 	if (cManualVcth==0) 
 	{
+        ReadoutChip* theCbc = static_cast<ReadoutChip*>(cCbc);
 	    cVisitor.setThreshold (cPedestal+cPedestalShift);
-	    cVisitor.visitChip(*cCbc);      // Visit a specific CBC
-	    cCbc->accept (cVisitor); // Should probably make a special Visitor to set a vector of Vcth's
+	    cVisitor.visitReadoutChip(*theCbc);      // Visit a specific CBC
+	    theCbc->accept (cVisitor); // Should probably make a special Visitor to set a vector of Vcth's
 	    LOG (INFO) << BOLDRED << "CBC" << i << ": set threshold to pedestal ("<<cPedestal<<") plus "<<cPedestalShift<<": "<< cPedestal+cPedestalShift << RESET;
 	}
 	else 
diff --git a/src/convertSLink.cc b/src/convertSLink.cc
index 8006a7285..57ed79a30 100644
--- a/src/convertSLink.cc
+++ b/src/convertSLink.cc
@@ -240,8 +240,6 @@ int main ( int argc, char* argv[] )
 
     // now query the parsing results
     std::string rawFilename = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "";
-    int cNevents = cmd.foundOption ( "events" ) ?  convertAnyInt ( cmd.optionValue ( "events" ).c_str() ) :  0;
-    bool cDecode = ( cmd.foundOption ( "decode" ) );
     
     if ( rawFilename.empty() )
     {
@@ -262,8 +260,8 @@ int main ( int argc, char* argv[] )
     auto cLastLocation = rawFilename.find(".raw");
     std::string cRunNumber = rawFilename.substr(cFirstLocation+1 , cLastLocation  -  cFirstLocation - 1 );
     std::string cDAQFileName = cRunNumber + ".daq";
-    FileHandler* cDAQFileHandler = nullptr;
-    cDAQFileHandler = new FileHandler(cDAQFileName, 'w');
+    // FileHandler* cDAQFileHandler = nullptr;
+    // cDAQFileHandler = new FileHandler(cDAQFileName, 'w');
     LOG (INFO) << "Writing DAQ File to:   " << cDAQFileName << " - ConditionData, if present, parsed from " << cHWFile ;
     
     TString cDirectory = Form("Results/MiniSlinkConverter_%s", cRunNumber.c_str() );
@@ -272,7 +270,6 @@ int main ( int argc, char* argv[] )
     std::stringstream outp;
     LOG (INFO) << "HWfile=" << cHWFile;
     cTool.InitializeHw ( cHWFile, outp );
-    BeBoard* cBoard = cTool.fBoardVector.at(0);
     
     // Add File handler
     cTool.addFileHandler ( rawFilename, 'r' );
diff --git a/src/d19c_test.cc b/src/d19c_test.cc
index f822ae6fd..2fb96210a 100644
--- a/src/d19c_test.cc
+++ b/src/d19c_test.cc
@@ -318,10 +318,13 @@ int main ( int argc, char** argv )
                     std::cout << std::endl;
 
                     // reset the counters
-                    for(auto& cFe : pBoard->fModuleVector) {
-                        for(auto& cCbc : cFe->fReadoutChipVector) {
-                            for(uint8_t ch = 0; ch < NCHANNELS; ch++) {
-                                cChannelCounters[cFe->getFeId()][cCbc->getChipId()][ch] = 0;
+                    for(auto cOpticalGroup : *pBoard)
+                    {
+                        for(auto cFe : *cOpticalGroup) {
+                            for(auto cCbc : *cFe) {
+                                for(uint8_t ch = 0; ch < NCHANNELS; ch++) {
+                                    cChannelCounters[cFe->getId()][cCbc->getId()][ch] = 0;
+                                }
                             }
                         }
                     }
diff --git a/src/eudaqproducer.cc b/src/eudaqproducer.cc
index d152cf23a..f447480b0 100644
--- a/src/eudaqproducer.cc
+++ b/src/eudaqproducer.cc
@@ -41,10 +41,8 @@ int main ( int argc, char** argv )
     // get values
     std::string cRunControlAddress = ( cmd.foundOption ( "runcontrol" ) ) ? cmd.optionValue ( "runcontrol" ) : "tcp://localhost:44000";
     std::string cName = ( cmd.foundOption ( "name" ) ) ? cmd.optionValue ( "name" ) : "ph2producer";
-    bool cSaveToFile = false;     
     std::string cOutputFile;     
-    if ( cmd.foundOption ( "save" ) )  cSaveToFile = true ;
-
+    
     // create eudaq2 producer (if need can also create eudaq1 here)
     #ifdef __EUDAQ__
         Eudaq2Producer cProducer(cName, cRunControlAddress);
diff --git a/src/feh_2s_test.cc b/src/feh_2s_test.cc
index 6ba7f60a1..d656bc421 100644
--- a/src/feh_2s_test.cc
+++ b/src/feh_2s_test.cc
@@ -105,8 +105,6 @@ int main ( int argc, char* argv[] )
     bool cCheckData = ( cmd.foundOption ( "checkData" ) ) ;
     bool cEvaluate = ( cmd.foundOption ( "evaluate" ) ) ;
     
-    int  cAntennaDelay = ( cmd.foundOption ( "antennaDelay" ) )   ?  convertAnyInt ( cmd.optionValue ( "antennaDelay" ).c_str() ) : -1;
-    int  cLatencyRange = ( cmd.foundOption ( "latencyRange" ) )   ?  convertAnyInt ( cmd.optionValue ( "latencyRange" ).c_str() ) :  -1;
     uint32_t  cThreshold = ( cmd.foundOption ( "threshold" ) )   ?  convertAnyInt ( cmd.optionValue ( "threshold" ).c_str() ) :  560 ;
     std::string cHybridId = ( cmd.foundOption ( "hybridId" ) ) ? cmd.optionValue ( "hybridId" ) : "xxxx";
     std::string cDirectory = ( cmd.foundOption ( "output" ) ) ? cmd.optionValue ( "output" ) : "Results/";
diff --git a/src/fpgaconfig.cc b/src/fpgaconfig.cc
index f5fa3a2ea..0d1471271 100644
--- a/src/fpgaconfig.cc
+++ b/src/fpgaconfig.cc
@@ -113,7 +113,7 @@ int main ( int argc, char* argv[] )
   std::string cHWFile = ( cmd.foundOption ( "config" ) ) ? cmd.optionValue ( "config" ) : "settings/HWDescription_2CBC.xml";
   std::ostringstream cStr;
   cSystemController.InitializeHw ( cHWFile, cStr );
-  BeBoard* pBoard = cSystemController.fBoardVector.at (0);
+  BeBoard* pBoard = static_cast<BeBoard*>(cSystemController.fDetectorContainer->at (0));
   vector<string> lstNames = cSystemController.fBeBoardInterface->getFpgaConfigList (pBoard);
   std::string cFWFile;
   string strImage ("1");
diff --git a/src/miniDAQ.cc b/src/miniDAQ.cc
index ad0c449af..3e2481af5 100644
--- a/src/miniDAQ.cc
+++ b/src/miniDAQ.cc
@@ -122,7 +122,7 @@ int main ( int argc, char* argv[] )
     outp.str ("");
     cSystemController.ConfigureHw ();
 
-    BeBoard* pBoard = cSystemController.fBoardVector.at ( 0 );
+    BeBoard* pBoard = static_cast<BeBoard*>(cSystemController.fDetectorContainer->at ( 0 ));
 
     // make event counter start at 1 as does the L1A counter
     uint32_t cN = 1;
diff --git a/src/mux_setup.cc b/src/mux_setup.cc
index 077641008..c55ac6c5d 100644
--- a/src/mux_setup.cc
+++ b/src/mux_setup.cc
@@ -51,8 +51,7 @@ int main ( int argc, char** argv )
     bool cMuxScan = ( cmd.foundOption ( "mux_scan" ) ) ? true : false;
     bool cMuxConfigure = ( cmd.foundOption ( "mux_configure" ) ) ? true : false;
     bool cMuxAutoConfigure = ( cmd.foundOption ( "mux_auto_configure" ) ) ? true : false;
-    bool cPowerEnable = ( cmd.foundOption ( "enable_fmc_power" ) ) ? true : false;
-
+    
     // now query the parsing results
     std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/D19CHWDescription.xml";
 
diff --git a/tools/BackEndAlignment.cc b/tools/BackEndAlignment.cc
index b4497d1d4..290ab112a 100644
--- a/tools/BackEndAlignment.cc
+++ b/tools/BackEndAlignment.cc
@@ -72,7 +72,7 @@ void BackEndAlignment::Initialise ()
         {
             for (auto cHybrid : *cOpticalReadout)
             {
-                auto& cRegMapThisHybrid = cRegMapThisBoard->at(cHybrid->getIndex());
+                auto& cRegMapThisHybrid = cRegMapThisBoard->at(cOpticalReadout->getIndex())->at(cHybrid->getIndex());
                 for (auto cChip : *cHybrid)
                 {
                     cRegMapThisHybrid->at(cChip->getIndex())->getSummary<ChipRegMap>() = static_cast<ReadoutChip*>(cChip)->getRegMap();
@@ -268,7 +268,6 @@ bool BackEndAlignment::Align()
         BeBoard* theBoard = static_cast<BeBoard*>(cBoard);
         // read back register map before you've done anything 
         auto cBoardRegisterMap = theBoard->getBeBoardRegMap();
-        auto& cRegMapThisBoard = fRegMapContainer.at(cBoard->getIndex());
         
         OuterTrackerModule* theFirstHibrid = static_cast<OuterTrackerModule*>(cBoard->at(0)->at(0));
         bool cWithCIC = theFirstHibrid->fCic != NULL;
diff --git a/tools/ShortFinder.cc b/tools/ShortFinder.cc
index bdcff1fc5..f59613374 100644
--- a/tools/ShortFinder.cc
+++ b/tools/ShortFinder.cc
@@ -44,7 +44,6 @@ void ShortFinder::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
     ContainerFactory::copyAndInitChannel<int>(*fDetectorContainer, fShortsContainer);
     uint8_t cFirmwareTPdelay=100;
     uint8_t cFirmwareTriggerDelay=200;
-    uint16_t cDefaultStubLatency=50; 
     
     // set-up for TP
     fAllChan = true;
@@ -63,7 +62,6 @@ void ShortFinder::FindShorts(uint16_t pThreshold, uint16_t pTPamplitude)
         //first, set VCth to the target value for each CBC
         this->setSameDacBeBoard(theBoard , "VCth", pThreshold);
         auto& cThisShortsContainer = fShortsContainer.at(cBoard->getIndex());
-        uint16_t cMinValue=0;
         uint16_t cDelay = fBeBoardInterface->ReadBoardReg( theBoard, "fc7_daq_cnfg.fast_command_block.test_pulse.delay_after_test_pulse") ;
         this->setSameDacBeBoard(theBoard, "TriggerLatency", cDelay-1);
         uint8_t cTestGroup=0;
diff --git a/tools/StubQuickCheck.cc b/tools/StubQuickCheck.cc
index 883b0db10..d81cf1a5d 100644
--- a/tools/StubQuickCheck.cc
+++ b/tools/StubQuickCheck.cc
@@ -159,7 +159,6 @@ void StubQuickCheck::StubCheck(BeBoard* pBoard, const std::vector<Event*> pEvent
         auto cEventCount = cEvent->GetEventCount(); 
         auto cTDC = cEvent->GetTDC();
         std::vector<uint32_t> cBxIds(0);
-        bool cGoodEvent=false;
         
         LOG (DEBUG) << BOLDBLUE << "Event " << +cEventCount << " --- TDC  " << +cTDC << RESET;
         std::vector<double> cSeeds(0);
@@ -173,7 +172,6 @@ void StubQuickCheck::StubCheck(BeBoard* pBoard, const std::vector<Event*> pEvent
                 TH2D* cStubHitCorrelation = static_cast<TH2D*> ( getHist ( cFe, Form("StubHitCorrelation") ) );
 
                 auto cBxId = cEvent->BxId( cFe->getId() );
-                auto cStatus = static_cast<D19cCicEvent*>(cEvent)->Status ( cFe->getId() );
                 LOG (DEBUG) << BOLDBLUE << "FE" << +cFe->getId() << " BxId " << +cBxId << RESET; 
                 if ( std::find(cBxIds.begin(), cBxIds.end(), cBxId) == cBxIds.end() )
                     cBxIds.push_back(cBxId);
-- 
GitLab


From 3b87fcdb5b26e38b4c4248792442e95e9f9c9ed5 Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 21:32:36 -0500
Subject: [PATCH 7/9] Working in So

---
 setup.sh           | 8 ++++----
 tools/BiasSweep.cc | 4 ++--
 tools/BiasSweep.h  | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/setup.sh b/setup.sh
index a15fe8787..2ae25819e 100755
--- a/setup.sh
+++ b/setup.sh
@@ -82,12 +82,12 @@ export EuDaqFlag='-D__EUDAQ__'
 ################
 
 # Stand-alone application, without data streaming
-export CompileForHerd=false
-export CompileForShep=false
+# export CompileForHerd=false
+# export CompileForShep=false
 
 # Stand-alone application, with data streaming
-# export CompileForHerd=true
-# export CompileForShep=true
+export CompileForHerd=true
+export CompileForShep=true
 
 # Herd application
 # export CompileForHerd=true
diff --git a/tools/BiasSweep.cc b/tools/BiasSweep.cc
index 4b4554036..cb399b1c3 100644
--- a/tools/BiasSweep.cc
+++ b/tools/BiasSweep.cc
@@ -1,5 +1,5 @@
 #include "BiasSweep.h"
-// #ifdef __USE_ROOT__
+#ifdef __USE_ROOT__
 
 void BiasSweep::InitializeAmuxMap()
 {
@@ -760,4 +760,4 @@ void BiasSweep::StopDAQ()
     //}
 }
 
-// #endif
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/tools/BiasSweep.h b/tools/BiasSweep.h
index 0355ba122..64ff1ab78 100644
--- a/tools/BiasSweep.h
+++ b/tools/BiasSweep.h
@@ -13,7 +13,7 @@
 #ifndef __BIASSWEEP_H__
 #define __BIASSWEEP_H__
 
-// #ifdef __USE_ROOT__
+#ifdef __USE_ROOT__
 
 #include "Tool.h"
 #include <map>
@@ -131,4 +131,4 @@ class BiasSweep : public Tool
 
 
 #endif
-// #endif
+#endif
-- 
GitLab


From 91fda40afd2d7af30c41a8c60f21b1b4a1dfaf6a Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 21:36:14 -0500
Subject: [PATCH 8/9] Reverted setup.sh

---
 setup.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/setup.sh b/setup.sh
index 2ae25819e..a15fe8787 100755
--- a/setup.sh
+++ b/setup.sh
@@ -82,12 +82,12 @@ export EuDaqFlag='-D__EUDAQ__'
 ################
 
 # Stand-alone application, without data streaming
-# export CompileForHerd=false
-# export CompileForShep=false
+export CompileForHerd=false
+export CompileForShep=false
 
 # Stand-alone application, with data streaming
-export CompileForHerd=true
-export CompileForShep=true
+# export CompileForHerd=true
+# export CompileForShep=true
 
 # Herd application
 # export CompileForHerd=true
-- 
GitLab


From 9a9005330709e5dfe0cdd62f03deaffa0157e792 Mon Sep 17 00:00:00 2001
From: Fabio Ravera <fabio.ravera@cern.ch>
Date: Mon, 6 Apr 2020 21:41:29 -0500
Subject: [PATCH 9/9] Updated xml files

---
 settings/CMSIT.xml                          | 204 ++++++++++----------
 settings/D19CDescriptionSSA.xml             |  10 +-
 settings/D19CDescription_Cic.xml            |  98 +++++-----
 settings/D19CDescription_Cic2.xml           | 100 +++++-----
 settings/D19CDescription_Commission.xml     |  40 ++--
 settings/D19CDescription_SignalScanTest.xml |  32 +--
 settings/D19CDescription_backplane.xml      |  44 +++--
 settings/D19CDescription_forAntenna.xml     |  26 +--
 settings/D19CDescription_optical.xml        |  86 +++++----
 settings/D19C_2xSSA_Calib.xml               |  12 +-
 settings/D19C_2xSSA_onechip.xml             |  12 +-
 11 files changed, 343 insertions(+), 321 deletions(-)

diff --git a/settings/CMSIT.xml b/settings/CMSIT.xml
index 64d88b0f4..a30652e83 100755
--- a/settings/CMSIT.xml
+++ b/settings/CMSIT.xml
@@ -8,108 +8,110 @@
     -->
 
     <!-- Frontend chip configuration -->
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-      <RD53_Files path="./" />
-
-      <RD53 Id="0" Lane="0" configfile="CMSIT_RD53.txt">
-        <!-- Overwrite .txt configuration file settings -->
-        <Settings
-            PA_IN_BIAS_LIN        =  "350"
-            FC_BIAS_LIN           =   "20"
-            KRUM_CURR_LIN         =   "29"
-            LDAC_LIN              =  "130"
-            COMP_LIN              =  "110"
-            REF_KRUM_LIN          =  "300"
-            Vthreshold_LIN        =  "400"
-
-            IBIASP1_SYNC          =  "100"
-            IBIASP2_SYNC          =  "150"
-            IBIAS_SF_SYNC         =   "80"
-            IBIAS_KRUM_SYNC       =   "55"
-            IBIAS_DISC_SYNC       =  "280"
-            ICTRL_SYNCT_SYNC      =  "100"
-            VBL_SYNC              =  "360"
-            VTH_SYNC              =  "400"
-            VREF_KRUM_SYNC        =  "450"
-            CONF_FE_SYNC          =    "2"
-
-            PRMP_DIFF             =  "511"
-            FOL_DIFF              =  "542"
-            PRECOMP_DIFF          =  "512"
-            COMP_DIFF             = "1023"
-            VFF_DIFF              =   "40"
-            VTH1_DIFF             =  "600"
-            VTH2_DIFF             =  "100"
-            LCC_DIFF              =   "20"
-            CONF_FE_DIFF          =    "0"
-
-            VCAL_HIGH             =  "600"
-            VCAL_MED              =  "100"
-
-            GP_LVDS_ROUTE         =    "0"
-            LATENCY_CONFIG        =  "136"
-            CLK_DATA_DELAY        =    "0"
-            INJECTION_SELECT      =    "9"
-
-            VOLTAGE_TRIM          =  "528"
-
-            ADC_MONITOR_CONFIG    =    "5"
-            BG_MONITOR_CONFIG     =   "12"
-            ADC_OFFSET_VOLT       =   "63"
-            ADC_MAXIMUM_VOLT      =  "839"
-            TEMPSENS_IDEAL_FACTOR = "1225"
+    <OpticalGroup Id="0" FMCId="0" >
+      <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+        <RD53_Files path="./" />
+
+        <RD53 Id="0" Lane="0" configfile="CMSIT_RD53.txt">
+          <!-- Overwrite .txt configuration file settings -->
+          <Settings
+              PA_IN_BIAS_LIN        =  "350"
+              FC_BIAS_LIN           =   "20"
+              KRUM_CURR_LIN         =   "29"
+              LDAC_LIN              =  "130"
+              COMP_LIN              =  "110"
+              REF_KRUM_LIN          =  "300"
+              Vthreshold_LIN        =  "400"
+
+              IBIASP1_SYNC          =  "100"
+              IBIASP2_SYNC          =  "150"
+              IBIAS_SF_SYNC         =   "80"
+              IBIAS_KRUM_SYNC       =   "55"
+              IBIAS_DISC_SYNC       =  "280"
+              ICTRL_SYNCT_SYNC      =  "100"
+              VBL_SYNC              =  "360"
+              VTH_SYNC              =  "400"
+              VREF_KRUM_SYNC        =  "450"
+              CONF_FE_SYNC          =    "2"
+
+              PRMP_DIFF             =  "511"
+              FOL_DIFF              =  "542"
+              PRECOMP_DIFF          =  "512"
+              COMP_DIFF             = "1023"
+              VFF_DIFF              =   "40"
+              VTH1_DIFF             =  "600"
+              VTH2_DIFF             =  "100"
+              LCC_DIFF              =   "20"
+              CONF_FE_DIFF          =    "0"
+
+              VCAL_HIGH             =  "600"
+              VCAL_MED              =  "100"
+
+              GP_LVDS_ROUTE         =    "0"
+              LATENCY_CONFIG        =  "136"
+              CLK_DATA_DELAY        =    "0"
+              INJECTION_SELECT      =    "9"
+
+              VOLTAGE_TRIM          =  "528"
+
+              ADC_MONITOR_CONFIG    =    "5"
+              BG_MONITOR_CONFIG     =   "12"
+              ADC_OFFSET_VOLT       =   "63"
+              ADC_MAXIMUM_VOLT      =  "839"
+              TEMPSENS_IDEAL_FACTOR = "1225"
+              />
+          <!--
+              Monitoring: ADC_MONITOR_CONFIG, BG_MONITOR_CONFIG, ADC_OFFSET_VOLT, ADC_MAXIMUM_VOLT, TEMPSENS_IDEAL_FACTOR
+              CLK_DATA_DELAY: [8] clk phase; [7:4] clk delay; [3:0] data delay
+          -->
+        </RD53>
+
+        <Global
+            EN_CORE_COL_SYNC        =     "0"
+            EN_CORE_COL_LIN_1       = "65535"
+            EN_CORE_COL_LIN_2       =     "1"
+            EN_CORE_COL_DIFF_1      =     "0"
+            EN_CORE_COL_DIFF_2      =     "0"
+
+            EN_MACRO_COL_CAL_LIN_1  = "65535"
+            EN_MACRO_COL_CAL_LIN_2  = "65535"
+            EN_MACRO_COL_CAL_LIN_3  = "65535"
+            EN_MACRO_COL_CAL_LIN_4  = "65535"
+            EN_MACRO_COL_CAL_LIN_5  =    "15"
+
+            EN_MACRO_COL_CAL_SYNC_1 = "65535"
+            EN_MACRO_COL_CAL_SYNC_2 = "65535"
+            EN_MACRO_COL_CAL_SYNC_3 = "65535"
+            EN_MACRO_COL_CAL_SYNC_4 = "65535"
+
+            EN_MACRO_COL_CAL_DIFF_1 = "65535"
+            EN_MACRO_COL_CAL_DIFF_2 = "65535"
+            EN_MACRO_COL_CAL_DIFF_3 = "65535"
+            EN_MACRO_COL_CAL_DIFF_4 = "65535"
+            EN_MACRO_COL_CAL_DIFF_5 =    "15"
+
+            HITOR_0_MASK_SYNC       = "65535"
+            HITOR_1_MASK_SYNC       = "65535"
+            HITOR_2_MASK_SYNC       = "65535"
+            HITOR_3_MASK_SYNC       = "65535"
+
+            HITOR_0_MASK_DIFF_0     = "65535"
+            HITOR_0_MASK_DIFF_1     =     "1"
+            HITOR_1_MASK_DIFF_0     = "65535"
+            HITOR_1_MASK_DIFF_1     =     "1"
+            HITOR_2_MASK_DIFF_0     = "65535"
+            HITOR_2_MASK_DIFF_1     =     "1"
+            HITOR_3_MASK_DIFF_0     = "65535"
+            HITOR_3_MASK_DIFF_1     =     "1"
+
+            LOCKLOSS_CNT            =     "0"
+            BITFLIP_WNG_CNT         =     "0"
+            BITFLIP_ERR_CNT         =     "0"
+            CMDERR_CNT              =     "0"
+            SKIPPED_TRIGGER_CNT     =     "0"
             />
-        <!--
-            Monitoring: ADC_MONITOR_CONFIG, BG_MONITOR_CONFIG, ADC_OFFSET_VOLT, ADC_MAXIMUM_VOLT, TEMPSENS_IDEAL_FACTOR
-            CLK_DATA_DELAY: [8] clk phase; [7:4] clk delay; [3:0] data delay
-        -->
-      </RD53>
-
-      <Global
-          EN_CORE_COL_SYNC        =     "0"
-          EN_CORE_COL_LIN_1       = "65535"
-          EN_CORE_COL_LIN_2       =     "1"
-          EN_CORE_COL_DIFF_1      =     "0"
-          EN_CORE_COL_DIFF_2      =     "0"
-
-          EN_MACRO_COL_CAL_LIN_1  = "65535"
-          EN_MACRO_COL_CAL_LIN_2  = "65535"
-          EN_MACRO_COL_CAL_LIN_3  = "65535"
-          EN_MACRO_COL_CAL_LIN_4  = "65535"
-          EN_MACRO_COL_CAL_LIN_5  =    "15"
-
-          EN_MACRO_COL_CAL_SYNC_1 = "65535"
-          EN_MACRO_COL_CAL_SYNC_2 = "65535"
-          EN_MACRO_COL_CAL_SYNC_3 = "65535"
-          EN_MACRO_COL_CAL_SYNC_4 = "65535"
-
-          EN_MACRO_COL_CAL_DIFF_1 = "65535"
-          EN_MACRO_COL_CAL_DIFF_2 = "65535"
-          EN_MACRO_COL_CAL_DIFF_3 = "65535"
-          EN_MACRO_COL_CAL_DIFF_4 = "65535"
-          EN_MACRO_COL_CAL_DIFF_5 =    "15"
-
-          HITOR_0_MASK_SYNC       = "65535"
-          HITOR_1_MASK_SYNC       = "65535"
-          HITOR_2_MASK_SYNC       = "65535"
-          HITOR_3_MASK_SYNC       = "65535"
-
-          HITOR_0_MASK_DIFF_0     = "65535"
-          HITOR_0_MASK_DIFF_1     =     "1"
-          HITOR_1_MASK_DIFF_0     = "65535"
-          HITOR_1_MASK_DIFF_1     =     "1"
-          HITOR_2_MASK_DIFF_0     = "65535"
-          HITOR_2_MASK_DIFF_1     =     "1"
-          HITOR_3_MASK_DIFF_0     = "65535"
-          HITOR_3_MASK_DIFF_1     =     "1"
-
-          LOCKLOSS_CNT            =     "0"
-          BITFLIP_WNG_CNT         =     "0"
-          BITFLIP_ERR_CNT         =     "0"
-          CMDERR_CNT              =     "0"
-          SKIPPED_TRIGGER_CNT     =     "0"
-          />
-    </Module>
+      </Module>
+    </OpticalGroup>
 
     <!-- Configuration for backend readout board -->
     <Register name="user">
diff --git a/settings/D19CDescriptionSSA.xml b/settings/D19CDescriptionSSA.xml
index 83ae58e80..431aa118e 100644
--- a/settings/D19CDescriptionSSA.xml
+++ b/settings/D19CDescriptionSSA.xml
@@ -2,10 +2,12 @@
 <HwDescription>
   <BeBoard Id="0" boardType="D19C" eventType="VR">
       <connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.1.51:50001" address_table="file://settings/address_tables/d19c_address_table.xml" />
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <SSA_Files path="./settings/SSAFiles/" />
-        <SSA Id="0" side="0" configfile="SSA_AllStrips.txt" />
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <SSA_Files path="./settings/SSAFiles/" />
+            <SSA Id="0" side="0" configfile="SSA_AllStrips.txt" />
+        </Module>
+    </OpticalGroup>
 
     <!--CONFIG-->
     <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 -->
diff --git a/settings/D19CDescription_Cic.xml b/settings/D19CDescription_Cic.xml
index 7d549ea29..c81603ba3 100755
--- a/settings/D19CDescription_Cic.xml
+++ b/settings/D19CDescription_Cic.xml
@@ -13,54 +13,56 @@
     </GBT_Links>
     
     <!-- RHS --> 
-    <!-- <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="500" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
-            <ChannelMask disable=""/>
-            <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
-
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
-
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC Id="8" configfile="CIC_default.txt" />
-    </Module> -->
-
-    <!-- LHS --> 
-    <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="500" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
-            <ChannelMask disable=""/>
-            <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
-
-        <CBC_Files path="./Results/FEH_2S_xxxx_Electron_15-03-20_21h19m22/" />
-        <CBC Id="0" configfile="BE0_FE1_Chip0.txt" />
-        <CBC Id="1" configfile="BE0_FE1_Chip1.txt" />
-        <CBC Id="2" configfile="BE0_FE1_Chip2.txt" />
-        <CBC Id="3" configfile="BE0_FE1_Chip3.txt" />
-        <CBC Id="4" configfile="BE0_FE1_Chip4.txt" />
-        <CBC Id="5" configfile="BE0_FE1_Chip5.txt" />
-        <CBC Id="6" configfile="BE0_FE1_Chip6.txt" />
-        <CBC Id="7" configfile="BE0_FE1_Chip7.txt" />
-
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC Id="8" configfile="CIC_default.txt" />
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <!-- <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="500" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
+                <ChannelMask disable=""/>
+                <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
+
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
+
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC Id="8" configfile="CIC_default.txt" />
+        </Module> -->
+
+        <!-- LHS --> 
+        <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="500" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
+                <ChannelMask disable=""/>
+                <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
+
+            <CBC_Files path="./Results/FEH_2S_xxxx_Electron_15-03-20_21h19m22/" />
+            <CBC Id="0" configfile="BE0_FE1_Chip0.txt" />
+            <CBC Id="1" configfile="BE0_FE1_Chip1.txt" />
+            <CBC Id="2" configfile="BE0_FE1_Chip2.txt" />
+            <CBC Id="3" configfile="BE0_FE1_Chip3.txt" />
+            <CBC Id="4" configfile="BE0_FE1_Chip4.txt" />
+            <CBC Id="5" configfile="BE0_FE1_Chip5.txt" />
+            <CBC Id="6" configfile="BE0_FE1_Chip6.txt" />
+            <CBC Id="7" configfile="BE0_FE1_Chip7.txt" />
+
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC Id="8" configfile="CIC_default.txt" />
+        </Module>
+    </OpticalGroup>
 
 
     <SLink>
diff --git a/settings/D19CDescription_Cic2.xml b/settings/D19CDescription_Cic2.xml
index 761ddd51b..8ed0af757 100755
--- a/settings/D19CDescription_Cic2.xml
+++ b/settings/D19CDescription_Cic2.xml
@@ -12,55 +12,57 @@
     </GBT_Links>
     
     <!-- RHS --> 
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="550" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
-            <ChannelMask disable=""/>
-            <CIC2 enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
-
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
-
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC2 Id="8" configfile="CIC2_default.txt" />
-    </Module>
-
-    <!-- LHS --> 
- <!--    <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="550" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
-            <ChannelMask disable=""/>
-            <CIC2 enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
-
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
-
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC2 Id="8" configfile="CIC2_default.txt" />
-    </Module> 
- -->
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="550" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
+                <ChannelMask disable=""/>
+                <CIC2 enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
+
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
+
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC2 Id="8" configfile="CIC2_default.txt" />
+        </Module>
+
+        <!-- LHS --> 
+    <!--    <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="550" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
+                <ChannelMask disable=""/>
+                <CIC2 enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
+
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
+
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC2 Id="8" configfile="CIC2_default.txt" />
+        </Module> 
+    -->
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
diff --git a/settings/D19CDescription_Commission.xml b/settings/D19CDescription_Commission.xml
index a6460eab2..28c61e785 100755
--- a/settings/D19CDescription_Commission.xml
+++ b/settings/D19CDescription_Commission.xml
@@ -3,26 +3,28 @@
   <BeBoard Id="0" boardType="D19C" eventType="VR">
         <connection id="board" uri="chtcp-2.0://127.0.0.1:10203?target=192.168.0.7:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> 
 
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <Global>
-            <Settings threshold="540" latency="199"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFA" channelgroup="0" delay="7" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="0" tpgclock="1" testclock="1" dll="11"/>
-            <ChannelMask disable=""/>
-        </Global>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <Global>
+                <Settings threshold="540" latency="199"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFA" channelgroup="0" delay="7" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="0" tpgclock="1" testclock="1" dll="11"/>
+                <ChannelMask disable=""/>
+            </Global>
 
-        <CBC_Files path="./Results/Calibration_Electron_22-01-20_20h26m47/" />
-        <CBC Id="0" configfile="BE0_FE0_Chip0.txt" />
-        <CBC Id="1" configfile="BE0_FE0_Chip1.txt" />
-        <!-- <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
-        <CIC Id="8" configfile="CIC_default.txt" /> -->
-    </Module>
+            <CBC_Files path="./Results/Calibration_Electron_22-01-20_20h26m47/" />
+            <CBC Id="0" configfile="BE0_FE0_Chip0.txt" />
+            <CBC Id="1" configfile="BE0_FE0_Chip1.txt" />
+            <!-- <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
+            <CIC Id="8" configfile="CIC_default.txt" /> -->
+        </Module>
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
diff --git a/settings/D19CDescription_SignalScanTest.xml b/settings/D19CDescription_SignalScanTest.xml
index 06d434028..3f084765b 100755
--- a/settings/D19CDescription_SignalScanTest.xml
+++ b/settings/D19CDescription_SignalScanTest.xml
@@ -4,21 +4,23 @@
     <!--<connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.0.7:50001" address_table="file://settings/address_tables/d19c_address_table.xml" />-->
     <connection id="board" uri="chtcp-2.0://cmsuptracker003.cern.ch:10203?target=192.168.0.50:50001" address_table="file://settings/address_tables/d19c_address_table_SignalScanTest.xml" />
 
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <Global>
-            <Settings threshold="550" latency="26"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="0"/>
-            <ClusterStub clusterwidth="4" ptwidth="3" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="4"/>
-            <ChannelMask disable=""/>
-        </Global>
-        <CBC_Files path="./Results/Calibration_Electron_25-06-19_15h30/" />
-        <CBC Id="0" configfile="FE0CBC0.txt" />
-        <CBC Id="1" configfile="FE0CBC1.txt" />
-        <!-- <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" /> -->
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <Global>
+                <Settings threshold="550" latency="26"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="0"/>
+                <ClusterStub clusterwidth="4" ptwidth="3" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="4"/>
+                <ChannelMask disable=""/>
+            </Global>
+            <CBC_Files path="./Results/Calibration_Electron_25-06-19_15h30/" />
+            <CBC Id="0" configfile="FE0CBC0.txt" />
+            <CBC Id="1" configfile="FE0CBC1.txt" />
+            <!-- <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" /> -->
+        </Module>
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
diff --git a/settings/D19CDescription_backplane.xml b/settings/D19CDescription_backplane.xml
index aefedc961..7a435649c 100755
--- a/settings/D19CDescription_backplane.xml
+++ b/settings/D19CDescription_backplane.xml
@@ -4,29 +4,31 @@
       <connection id="board" uri="chtcp-2.0://hybridtesting:10203?target=192.168.0.9:50001" address_table="file://settings/address_tables/uDTC_OT_address_table.xml" />
       <!-- <connection id="board" uri="chtcp-2.0://cmsuptkhsetup2.cern.ch:10203?target=192.168.0.9:50001" address_table="file://settings/address_tables/uDTC_OT_address_table.xml" /> -->
 
-    <Module FeId="0" FMCId="0" ModuleId="1" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="500" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
-            <ChannelMask disable=""/>
-            <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="1" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="500" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="0" dll="0"/>
+                <ChannelMask disable=""/>
+                <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
 
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
 
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC Id="8" configfile="CIC_default.txt" />
-    </Module>
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC Id="8" configfile="CIC_default.txt" />
+        </Module>
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
diff --git a/settings/D19CDescription_forAntenna.xml b/settings/D19CDescription_forAntenna.xml
index 351a7f68d..5287882ee 100755
--- a/settings/D19CDescription_forAntenna.xml
+++ b/settings/D19CDescription_forAntenna.xml
@@ -5,18 +5,20 @@
 
       <!-- <connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.0.7:50001" address_table="file://settings/address_tables/d19c_address_table.xml" /> -->
 
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <Global>
-            <Settings threshold="280" latency="196"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="4"/>
-            <ChannelMask disable=""/>
-        </Global>
-        <CBC_Files path="./Results/Calibration_Electron_19-12-18_09h45" />
-        <CBC Id="0" configfile="FE0CBC0.txt" />
-        <CBC Id="1" configfile="FE0CBC1.txt" />
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <Global>
+                <Settings threshold="280" latency="196"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="4"/>
+                <ChannelMask disable=""/>
+            </Global>
+            <CBC_Files path="./Results/Calibration_Electron_19-12-18_09h45" />
+            <CBC Id="0" configfile="FE0CBC0.txt" />
+            <CBC Id="1" configfile="FE0CBC1.txt" />
+        </Module>
+    </OpticalGroup>
 
     <SLink>
         <DebugMode type="FULL"/>
diff --git a/settings/D19CDescription_optical.xml b/settings/D19CDescription_optical.xml
index ad58f56dc..79ff629d1 100755
--- a/settings/D19CDescription_optical.xml
+++ b/settings/D19CDescription_optical.xml
@@ -9,53 +9,55 @@
 
     <CDCE configure = "0"/>
    
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="500" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
-            <ChannelMask disable=""/>
-            <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="500" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
+                <ChannelMask disable=""/>
+                <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
 
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
 
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC Id="8" configfile="CIC_default.txt" />
-    </Module>
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC Id="8" configfile="CIC_default.txt" />
+        </Module>
 
-    <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
-        <Global>
-            <Settings threshold="500" latency="19"/>
-            <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
-            <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
-            <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
-            <ChannelMask disable=""/>
-            <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
-        </Global>
+        <Module FeId="1" FMCId="0" ModuleId="0" Status="1" LinkId="0">
+            <Global>
+                <Settings threshold="500" latency="19"/>
+                <TestPulse enable="0" polarity="0" amplitude="0xFF" channelgroup="0" delay="0" groundothers="1"/>
+                <ClusterStub clusterwidth="4" ptwidth="14" layerswap="0" off1="0" off2="0" off3="0" off4="0"/>
+                <Misc analogmux="0b00000" pipelogic="0" stublogic="0" or254="1" tpgclock="1" testclock="1" dll="1"/>
+                <ChannelMask disable=""/>
+                <CIC enableBend="1" enableLastLine="0" enableSparsification="0" clockFrequency="320"/>
+            </Global>
 
-        <CBC_Files path="./settings/CbcFiles/" />
-        <CBC Id="0" configfile="CBC3_default.txt" />
-        <CBC Id="1" configfile="CBC3_default.txt" />
-        <CBC Id="2" configfile="CBC3_default.txt" />
-        <CBC Id="3" configfile="CBC3_default.txt" />
-        <CBC Id="4" configfile="CBC3_default.txt" />
-        <CBC Id="5" configfile="CBC3_default.txt" />
-        <CBC Id="6" configfile="CBC3_default.txt" />
-        <CBC Id="7" configfile="CBC3_default.txt" />
+            <CBC_Files path="./settings/CbcFiles/" />
+            <CBC Id="0" configfile="CBC3_default.txt" />
+            <CBC Id="1" configfile="CBC3_default.txt" />
+            <CBC Id="2" configfile="CBC3_default.txt" />
+            <CBC Id="3" configfile="CBC3_default.txt" />
+            <CBC Id="4" configfile="CBC3_default.txt" />
+            <CBC Id="5" configfile="CBC3_default.txt" />
+            <CBC Id="6" configfile="CBC3_default.txt" />
+            <CBC Id="7" configfile="CBC3_default.txt" />
 
-        <CIC_Files path="./settings/CicFiles/" />
-        <CIC Id="8" configfile="CIC_default.txt" />
-    </Module>
+            <CIC_Files path="./settings/CicFiles/" />
+            <CIC Id="8" configfile="CIC_default.txt" />
+        </Module>
+    </OpticalGroup>
 
 
     <SLink>
diff --git a/settings/D19C_2xSSA_Calib.xml b/settings/D19C_2xSSA_Calib.xml
index 3fb7882f0..f98b072c7 100644
--- a/settings/D19C_2xSSA_Calib.xml
+++ b/settings/D19C_2xSSA_Calib.xml
@@ -2,11 +2,13 @@
 <HwDescription>
   <BeBoard Id="0" boardType="D19C" eventType="SSA">
       <connection id="board" uri="chtcp-2.0://localhost:10203?target=198.162.4.11:50001" address_table="file://settings/address_tables/d19c_MT_address_table.xml" />
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <SSA_Files path="./settings/SSAFiles/" />
-        <SSA Id="0" side="0" configfile="SSA1.txt" />
-        <SSA Id="1" side="0" configfile="SSA2.txt" />
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <SSA_Files path="./settings/SSAFiles/" />
+            <SSA Id="0" side="0" configfile="SSA1.txt" />
+            <SSA Id="1" side="0" configfile="SSA2.txt" />
+        </Module>
+    </OpticalGroup>
 
     <!--CONFIG-->
     <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 -->
diff --git a/settings/D19C_2xSSA_onechip.xml b/settings/D19C_2xSSA_onechip.xml
index 226c04191..3ce396627 100644
--- a/settings/D19C_2xSSA_onechip.xml
+++ b/settings/D19C_2xSSA_onechip.xml
@@ -2,11 +2,13 @@
 <HwDescription>
   <BeBoard Id="0" boardType="D19C" eventType="SSA">
       <connection id="board" uri="chtcp-2.0://localhost:10203?target=192.168.0.8:50001" address_table="file://settings/address_tables/d19c_MT_address_table.xml" />
-    <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
-        <SSA_Files path="./settings/SSAFiles/" />
-        <SSA Id="0" side="0" configfile="SSA_init.txt" />
-        <SSA Id="1" side="0" configfile="SSA_init.txt" />
-    </Module>
+    <OpticalGroup Id="0" FMCId="0" >
+        <Module FeId="0" FMCId="0" ModuleId="0" Status="1">
+            <SSA_Files path="./settings/SSAFiles/" />
+            <SSA Id="0" side="0" configfile="SSA_init.txt" />
+            <SSA Id="1" side="0" configfile="SSA_init.txt" />
+        </Module>
+    </OpticalGroup>
 
     <!--CONFIG-->
     <Register name="clock_source">3</Register> <!-- 3 - default (internal oscillator), 2 - backplane, 0 - AMC13 -->
-- 
GitLab