RD53ThrEqualization.cc 32.5 KB
Newer Older
1
/*!
Mauro Dinardo's avatar
Mauro Dinardo committed
2
  \file                  RD53ThrEqualization.cc
3
4
5
6
7
8
9
  \brief                 Implementaion of threshold equalization
  \author                Mauro DINARDO
  \version               1.0
  \date                  28/06/18
  Support:               email to mauro.dinardo@cern.ch
*/

Mauro Dinardo's avatar
Mauro Dinardo committed
10
#include "RD53ThrEqualization.h"
11

12
13
14
using namespace Ph2_HwDescription;
using namespace Ph2_HwInterface;

Fabio Ravera's avatar
Fabio Ravera committed
15
void ThrEqualization::ConfigureCalibration()
16
{
Fabio Ravera's avatar
Fabio Ravera committed
17
18
19
20
21
22
    // ##############################
    // # Initialize sub-calibration #
    // ##############################
    PixelAlive::ConfigureCalibration();
    PixelAlive::doDisplay    = false;
    PixelAlive::doUpdateChip = false;
Mauro Dinardo's avatar
Mauro Dinardo committed
23
    RD53RunProgress::total() -= PixelAlive::getNumberIterations();
Fabio Ravera's avatar
Fabio Ravera committed
24
25
26
27

    // #######################
    // # Retrieve parameters #
    // #######################
28
29
30
31
32
33
34
35
    rowStart       = this->findValueInSettings<double>("ROWstart");
    rowStop        = this->findValueInSettings<double>("ROWstop");
    colStart       = this->findValueInSettings<double>("COLstart");
    colStop        = this->findValueInSettings<double>("COLstop");
    nEvents        = this->findValueInSettings<double>("nEvents");
    nEvtsBurst     = this->findValueInSettings<double>("nEvtsBurst") < nEvents ? this->findValueInSettings<double>("nEvtsBurst") : nEvents;
    startValue     = this->findValueInSettings<double>("VCalHstart");
    stopValue      = this->findValueInSettings<double>("VCalHstop");
36
    nSteps         = this->findValueInSettings<double>("VCalHnsteps");
37
38
    nHITxCol       = this->findValueInSettings<double>("nHITxCol");
    doFast         = this->findValueInSettings<double>("DoFast");
39
    doOnlyNGroups  = this->findValueInSettings<double>("DoOnlyNGroups");
40
41
42
    doDisplay      = this->findValueInSettings<double>("DisplayHisto");
    doUpdateChip   = this->findValueInSettings<double>("UpdateChipCfg");
    saveBinaryData = this->findValueInSettings<double>("SaveBinaryData");
Fabio Ravera's avatar
Fabio Ravera committed
43
44
45

    frontEnd = RD53::getMajorityFE(colStart, colStop);
    if(frontEnd == &RD53::SYNC)
Mini-Me's avatar
Mini-Me committed
46
    {
Fabio Ravera's avatar
Fabio Ravera committed
47
48
        LOG(ERROR) << BOLDRED << "ThrEqualization cannot be used on the Synchronous FE, please change the selected columns" << RESET;
        exit(EXIT_FAILURE);
Alkiviadis Papadopoulos's avatar
Alkiviadis Papadopoulos committed
49
    }
Fabio Ravera's avatar
Fabio Ravera committed
50
51
52
53
54
55
56
57
58
59
60
61
    colStart = std::max(colStart, frontEnd->colStart);
    colStop  = std::min(colStop, frontEnd->colStop);
    LOG(INFO) << GREEN << "ThrEqualization will run on the " << RESET << BOLDYELLOW << frontEnd->name << RESET << GREEN << " FE, columns [" << GREEN << BOLDYELLOW << colStart << ", " << colStop
              << RESET << GREEN << "]" << RESET;

    // ########################
    // # Custom channel group #
    // ########################
    ChannelGroup<RD53::nRows, RD53::nCols> customChannelGroup;
    customChannelGroup.disableAllChannels();

    for(auto row = rowStart; row <= rowStop; row++)
Fabio Ravera's avatar
Fabio Ravera committed
62
        for(auto col = colStart; col <= colStop; col++) customChannelGroup.enableChannel(row, col);
Fabio Ravera's avatar
Fabio Ravera committed
63

64
    theChnGroupHandler = std::make_shared<RD53ChannelGroupHandler>(customChannelGroup, doFast == true ? RD53GroupType::OneGroup : RD53GroupType::AllGroups, nHITxCol, doOnlyNGroups);
Fabio Ravera's avatar
Fabio Ravera committed
65
66
67
68
69
70
    theChnGroupHandler->setCustomChannelGroup(customChannelGroup);

    // #######################
    // # Initialize progress #
    // #######################
    RD53RunProgress::total() += ThrEqualization::getNumberIterations();
71
72
}

