@@ -149,6 +149,12 @@ void ITSThresholdCalibrator::init(InitContext& ic)
149149 // Parameters to operate in manual mode (when run type is not recognized automatically)
150150 isManualMode = ic.options ().get <bool >(" manual-mode" );
151151 if (isManualMode) {
152+ try {
153+ manualRowScan = ic.options ().get <short int >(" manual-rowscan" );
154+ } catch (std::exception const & e) {
155+ throw std::runtime_error (" Number of scanned rows not found, mandatory in manual mode" );
156+ }
157+
152158 try {
153159 manualMin = ic.options ().get <short int >(" manual-min" );
154160 } catch (std::exception const & e) {
@@ -746,39 +752,40 @@ void ITSThresholdCalibrator::extractThresholdRow(const short int& chipID, const
746752
747753 } else { // threshold, vcasn, ithr, vresetd_2d
748754
749- short int iRU = getRUID (chipID);
755+ for ( int scan_i = 0 ; scan_i < (( mScanType == ' r ' ) ? N_RANGE : N_RANGE2); scan_i++) {
750756#ifdef WITH_OPENMP
751757 omp_set_num_threads (mNThreads );
752758#pragma omp parallel for schedule(dynamic)
753759#endif
754- // Loop over all columns (pixels) in the row
755- for (short int col_i = 0 ; col_i < this ->N_COL ; col_i++) {
756- // Do the threshold fit
757- float thresh = 0 ., noise = 0 .;
758- bool success = false ;
759- int spoints = 0 ;
760- int scan_i = mScanType == ' r' ? (mLoopVal [iRU][row] - mMin ) / mStep : 0 ;
761- if (isDumpS) { // already protected for multi-thread in the init
762- mFitHist ->SetName (Form (" scurve_chip%d_row%d_col%d_scani%d" , chipID, row, col_i, scan_i));
763- }
760+ // Loop over all columns (pixels) in the row
761+ for (short int col_i = 0 ; col_i < this ->N_COL ; col_i++) {
762+ // Do the threshold fit
763+ float thresh = 0 ., noise = 0 .;
764+ bool success = false ;
765+ int spoints = 0 ;
764766
765- success = this ->findThreshold (chipID, mPixelHits [chipID][row][col_i],
766- this ->mX , mScanType == ' r' ? N_RANGE2 : N_RANGE, thresh, noise, spoints, scan_i);
767+ if (isDumpS) { // already protected for multi-thread in the init
768+ mFitHist ->SetName (Form (" scurve_chip%d_row%d_col%d_scani%d" , chipID, row, col_i, scan_i));
769+ }
767770
768- vChipid[col_i] = chipID;
769- vRow[col_i] = row;
770- vThreshold[col_i] = (mScanType == ' T' || mScanType == ' r' ) ? (short int )(thresh * 10 .) : (short int )(thresh);
771- vNoise[col_i] = (float )(noise * 10 .); // always factor 10 also for ITHR/VCASN to not have all zeros
772- vSuccess[col_i] = success;
773- vPoints[col_i] = spoints > 0 ? (unsigned char )(spoints) : 0 ;
771+ success = this ->findThreshold (chipID, mPixelHits [chipID][row][col_i],
772+ this ->mX , mScanType == ' r' ? N_RANGE2 : N_RANGE, thresh, noise, spoints, scan_i);
774773
774+ vChipid[col_i] = chipID;
775+ vRow[col_i] = row;
776+ vThreshold[col_i] = (mScanType == ' T' || mScanType == ' r' ) ? (short int )(thresh * 10 .) : (short int )(thresh);
777+ vNoise[col_i] = (float )(noise * 10 .); // always factor 10 also for ITHR/VCASN to not have all zeros
778+ vSuccess[col_i] = success;
779+ vPoints[col_i] = spoints > 0 ? (unsigned char )(spoints) : 0 ;
780+
781+ if (mScanType == ' r' ) {
782+ vMixData[col_i] = (scan_i * mStep ) + mMin ;
783+ }
784+ }
775785 if (mScanType == ' r' ) {
776- vMixData[col_i] = mLoopVal [iRU][row];
786+ this -> saveThreshold (); // save before moving to the next vresetd
777787 }
778788 }
779- if (mScanType == ' r' ) {
780- this ->saveThreshold (); // save before moving to the next vresetd
781- }
782789
783790 // Fill the ScTree tree
784791 if (mScanType == ' T' || mScanType == ' V' || mScanType == ' I' ) { // TODO: store also for other scans?
@@ -794,6 +801,9 @@ void ITSThresholdCalibrator::extractThresholdRow(const short int& chipID, const
794801
795802 // Saves threshold information to internal memory
796803 if (mScanType != ' P' && mScanType != ' p' && mScanType != ' t' && mScanType != ' R' && mScanType != ' r' ) {
804+ if (mVerboseOutput ) {
805+ LOG (info)<<" Saving data of ChipID: " <<chipID<<" Row: " <<row;
806+ }
797807 this ->saveThreshold ();
798808 }
799809}
@@ -934,6 +944,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
934944 this ->mMax = 50 ;
935945 this ->N_RANGE = 51 ;
936946 this ->mCheckExactRow = true ;
947+ mRowScan = 512 ;
937948
938949 } else if (runtype == THR_SCAN_SHORT || runtype == THR_SCAN_SHORT_100HZ ||
939950 runtype == THR_SCAN_SHORT_200HZ || runtype == THR_SCAN_SHORT_33 || runtype == THR_SCAN_SHORT_2_10HZ || runtype == THR_SCAN_SHORT_150INJ) {
@@ -951,6 +962,12 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
951962 nInjScaled = nInj / 3 ;
952963 }
953964 }
965+ mRowScan = 11 ;
966+ if (runtype == THR_SCAN_SHORT_33) {
967+ mRowScan = 33 ;
968+ } else if (runtype == THR_SCAN_SHORT_2_10HZ){
969+ mRowScan = 2 ;
970+ }
954971 } else if (runtype == VCASN150 || runtype == VCASN100 || runtype == VCASN100_100HZ || runtype == VCASN130 || runtype == VCASNBB) {
955972 // VCASN tuning for different target thresholds
956973 // Store average VCASN for each chip into CCDB
@@ -962,6 +979,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
962979 this ->mMax = inMaxVcasn; // 80 is the default
963980 this ->N_RANGE = mMax - mMin + 1 ;
964981 this ->mCheckExactRow = true ;
982+ mRowScan = 4 ;
965983
966984 } else if (runtype == ITHR150 || runtype == ITHR100 || runtype == ITHR100_100HZ || runtype == ITHR130) {
967985 // ITHR tuning -- average ITHR per chip
@@ -973,6 +991,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
973991 this ->mMax = inMaxIthr; // 100 is the default
974992 this ->N_RANGE = mMax - mMin + 1 ;
975993 this ->mCheckExactRow = true ;
994+ mRowScan = 4 ;
976995
977996 } else if (runtype == DIGITAL_SCAN || runtype == DIGITAL_SCAN_100HZ || runtype == DIGITAL_SCAN_NOMASK) {
978997 // Digital scan -- only storing one value per chip, no fit needed
@@ -1078,6 +1097,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
10781097 if (scaleNinj) {
10791098 nInjScaled = nInj / 3 ;
10801099 }
1100+ mRowScan = manualRowScan;
10811101 } else {
10821102 throw runtype;
10831103 }
@@ -1367,15 +1387,14 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
13671387 row = !mCdwVersion ? (short int )(calib.calibUserField & 0xffff ) : (short int )(calib.calibUserField & 0x1ff );
13681388 // cw counter
13691389 cwcnt = (short int )(calib.calibCounter );
1370- // count the last N injections
1371- short int checkVal = (mScanType == ' I' ) ? mMin : mMax ;
1372- if ((mScanType != ' r' && mScanType != ' p' && mScanType != ' t' && loopval == checkVal) ||
1373- (mScanType == ' r' && realcharge == mMax2 ) ||
1374- (mScanType == ' p' && realcharge == mMin2 ) ||
1375- (mScanType == ' t' && loopval == checkVal && realcharge == mMax2 )) {
1376- mCdwCntRU [iRU][row]++;
1377- mLoopVal [iRU][row] = loopval; // keep loop val (relevant for VRESET2D and TOT_1ROW scan only)
1378- }
1390+
1391+ // count injections
1392+ short int loopPoint = (loopval - this ->mMin ) / mStep ;
1393+ short int chgPoint = (realcharge - this ->mMin2 ) / mStep2 ;
1394+ auto &arr = mCdwCntRU [iRU][row];
1395+ arr[chgPoint][loopPoint]++;
1396+
1397+
13791398 if (this ->mVerboseOutput ) {
13801399 LOG (info) << " RU: " << iRU << " CDWcounter: " << cwcnt << " row: " << row << " Loopval: " << loopval << " realcharge: " << realcharge << " confDBv: " << mCdwVersion ;
13811400 LOG (info) << " NDIGITS: " << digits.size ();
@@ -1470,12 +1489,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
14701489 if (ruIndex < 0 ) {
14711490 continue ;
14721491 }
1473- short int nL = 0 ;
1474- for (int iL = 0 ; iL < 3 ; iL++) {
1475- if (mActiveLinks [ruIndex][iL]) {
1476- nL++; // count active links
1477- }
1478- }
1492+ short int nL = ruIndex > 47 ? 2 : 3 ; // total number of links per RU
14791493 std::vector<short int > chipEnabled = getChipListFromRu (ruIndex, mActiveLinks [ruIndex]); // chip boundaries
14801494 // Fill the chipDone info string
14811495 if (mRunTypeRUCopy [ruIndex] == nInjScaled * nL) {
@@ -1488,14 +1502,27 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
14881502 mRunTypeRUCopy [ruIndex] = 0 ; // reset here is safer (the other counter is reset in finalize)
14891503 }
14901504 // Check if scan of a row is finished: only for specific scans!
1491- bool passCondition = (mCdwCntRU [ruIndex][row] >= nInjScaled * nL);
1492- if (mScanType == ' p' || mScanType == ' t' ) {
1493- passCondition = passCondition && (mLoopVal [ruIndex][row] == mMax );
1494- if (mVerboseOutput ) {
1495- LOG (info) << " PassCondition: " << passCondition << " - (mCdwCntRU,mLoopVal) of RU" << ruIndex << " row " << row << " = (" << mCdwCntRU [ruIndex][row] << " , " << mLoopVal [ruIndex][row] << " )" ;
1505+ bool passCondition = true ;
1506+ for (int j1=0 ; j1 < N_RANGE2; j1++) {
1507+ for (int j2=0 ; j2 < N_RANGE; j2++) {
1508+ if (mScanType == ' t' ) { // ToT scan is done in specific ranges depending on charge (see ITSComm)
1509+ if ((j1 == 0 && j2<((600 -mMin )/mStep )) || (j2>=((600 -mMin )/mStep ) && j2<=((800 -mMin )/mStep )) || (j1==1 && j2>((800 -mMin )/mStep ))) {
1510+ if (mCdwCntRU [ruIndex][row][j1][j2] < nInjScaled * nL) {
1511+ passCondition = false ;
1512+ break ;
1513+ }
1514+ }
1515+ } else if (mCdwCntRU [ruIndex][row][j1][j2] < nInjScaled * nL) {
1516+ passCondition = false ;
1517+ break ;
1518+ }
14961519 }
1497- } else if (mVerboseOutput ) {
1498- LOG (info) << " PassCondition: " << passCondition << " - mCdwCntRU of RU" << ruIndex << " row " << row << " = " << mCdwCntRU [ruIndex][row];
1520+ if (!passCondition){
1521+ break ;
1522+ }
1523+ }
1524+ if (mVerboseOutput ) {
1525+ LOG (info) << " PassCondition: " << passCondition << " - mCdwCntRU of RU" << ruIndex << " row " << row << " = " << mCdwCntRU [ruIndex][row][0 ][0 ] << " (Links: " <<mActiveLinks [ruIndex][0 ]<<" , " <<mActiveLinks [ruIndex][1 ]<<" ," <<mActiveLinks [ruIndex][2 ]<<" )" ;
14991526 }
15001527
15011528 if (mScanType != ' D' && mScanType != ' A' && mScanType != ' P' && mScanType != ' R' && passCondition) {
@@ -1509,32 +1536,35 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
15091536 if (mPixelHits .count (chipID)) {
15101537 if (mPixelHits [chipID].count (row)) { // make sure the row exists
15111538 extractAndUpdate (chipID, row);
1512- if (mScanType != ' p' && ( mScanType != ' r ' || mLoopVal [ruIndex][row] == mMax ) ) { // do not erase for scantype = p because in finalize() we have calculate2Dparams
1539+ if (mScanType != ' p' ) { // do not erase for scantype = p because in finalize() we have calculate2Dparams
15131540 mPixelHits [chipID].erase (row);
15141541 }
15151542 }
15161543 }
15171544 }
15181545 }
1519- mCdwCntRU [ruIndex][row] = 0 ; // reset
1546+ mCdwCntRU [ruIndex].erase (row); // row is gone
1547+ }
1548+
1549+ if (mRunTypeRU [ruIndex] >= nInjScaled * nL && passCondition) {
1550+ mFlagsRU [ruIndex] = true ;
1551+ finalize ();
1552+ LOG (info) << " Shipping all outputs to aggregator (before endOfStream arrival!)" ;
1553+ pc.outputs ().snapshot (Output{" ITS" , " TSTR" , (unsigned int )mChipModSel }, this ->mTuning );
1554+ pc.outputs ().snapshot (Output{" ITS" , " PIXTYP" , (unsigned int )mChipModSel }, this ->mPixStat );
1555+ pc.outputs ().snapshot (Output{" ITS" , " RUNT" , (unsigned int )mChipModSel }, this ->mRunType );
1556+ pc.outputs ().snapshot (Output{" ITS" , " SCANT" , (unsigned int )mChipModSel }, this ->mScanType );
1557+ pc.outputs ().snapshot (Output{" ITS" , " FITT" , (unsigned int )mChipModSel }, this ->mFitType );
1558+ pc.outputs ().snapshot (Output{" ITS" , " CONFDBV" , (unsigned int )mChipModSel }, this ->mConfDBv );
1559+ pc.outputs ().snapshot (Output{" ITS" , " QCSTR" , (unsigned int )mChipModSel }, this ->mChipDoneQc );
1560+ // reset the DCSconfigObject_t before next ship out
1561+ mTuning .clear ();
1562+ mPixStat .clear ();
1563+ mChipDoneQc .clear ();
15201564 }
15211565 } // for (ROFs)
15221566
1523- if (!(this ->mRunTypeUp )) {
1524- finalize ();
1525- LOG (info) << " Shipping all outputs to aggregator (before endOfStream arrival!)" ;
1526- pc.outputs ().snapshot (Output{" ITS" , " TSTR" , (unsigned int )mChipModSel }, this ->mTuning );
1527- pc.outputs ().snapshot (Output{" ITS" , " PIXTYP" , (unsigned int )mChipModSel }, this ->mPixStat );
1528- pc.outputs ().snapshot (Output{" ITS" , " RUNT" , (unsigned int )mChipModSel }, this ->mRunType );
1529- pc.outputs ().snapshot (Output{" ITS" , " SCANT" , (unsigned int )mChipModSel }, this ->mScanType );
1530- pc.outputs ().snapshot (Output{" ITS" , " FITT" , (unsigned int )mChipModSel }, this ->mFitType );
1531- pc.outputs ().snapshot (Output{" ITS" , " CONFDBV" , (unsigned int )mChipModSel }, this ->mConfDBv );
1532- pc.outputs ().snapshot (Output{" ITS" , " QCSTR" , (unsigned int )mChipModSel }, this ->mChipDoneQc );
1533- // reset the DCSconfigObject_t before next ship out
1534- mTuning .clear ();
1535- mPixStat .clear ();
1536- mChipDoneQc .clear ();
1537- } else if (pc.transitionState () == TransitionHandlingState::Requested) {
1567+ if (pc.transitionState () == TransitionHandlingState::Requested) {
15381568 LOG (info) << " Run stop requested during the scan, sending output to aggregator and then stopping to process new data" ;
15391569 mRunStopRequested = true ;
15401570 finalize (); // calculating average thresholds based on what's collected up to this moment
@@ -1769,13 +1799,13 @@ void ITSThresholdCalibrator::finalize()
17691799 if (mScanType == ' I' ) {
17701800 // Only ITHR scan: assign default ITHR = 50 if chip has no avg ITHR
17711801 for (auto & iRU : mRuSet ) {
1772- if (mRunTypeRU [iRU] >= nInjScaled * getNumberOfActiveLinks ( mActiveLinks [iRU]) || mRunStopRequested ) {
1802+ if (mFlagsRU [iRU] || mRunStopRequested ) {
17731803 std::vector<short int > chipList = getChipListFromRu (iRU, mActiveLinks [iRU]);
17741804 for (size_t i = 0 ; i < chipList.size (); i++) {
17751805 if ((chipList[i] % mChipModBase ) != mChipModSel ) {
17761806 continue ;
17771807 }
1778- if (!mThresholds .count (chipList[i])) {
1808+ if (!mThresholds .count (chipList[i]) && !isChipDB[chipList[i]] ) {
17791809 if (mVerboseOutput ) {
17801810 LOG (info) << " Setting ITHR = 50 for chip " << chipList[i];
17811811 }
@@ -1790,7 +1820,7 @@ void ITSThresholdCalibrator::finalize()
17901820 auto it = this ->mThresholds .cbegin ();
17911821 while (it != this ->mThresholds .cend ()) {
17921822 short int iRU = getRUID (it->first );
1793- if (!isCRUITS && (mRunTypeRU [iRU] < nInjScaled * getNumberOfActiveLinks ( mActiveLinks [iRU] ) && !mRunStopRequested ) ) {
1823+ if (!isCRUITS && (! mFlagsRU [iRU]) && !mRunStopRequested ) {
17941824 ++it;
17951825 continue ;
17961826 }
@@ -1804,8 +1834,8 @@ void ITSThresholdCalibrator::finalize()
18041834 }
18051835 if (mVerboseOutput ) {
18061836 LOG (info) << " Average or mpv " << name << " of chip " << it->first << " = " << outVal << " e-" ;
1807- }
1808- float status = ((float )it->second [4 ] / (float )(it-> second [ 4 ] + it-> second [ 5 ] )) * 100 .; // percentage of successful threshold extractions
1837+ }
1838+ float status = ((float )it->second [4 ] / (float )(mRowScan * N_COL )) * 100 .; // percentage of successful threshold extractions
18091839 if (status < mPercentageCut && (mScanType == ' I' || mScanType == ' V' )) {
18101840 if (mScanType == ' I' ) { // default ITHR if percentage of success < mPercentageCut
18111841 outVal = 50 .;
@@ -1822,6 +1852,7 @@ void ITSThresholdCalibrator::finalize()
18221852 }
18231853 std::vector<float > data = {outVal, rmsT, avgN, rmsN, status};
18241854 this ->addDatabaseEntry (it->first , name, data, false );
1855+ isChipDB[it->first ] = true ;
18251856 it = this ->mThresholds .erase (it);
18261857 }
18271858 } else if (this ->mScanType == ' D' || this ->mScanType == ' A' ) {
@@ -1831,7 +1862,7 @@ void ITSThresholdCalibrator::finalize()
18311862 auto itchip = this ->mPixelHits .cbegin ();
18321863 while (itchip != this ->mPixelHits .cend ()) { // loop over chips collected
18331864 short int iRU = getRUID (itchip->first );
1834- if (!isCRUITS && ( mRunTypeRU [iRU] < nInjScaled * getNumberOfActiveLinks ( mActiveLinks [iRU]) && !mRunStopRequested ) ) {
1865+ if (!isCRUITS && ! mFlagsRU [iRU] && !mRunStopRequested ) {
18351866 ++itchip;
18361867 continue ;
18371868 }
@@ -1845,7 +1876,7 @@ void ITSThresholdCalibrator::finalize()
18451876 if (this ->mVerboseOutput ) {
18461877 LOG (info) << " Chip " << itchip->first << " hits extracted" ;
18471878 }
1848- ++ itchip;
1879+ itchip = mPixelHits . erase (itchip) ;
18491880 }
18501881
18511882 auto it = this ->mNoisyPixID .cbegin ();
@@ -1886,7 +1917,7 @@ void ITSThresholdCalibrator::finalize()
18861917 auto itchip = this ->mPixelHits .cbegin ();
18871918 while (itchip != mPixelHits .cend ()) {
18881919 int iRU = getRUID (itchip->first );
1889- if (!mRunStopRequested && mRunTypeRU [iRU] < nInjScaled * getNumberOfActiveLinks ( mActiveLinks [iRU]) ) {
1920+ if (!mRunStopRequested && ! mFlagsRU [iRU]) {
18901921 ++itchip;
18911922 continue ;
18921923 }
@@ -1909,15 +1940,11 @@ void ITSThresholdCalibrator::finalize()
19091940 if (this ->mVerboseOutput ) {
19101941 LOG (info) << " Chip " << itchip->first << " hits extracted" ;
19111942 }
1912- ++ itchip;
1943+ itchip = mPixelHits . erase (itchip) ;
19131944 }
19141945 // reset RU counters so that the chips which are done will not appear again in the DCSConfigObject
19151946 }
19161947
1917- for (auto & ru : thisRUs) {
1918- mRunTypeRU [ru] = 0 ; // reset
1919- }
1920-
19211948 return ;
19221949}
19231950
@@ -1996,6 +2023,7 @@ DataProcessorSpec getITSThresholdCalibratorSpec(const ITSCalibInpConf& inpConf)
19962023 {" manual-step2" , VariantType::Int, 1 , {" Step2 value: defines the steps between manual-min2 and manual-max2. Default is 1. Use only in manual mode" }},
19972024 {" manual-scantype" , VariantType::String, " T" , {" scan type, can be D, T, I, V, P, p: use only in manual mode" }},
19982025 {" manual-strobewindow" , VariantType::Int, 5 , {" strobe duration in clock cycles, default is 5 = 125 ns: use only in manual mode" }},
2026+ {" manual-rowscan" , VariantType::Int, 512 , {" Number of ALPIDE rows scanned in the run: use only in manual mode" }},
19992027 {" save-tree" , VariantType::Bool, false , {" Flag to save ROOT tree on disk: use only in manual mode" }},
20002028 {" scale-ninj" , VariantType::Bool, false , {" Flag to activate the scale of the number of injects to be used to count hits from specific MEBs: use only in manual mode and in combination with --meb-select" }},
20012029 {" enable-mpv" , VariantType::Bool, false , {" Flag to enable calculation of most-probable value in vcasn/ithr scans" }},
0 commit comments