73
void ThrEqualization::Running()
74
{
75
    theCurrentRun = this->fRunNumber;
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
76
    LOG(INFO) << GREEN << "[ThrEqualization::Running] Starting run: " << BOLDYELLOW << theCurrentRun << RESET;
Mini-Me's avatar
Minor    
Mini-Me committed
77

Fabio Ravera's avatar
Fabio Ravera committed
78
    if(saveBinaryData == true)
Mini-Me's avatar
Mini-Me committed
79
    {
80
        this->addFileHandler(std::string(this->fDirectoryName) + "/Run" + RD53Shared::fromInt2Str(theCurrentRun) + "_ThrEqualization.raw", 'w');
Fabio Ravera's avatar
Fabio Ravera committed
81
        this->initializeWriteFileHandler();
Mini-Me's avatar
Mini-Me committed
82
    }
83

Fabio Ravera's avatar
Fabio Ravera committed
84
85
    ThrEqualization::run();
    ThrEqualization::analyze();
86
    ThrEqualization::saveChipRegisters(theCurrentRun);
Fabio Ravera's avatar
Fabio Ravera committed
87
    ThrEqualization::sendData();
88

Fabio Ravera's avatar
Fabio Ravera committed
89
    PixelAlive::sendData();
90
}
91

Fabio Ravera's avatar
Fabio Ravera committed
92
void ThrEqualization::sendData()
93
{
Fabio Ravera's avatar
Fabio Ravera committed
94
95
    auto theOccStream  = prepareChannelContainerStreamer<OccupancyAndPh>("Occ");
    auto theTDACStream = prepareChannelContainerStreamer<uint16_t>("TDAC");
96

Sarah Seif El Nasr's avatar
Sarah Seif El Nasr committed
97
    if(fDQMStreamerEnabled == true)
98
    {
99
100
        for(const auto cBoard: theOccContainer) theOccStream.streamAndSendBoard(cBoard, fDQMStreamer);
        for(const auto cBoard: theTDACcontainer) theTDACStream.streamAndSendBoard(cBoard, fDQMStreamer);
101
102
103
    }
}

Fabio Ravera's avatar
Fabio Ravera committed
104
void ThrEqualization::Stop()
105
{
Fabio Ravera's avatar
Fabio Ravera committed
106
    LOG(INFO) << GREEN << "[ThrEqualization::Stop] Stopping" << RESET;
107

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
108
109
    Tool::Stop();

110
    ThrEqualization::draw();
Fabio Ravera's avatar
Fabio Ravera committed
111
    this->closeFileHandler();
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
112

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
113
    RD53RunProgress::reset();
114
115
}

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
116
void ThrEqualization::localConfigure(const std::string& fileRes_, int currentRun)
117
{
118
#ifdef __USE_ROOT__
Fabio Ravera's avatar
Fabio Ravera committed
119
120
    histos             = nullptr;
    PixelAlive::histos = nullptr;
121
#endif
122

123
    if(currentRun >= 0)
Mauro Dinardo's avatar
Mauro Dinardo committed
124
125
    {
        theCurrentRun = currentRun;
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
126
        LOG(INFO) << GREEN << "[ThrEqualization::localConfigure] Starting run: " << BOLDYELLOW << theCurrentRun << RESET;
Mauro Dinardo's avatar
Mauro Dinardo committed
127
    }
Fabio Ravera's avatar
Fabio Ravera committed
128
129
    ThrEqualization::ConfigureCalibration();
    ThrEqualization::initializeFiles(fileRes_, currentRun);
Mauro Dinardo's avatar
Mauro Dinardo committed
130
131
}

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
132
void ThrEqualization::initializeFiles(const std::string& fileRes_, int currentRun)
Mauro Dinardo's avatar
Mauro Dinardo committed
133
{
Fabio Ravera's avatar
Fabio Ravera committed
134
135
136
137
    // ##############################
    // # Initialize sub-calibration #
    // ##############################
    PixelAlive::initializeFiles("", -1);
138

Fabio Ravera's avatar
Fabio Ravera committed
139
    fileRes = fileRes_;
140

141
    if((currentRun >= 0) && (saveBinaryData == true))
142
    {
Fabio Ravera's avatar
Fabio Ravera committed
143
144
        this->addFileHandler(std::string(this->fDirectoryName) + "/Run" + RD53Shared::fromInt2Str(currentRun) + "_ThrEqualization.raw", 'w');
        this->initializeWriteFileHandler();
145
    }
146
147

#ifdef __USE_ROOT__
Fabio Ravera's avatar
Fabio Ravera committed
148
149
    delete histos;
    histos = new ThrEqualizationHistograms;
150
#endif
151
152
}

Fabio Ravera's avatar
Fabio Ravera committed
153
void ThrEqualization::run()
154
{
155
156
157
158
    // #########################
    // # Find global threshold #
    // #########################
    ThrEqualization::bitWiseScanGlobal("VCAL_HIGH", TARGETEFF, startValue, stopValue);
Fabio Ravera's avatar
Fabio Ravera committed
159
160
161
162
163

    // ##############################
    // # Run threshold equalization #
    // ##############################
    size_t TDACsize = RD53Shared::setBits(RD53Constants::NBIT_TDAC) + 1;
Mauro Dinardo's avatar
Mauro Dinardo committed
164
    if(frontEnd == &RD53::DIFF) TDACsize *= 2;
Fabio Ravera's avatar
Fabio Ravera committed
165
166
167
168
169

    this->fDetectorDataContainer = &theOccContainer;
    ContainerFactory::copyAndInitStructure<OccupancyAndPh>(*fDetectorContainer, *this->fDetectorDataContainer);
    ContainerFactory::copyAndInitChannel<uint16_t>(*fDetectorContainer, theTDACcontainer);

170
    setChannelGroupHandler(theChnGroupHandler);
Fabio Ravera's avatar
Fabio Ravera committed
171
172
    this->SetTestPulse(true);
    this->fMaskChannelsFromOtherGroups = true;
173
    ThrEqualization::bitWiseScanLocal(frontEnd->name, nEvents * nSteps, TARGETEFF, nEvtsBurst * nSteps);
Fabio Ravera's avatar
Fabio Ravera committed
174
175
176
177
178
179

    // #################################################
    // # Fill TDAC container and mark enabled channels #
    // #################################################
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
180
181
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
182
183
                {
                    this->fReadoutChipInterface->ReadChipAllLocalReg(
184
                        static_cast<RD53*>(cChip), "PIX_PORTAL", *theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex()));
Fabio Ravera's avatar
Fabio Ravera committed
185
186
187

                    for(auto row = 0u; row < RD53::nRows; row++)
                        for(auto col = 0u; col < RD53::nCols; col++)
188
                            if(!static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row, col) || !getChannelGroupHandlerContainer()->getObject(cBoard->getId())
Sarah Seif El Nasr's avatar
Sarah Seif El Nasr committed
189
190
191
192
193
194
                                                                                                                     ->getObject(cOpticalGroup->getId())
                                                                                                                     ->getObject(cHybrid->getId())
                                                                                                                     ->getObject(cChip->getId())
                                                                                                                     ->getSummary<std::shared_ptr<ChannelGroupHandler>>()
                                                                                                                     ->allChannelGroup()
                                                                                                                     ->isChannelEnabled(row, col))
Fabio Ravera's avatar
Fabio Ravera committed
195
                            {
196
                                theOccContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<OccupancyAndPh>(row, col).fOccupancy =
Fabio Ravera's avatar
Fabio Ravera committed
197
                                    RD53Shared::ISDISABLED;
198
                                theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) = TDACsize;
Fabio Ravera's avatar
Fabio Ravera committed
199
200
201
202
203
204
205
                            }
                }

    // ################
    // # Error report #
    // ################
    ThrEqualization::chipErrorReport();
206
207
}

208
void ThrEqualization::draw()
209
{
210
    ThrEqualization::saveChipRegisters(theCurrentRun);
211

212
#ifdef __USE_ROOT__
Fabio Ravera's avatar
Fabio Ravera committed
213
    TApplication* myApp = nullptr;
214

Fabio Ravera's avatar
Fabio Ravera committed
215
    if(doDisplay == true) myApp = new TApplication("myApp", nullptr, nullptr);
216

217
218
219
220
221
    if((this->fResultFile == nullptr) || (this->fResultFile->IsOpen() == false))
    {
        this->InitResultFile(fileRes);
        LOG(INFO) << BOLDBLUE << "\t--> ThrEqualization saving histograms..." << RESET;
    }
222

223
    histos->book(this->fResultFile, *fDetectorContainer, fSettingsMap);
Fabio Ravera's avatar
Fabio Ravera committed
224
225
    ThrEqualization::fillHisto();
    histos->process();
226

227
    PixelAlive::draw(false);
228

Fabio Ravera's avatar
Fabio Ravera committed
229
    if(doDisplay == true) myApp->Run(true);
230
#endif
231
}
IT DAQ Firmware Development's avatar
IT DAQ Firmware Development committed
232

Fabio Ravera's avatar
Fabio Ravera committed
233
void ThrEqualization::analyze()
234
{
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
235
    const float  maxTDACdistance = 2; // @CONST@
236
237
    const size_t TDACcenter      = RD53Shared::setBits(RD53Constants::NBIT_TDAC) / 2;

Fabio Ravera's avatar
Fabio Ravera committed
238
239
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
240
241
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
242
243
                {
                    static_cast<RD53*>(cChip)->copyMaskFromDefault();
244
245
                    float avgTDAC = 0;
                    int   counter = 0;
Fabio Ravera's avatar
Fabio Ravera committed
246
247
248

                    for(auto row = 0u; row < RD53::nRows; row++)
                        for(auto col = 0u; col < RD53::nCols; col++)
249
                            if(static_cast<RD53*>(cChip)->getChipOriginalMask()->isChannelEnabled(row, col) && getChannelGroupHandlerContainer()->getObject(cBoard->getId())
Sarah Seif El Nasr's avatar
Sarah Seif El Nasr committed
250
251
252
253
254
255
                                                                                                                   ->getObject(cOpticalGroup->getId())
                                                                                                                   ->getObject(cHybrid->getId())
                                                                                                                   ->getObject(cChip->getId())
                                                                                                                   ->getSummary<std::shared_ptr<ChannelGroupHandler>>()
                                                                                                                   ->allChannelGroup()
                                                                                                                   ->isChannelEnabled(row, col))
256
                            {
Fabio Ravera's avatar
Fabio Ravera committed
257
                                static_cast<RD53*>(cChip)->setTDAC(
258
                                    row, col, theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col));
Fabio Ravera's avatar
Fabio Ravera committed
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
                                avgTDAC += theTDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col);
                                counter++;
                            }

                    avgTDAC /= counter;

                    // ###########################
                    // # Check TDAC distribution #
                    // ###########################
                    if(fabs(avgTDAC - TDACcenter) > maxTDACdistance)
                    {
                        LOG(WARNING) << BOLDRED << "Average TDAC distribution not centered around " << BOLDYELLOW << TDACcenter << BOLDRED << " (i.e. " << std::setprecision(1) << BOLDYELLOW << avgTDAC
                                     << BOLDRED << " - center > " << BOLDYELLOW << maxTDACdistance << BOLDRED << ") for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/"
                                     << cOpticalGroup->getId() << "/" << cHybrid->getId() << "/" << +cChip->getId() << BOLDRED << "]" << std::setprecision(-1) << RESET;
                    }

Fabio Ravera's avatar
Fabio Ravera committed
276
277
                    static_cast<RD53*>(cChip)->copyMaskToDefault();
                }
278
279
}

Fabio Ravera's avatar
Fabio Ravera committed
280
void ThrEqualization::fillHisto()
281
{
282
#ifdef __USE_ROOT__
Fabio Ravera's avatar
Fabio Ravera committed
283
284
    histos->fillOccupancy(theOccContainer);
    histos->fillTDAC(theTDACcontainer);
285
#endif
286
}
Mauro Dinardo's avatar
Mauro Dinardo committed
287

288
void ThrEqualization::bitWiseScanGlobal(const std::string& regName, const float& target, uint16_t startValue, uint16_t stopValue)
289
{
minime's avatar
minime committed
290
291
    std::vector<uint16_t> chipCommandList;
    std::vector<uint32_t> hybridCommandList;
292

293
    float    tmp;
Fabio Ravera's avatar
Fabio Ravera committed
294
    uint16_t init;
Mauro Dinardo's avatar
Mauro Dinardo committed
295
    uint16_t numberOfBits = floor(log2(stopValue - startValue + 1) + 1);
296

Fabio Ravera's avatar
Fabio Ravera committed
297
298
299
    DetectorDataContainer minDACcontainer;
    DetectorDataContainer midDACcontainer;
    DetectorDataContainer maxDACcontainer;
300

Fabio Ravera's avatar
Fabio Ravera committed
301
302
    DetectorDataContainer bestDACcontainer;
    DetectorDataContainer bestContainer;
303

Fabio Ravera's avatar
Fabio Ravera committed
304
305
306
    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, minDACcontainer, init = startValue);
    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, midDACcontainer);
    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, maxDACcontainer, init = (stopValue + 1));
307

308
309
    ContainerFactory::copyAndInitChip<uint16_t>(*fDetectorContainer, bestDACcontainer, init = 0);
    ContainerFactory::copyAndInitChip<float>(*fDetectorContainer, bestContainer, tmp = 0);
310

Fabio Ravera's avatar
Fabio Ravera committed
311
    for(auto i = 0u; i <= numberOfBits; i++)
312
    {
Fabio Ravera's avatar
Fabio Ravera committed
313
314
315
316
317
        // ###########################
        // # Download new DAC values #
        // ###########################
        for(const auto cBoard: *fDetectorContainer)
            for(const auto cOpticalGroup: *cBoard)
minime's avatar
minime committed
318
319
320
            {
                hybridCommandList.clear();

321
                for(const auto cHybrid: *cOpticalGroup)
322
                {
minime's avatar
minime committed
323
                    chipCommandList.clear();
324
325
                    int hybridId = cHybrid->getId();

326
                    for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
327
                    {
328
329
330
                        midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
                            (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() +
                             maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>()) /
Fabio Ravera's avatar
Fabio Ravera committed
331
332
                            2;

333
                        static_cast<RD53Interface*>(this->fReadoutChipInterface)
minime's avatar
Minor    
minime committed
334
                            ->PackChipCommands(cChip,
335
336
                                               regName,
                                               midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(),
minime's avatar
Minor    
minime committed
337
338
                                               chipCommandList,
                                               true);
Mauro Dinardo's avatar
Mauro Dinardo committed
339

Mauro Dinardo's avatar
Mauro Dinardo committed
340
341
                        LOG(INFO) << BOLDMAGENTA << ">>> " << BOLDYELLOW << regName << BOLDMAGENTA << " value for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/"
                                  << cOpticalGroup->getId() << "/" << cHybrid->getId() << "/" << +cChip->getId() << RESET << BOLDMAGENTA << "] = " << RESET << BOLDYELLOW
342
                                  << midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() << BOLDMAGENTA
Mauro Dinardo's avatar
Mauro Dinardo committed
343
                                  << " <<<" << RESET;
Fabio Ravera's avatar
Fabio Ravera committed
344
345
                    }

346
                    static_cast<RD53Interface*>(this->fReadoutChipInterface)->PackHybridCommands(cBoard, chipCommandList, hybridId, hybridCommandList);
347
348
                }

349
                static_cast<RD53Interface*>(this->fReadoutChipInterface)->SendHybridCommandsPack(cBoard, hybridCommandList);
minime's avatar
minime committed
350
351
            }

Fabio Ravera's avatar
Fabio Ravera committed
352
353
354
355
356
        // ################
        // # Run analysis #
        // ################
        PixelAlive::run();
        auto output = PixelAlive::analyze();
357
        // ##############################################
358
        // # Send periodic data to monitor the progress #
359
360
361
        // ##############################################
        PixelAlive::sendData();

Fabio Ravera's avatar
Fabio Ravera committed
362
363
364
365
366
        // #####################
        // # Compute next step #
        // #####################
        for(const auto cBoard: *output)
            for(const auto cOpticalGroup: *cBoard)
367
368
                for(const auto cHybrid: *cOpticalGroup)
                    for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
369
370
371
372
373
374
375
376
377
                    {
                        // #######################
                        // # Build discriminator #
                        // #######################
                        float newValue = cChip->getSummary<GenericDataVector, OccupancyAndPh>().fOccupancy;

                        // ########################
                        // # Save best DAC values #
                        // ########################
Mega Mind's avatar
Mega Mind committed
378
                        float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<float>();
Fabio Ravera's avatar
Fabio Ravera committed
379
380
381

                        if(fabs(newValue - target) < fabs(oldValue - target))
                        {
Mega Mind's avatar
Mega Mind committed
382
                            bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<float>() = newValue;
Fabio Ravera's avatar
Fabio Ravera committed
383

384
385
                            bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
                                midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
Fabio Ravera's avatar
Fabio Ravera committed
386
387
388
389
                        }

                        if(newValue > target)

390
391
                            maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
                                midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
Fabio Ravera's avatar
Fabio Ravera committed
392
393
394

                        else

395
396
                            minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() =
                                midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>();
Fabio Ravera's avatar
Fabio Ravera committed
397
                    }
398
399
    }

Fabio Ravera's avatar
Fabio Ravera committed
400
401
402
403
404
    // ###########################
    // # Download new DAC values #
    // ###########################
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
minime's avatar
minime committed
405
406
407
        {
            hybridCommandList.clear();

408
            for(const auto cHybrid: *cOpticalGroup)
409
            {
minime's avatar
minime committed
410
                chipCommandList.clear();
411
412
                int hybridId = cHybrid->getId();

413
                for(const auto cChip: *cHybrid)
Mauro Dinardo's avatar
Mauro Dinardo committed
414
415
                    if(bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() != 0)
                    {
416
                        static_cast<RD53Interface*>(this->fReadoutChipInterface)
minime's avatar
Minor    
minime committed
417
                            ->PackChipCommands(cChip,
418
419
                                               regName,
                                               bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>(),
minime's avatar
Minor    
minime committed
420
421
                                               chipCommandList,
                                               true);
minime's avatar
minime committed
422

Mauro Dinardo's avatar
Mauro Dinardo committed
423
424
425
426
427
428
429
430
                        LOG(INFO) << BOLDMAGENTA << ">>> Best " << BOLDYELLOW << regName << BOLDMAGENTA << " value for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/"
                                  << cOpticalGroup->getId() << "/" << cHybrid->getId() << "/" << +cChip->getId() << BOLDMAGENTA << "] = " << BOLDYELLOW
                                  << bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<uint16_t>() << BOLDMAGENTA
                                  << " <<<" << RESET;
                    }
                    else
                        LOG(WARNING) << BOLDRED << ">>> Best " << BOLDYELLOW << regName << BOLDRED << " value for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/"
                                     << cOpticalGroup->getId() << "/" << cHybrid->getId() << "/" << +cChip->getId() << BOLDRED << "] was not found <<<" << RESET;
Fabio Ravera's avatar
Fabio Ravera committed
431

432
                static_cast<RD53Interface*>(this->fReadoutChipInterface)->PackHybridCommands(cBoard, chipCommandList, hybridId, hybridCommandList);
433
434
            }

435
            static_cast<RD53Interface*>(this->fReadoutChipInterface)->SendHybridCommandsPack(cBoard, hybridCommandList);
minime's avatar
minime committed
436
437
        }

Fabio Ravera's avatar
Fabio Ravera committed
438
439
440
441
442
    // ################
    // # Run analysis #
    // ################
    PixelAlive::run();
    PixelAlive::analyze();
443
444
}

Fabio Ravera's avatar
Fabio Ravera committed
445
void ThrEqualization::bitWiseScanLocal(const std::string& regName, uint32_t nEvents, const float& target, uint32_t nEvtsBurst)
446
{
447
    float    tmp;
Mauro Dinardo's avatar
Mauro Dinardo committed
448
    uint16_t init;
449

Fabio Ravera's avatar
Fabio Ravera committed
450
451
452
453
454
455
456
    DetectorDataContainer minDACcontainer;
    DetectorDataContainer midDACcontainer;
    DetectorDataContainer maxDACcontainer;

    DetectorDataContainer bestDACcontainer;
    DetectorDataContainer bestContainer;

457
458
    DetectorDataContainer saveEff;

Fabio Ravera's avatar
Fabio Ravera committed
459
460
461
462
463
    ContainerFactory::copyAndInitChannel<uint16_t>(*fDetectorContainer, minDACcontainer, init = 0);
    ContainerFactory::copyAndInitChannel<uint16_t>(*fDetectorContainer, midDACcontainer);
    ContainerFactory::copyAndInitChannel<uint16_t>(*fDetectorContainer, maxDACcontainer, init = frontEnd->nTDACvalues);

    ContainerFactory::copyAndInitChannel<uint16_t>(*fDetectorContainer, bestDACcontainer);
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
464
    ContainerFactory::copyAndInitChannel<float>(*fDetectorContainer, bestContainer, tmp = (target < 0.5 ? 1 : 0));
Fabio Ravera's avatar
Fabio Ravera committed
465

466
    ContainerFactory::copyAndInitChannel<float>(*fDetectorContainer, saveEff, tmp = 0);
Fabio Ravera's avatar
Fabio Ravera committed
467
468
469
470
471
472

    // ############################
    // # Read DAC starting values #
    // ############################
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
473
474
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
475
                    this->fReadoutChipInterface->ReadChipAllLocalReg(
476
                        static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex()));
Fabio Ravera's avatar
Fabio Ravera committed
477

478
    uint16_t numberOfBits = floor(log2(frontEnd->nTDACvalues) + 1);
479
480
481
482
483
484
485
486
487
488
489
490
491
    // ################################
    // # Custom channel group handler #
    // ################################
    ChannelGroup<RD53::nRows, RD53::nCols> customChannelGroupNoise;
    customChannelGroupNoise.disableAllChannels();

    for(auto row = rowStart; row <= rowStop; row++)
        for(auto col = colStart; col <= colStop; col++) customChannelGroupNoise.enableChannel(row, col);

    std::shared_ptr<RD53ChannelGroupHandler> theChnGroupHandlerNoise;
    theChnGroupHandlerNoise = std::make_shared<RD53ChannelGroupHandler>(customChannelGroupNoise, RD53GroupType::AllPixels, nHITxCol);
    theChnGroupHandlerNoise->setCustomChannelGroup(customChannelGroupNoise);

Fabio Ravera's avatar
Fabio Ravera committed
492
    for(auto i = 0u; i <= numberOfBits; i++)
IT DAQ Firmware Development's avatar
IT DAQ Firmware Development committed
493
    {
Fabio Ravera's avatar
Fabio Ravera committed
494
495
496
497
498
        // ###########################
        // # Download new DAC values #
        // ###########################
        for(const auto cBoard: *fDetectorContainer)
            for(const auto cOpticalGroup: *cBoard)
499
500
                for(const auto cHybrid: *cOpticalGroup)
                    for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
501
                        this->fReadoutChipInterface->WriteChipAllLocalReg(
502
                            static_cast<RD53*>(cChip), regName, *midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex()));
Fabio Ravera's avatar
Fabio Ravera committed
503
504
505
506
507
508

        // ################
        // # Run analysis #
        // ################
        this->measureData(nEvents, nEvtsBurst);

509
510
511
512
513
514
515
516
        // ############################
        // # Save measured efficiency #
        // ############################
        ThrEqualization::copyAndResetContainer(theOccContainer, saveEff);

        // #################
        // # Measure noise #
        // #################
517
        setChannelGroupHandler(theChnGroupHandlerNoise);
518
519
        this->SetTestPulse(PixelAlive::INJtype::None);
        this->measureData(nEvents, nEvtsBurst);
520
        setChannelGroupHandler(theChnGroupHandler);
521
522
        this->SetTestPulse(PixelAlive::injType);

Fabio Ravera's avatar
Fabio Ravera committed
523
524
525
526
527
        // #####################
        // # Compute next step #
        // #####################
        for(const auto cBoard: theOccContainer)
            for(const auto cOpticalGroup: *cBoard)
528
529
                for(const auto cHybrid: *cOpticalGroup)
                    for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
530
531
532
533
534
535
                        for(auto row = 0u; row < RD53::nRows; row++)
                            for(auto col = 0u; col < RD53::nCols; col++)
                            {
                                // #######################
                                // # Build discriminator #
                                // #######################
536
537
                                float newValue = fabs(saveEff.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<float>(row, col) -
                                                      cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy);
Fabio Ravera's avatar
Fabio Ravera committed
538
539
540
541

                                // ########################
                                // # Save best DAC values #
                                // ########################
Mega Mind's avatar
Mega Mind committed
542
                                float oldValue = bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<float>(row, col);
Fabio Ravera's avatar
Fabio Ravera committed
543

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
544
                                if(fabs(newValue - target) <= fabs(oldValue - target))
Fabio Ravera's avatar
Fabio Ravera committed
545
                                {
Mega Mind's avatar
Mega Mind committed
546
                                    bestContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<float>(row, col) = newValue;
547
548
                                    bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) =
                                        midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col);
Fabio Ravera's avatar
Fabio Ravera committed
549
550
551
552
                                }

                                if(newValue < target)

553
554
                                    minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) =
                                        midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col);
Fabio Ravera's avatar
Fabio Ravera committed
555
556
557

                                else

558
559
                                    maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) =
                                        midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col);
Fabio Ravera's avatar
Fabio Ravera committed
560

561
562
563
                                midDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) =
                                    (minDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col) +
                                     maxDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<uint16_t>(row, col)) /
Fabio Ravera's avatar
Fabio Ravera committed
564
                                    2;
565
566
567
568
569

                                // ###################
                                // # Reset container #
                                // ###################
                                cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy = 0;
Fabio Ravera's avatar
Fabio Ravera committed
570
                            }
571
        theOccContainer.resetNormalizationStatus();
IT DAQ Firmware Development's avatar
IT DAQ Firmware Development committed
572
    }
Mini-Me's avatar
Mini-Me committed
573

Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
574
575
576
577
578
    // ###################
    // # Reset container #
    // ###################
    ThrEqualization::copyAndResetContainer(theOccContainer, saveEff);

Fabio Ravera's avatar
Fabio Ravera committed
579
580
581
582
583
    // ###########################
    // # Download new DAC values #
    // ###########################
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
584
585
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
586
                    this->fReadoutChipInterface->WriteChipAllLocalReg(
587
                        static_cast<RD53*>(cChip), regName, *bestDACcontainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex()));
Fabio Ravera's avatar
Fabio Ravera committed
588
589
590
591
592

    // ################
    // # Run analysis #
    // ################
    this->measureData(nEvents, nEvtsBurst);
593
594
}

Mauro Dinardo's avatar
Mauro Dinardo committed
595
void ThrEqualization::chipErrorReport() const
Mauro Dinardo's avatar
Mauro Dinardo committed
596
{
Fabio Ravera's avatar
Fabio Ravera committed
597
598
    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
599
600
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
601
                {
602
                    LOG(INFO) << GREEN << "Readout chip error report for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/" << cOpticalGroup->getId() << "/"
603
                              << cHybrid->getId() << "/" << +cChip->getId() << RESET << GREEN << "]" << RESET;
Mauro Dinardo's avatar
Mauro Dinardo committed
604
                    static_cast<RD53Interface*>(this->fReadoutChipInterface)->ChipErrorReport(cChip);
Fabio Ravera's avatar
Fabio Ravera committed
605
                }
Mauro Dinardo's avatar
Mauro Dinardo committed
606
}
607

Fabio Ravera's avatar
Fabio Ravera committed
608
void ThrEqualization::saveChipRegisters(int currentRun)
609
{
Mauro Dinardo's avatar
Mauro Dinardo committed
610
    const std::string fileReg("Run" + RD53Shared::fromInt2Str(currentRun) + "_");
Fabio Ravera's avatar
Fabio Ravera committed
611
612
613

    for(const auto cBoard: *fDetectorContainer)
        for(const auto cOpticalGroup: *cBoard)
614
615
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
Fabio Ravera's avatar
Fabio Ravera committed
616
                {
Fabio Ravera's avatar
Fabio Ravera committed
617
                    if(doUpdateChip == true) static_cast<RD53*>(cChip)->saveRegMap("");
Fabio Ravera's avatar
Fabio Ravera committed
618
619
620
                    static_cast<RD53*>(cChip)->saveRegMap(fileReg);
                    std::string command("mv " + static_cast<RD53*>(cChip)->getFileName(fileReg) + " " + RD53Shared::RESULTDIR);
                    system(command.c_str());
621
                    LOG(INFO) << BOLDBLUE << "\t--> ThrEqualization saved the configuration file for [board/opticalGroup/hybrid/chip = " << BOLDYELLOW << cBoard->getId() << "/"
622
                              << cOpticalGroup->getId() << "/" << cHybrid->getId() << "/" << +cChip->getId() << RESET << BOLDBLUE << "]" << RESET;
Fabio Ravera's avatar
Fabio Ravera committed
623
                }
624
}
625
626
627
628
629
630
631
632
633

void ThrEqualization::copyAndResetContainer(DetectorDataContainer& fromContainer, DetectorDataContainer& toContainer)
{
    for(const auto cBoard: fromContainer)
        for(const auto cOpticalGroup: *cBoard)
            for(const auto cHybrid: *cOpticalGroup)
                for(const auto cChip: *cHybrid)
                    for(auto row = 0u; row < RD53::nRows; row++)
                        for(auto col = 0u; col < RD53::nCols; col++)
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
634
                        {
635
636
637
638
639
640
641
                            toContainer.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getChannel<float>(row, col) =
                                cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy;

                            cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy   = 0;
                            cChip->getChannel<OccupancyAndPh>(row, col).fPh          = 0;
                            cChip->getChannel<OccupancyAndPh>(row, col).fPhError     = 0;
                            cChip->getChannel<OccupancyAndPh>(row, col).readoutError = false;
Mauro Dinardo's avatar
Minor    
Mauro Dinardo committed
642
                        }
Sarah Seif El Nasr's avatar
Sarah Seif El Nasr committed
643
    fromContainer.resetNormalizationStatus();
644
}