@@ -371,8 +371,10 @@ void ITSThresholdCalibrator::initThresholdTree(bool recreate /*=true*/)
371371 mThresholdTree = new TTree (" ITS_calib_tree" , " ITS_calib_tree" );
372372 mThresholdTree ->Branch (" chipid" , &vChipid, " vChipID[1024]/S" );
373373 mThresholdTree ->Branch (" row" , &vRow, " vRow[1024]/S" );
374- if (mScanType == ' T' ) {
375- mThresholdTree ->Branch (" thr" , &vThreshold, " vThreshold[1024]/S" );
374+ if (mScanType == ' T' || mScanType == ' V' || mScanType == ' I' ) {
375+ std::string bName = mScanType == ' T' ? " thr" : mScanType == ' V' ? " vcasn"
376+ : " ithr" ;
377+ mThresholdTree ->Branch (bName.c_str (), &vThreshold, " vThreshold[1024]/S" );
376378 mThresholdTree ->Branch (" noise" , &vNoise, " vNoise[1024]/F" );
377379 mThresholdTree ->Branch (" spoints" , &vPoints, " vPoints[1024]/b" );
378380 mThresholdTree ->Branch (" success" , &vSuccess, " vSuccess[1024]/O" );
@@ -384,7 +386,7 @@ void ITSThresholdCalibrator::initThresholdTree(bool recreate /*=true*/)
384386 } else if (mScanType == ' P' ) {
385387 mThresholdTree ->Branch (" n_hits" , &vThreshold, " vThreshold[1024]/S" );
386388 mThresholdTree ->Branch (" strobedel" , &vMixData, " vMixData[1024]/S" );
387- } else if (mScanType == ' p' ) {
389+ } else if (mScanType == ' p' || mScanType == ' t ' ) {
388390 mThresholdTree ->Branch (" n_hits" , &vThreshold, " vThreshold[1024]/S" );
389391 mThresholdTree ->Branch (" strobedel" , &vMixData, " vMixData[1024]/S" );
390392 mThresholdTree ->Branch (" charge" , &vCharge, " vCharge[1024]/b" );
@@ -675,7 +677,7 @@ void ITSThresholdCalibrator::extractThresholdRow(const short int& chipID, const
675677 this ->mDeadPixID [chipID].push_back (col_i * 1000 + row);
676678 }
677679 }
678- } else if (this ->mScanType == ' P' || this ->mScanType == ' p' || mScanType == ' R' ) {
680+ } else if (this ->mScanType == ' P' || this ->mScanType == ' p' || mScanType == ' R' || mScanType == ' t ' ) {
679681 // Loop over all columns (pixels) in the row
680682 for (short int var1_i = 0 ; var1_i < this ->N_RANGE ; var1_i++) {
681683 for (short int chg_i = 0 ; chg_i < this ->N_RANGE2 ; chg_i++) {
@@ -742,7 +744,7 @@ void ITSThresholdCalibrator::extractThresholdRow(const short int& chipID, const
742744 mSlopeTree ->Fill ();
743745 }
744746
745- } else { // threshold, vcasn, ithr
747+ } else { // threshold, vcasn, ithr, vresetd_2d
746748
747749 short int iRU = getRUID (chipID);
748750#ifdef WITH_OPENMP
@@ -779,32 +781,30 @@ void ITSThresholdCalibrator::extractThresholdRow(const short int& chipID, const
779781 }
780782
781783 // Fill the ScTree tree
782- if (mScanType == ' T' ) { // TODO: store also for other scans?
783- for (int ichg = mMin ; ichg <= mMax ; ichg++ ) {
784+ if (mScanType == ' T' || mScanType == ' V ' || mScanType == ' I ' ) { // TODO: store also for other scans?
785+ for (int ichg = mMin ; ichg <= mMax ; ichg += mStep ) {
784786 for (short int col_i = 0 ; col_i < this ->N_COL ; col_i += mColStep ) {
785787 vCharge[col_i] = ichg;
786- vHits[col_i] = mPixelHits [chipID][row][col_i][0 ][ichg - mMin ];
788+ vHits[col_i] = mPixelHits [chipID][row][col_i][0 ][( ichg - mMin ) / mStep ];
787789 }
788790 mScTree ->Fill ();
789791 }
790792 }
791793 } // end of the else
792794
793795 // Saves threshold information to internal memory
794- if (mScanType != ' P' && mScanType != ' p' && mScanType != ' R' && mScanType != ' r' ) {
796+ if (mScanType != ' P' && mScanType != ' p' && mScanType != ' t ' && mScanType != ' R' && mScanType != ' r' ) {
795797 this ->saveThreshold ();
796798 }
797799}
798800
799801// ////////////////////////////////////////////////////////////////////////////
800802void ITSThresholdCalibrator::saveThreshold ()
801803{
802- // In the case of a full threshold scan, write to TTree
803- if (this ->mScanType == ' T' || this ->mScanType == ' D' || this ->mScanType == ' A' || this ->mScanType == ' P' || this ->mScanType == ' p' || this ->mScanType == ' R' || this ->mScanType == ' r' ) {
804- this ->mThresholdTree ->Fill ();
805- }
804+ // write to TTree
805+ this ->mThresholdTree ->Fill ();
806806
807- if (this ->mScanType != ' D ' && this -> mScanType ! = ' A ' && this ->mScanType != ' P ' && this -> mScanType ! = ' p ' && this ->mScanType != ' R ' && this -> mScanType ! = ' r ' ) {
807+ if (this ->mScanType = = ' V ' || this ->mScanType = = ' I ' || this ->mScanType = = ' T ' ) {
808808 // Save info in a map for later averaging
809809 int sumT = 0 , sumSqT = 0 , sumN = 0 , sumSqN = 0 ;
810810 int countSuccess = 0 , countUnsuccess = 0 ;
@@ -957,6 +957,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
957957 // ATTENTION: with back bias (VCASNBB) put max vcasn to 130 (default is 80)
958958 // 4 rows per chip
959959 this ->mScanType = ' V' ;
960+ this ->initThresholdTree ();
960961 this ->mMin = inMinVcasn; // 30 is the default
961962 this ->mMax = inMaxVcasn; // 80 is the default
962963 this ->N_RANGE = mMax - mMin + 1 ;
@@ -967,6 +968,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
967968 // S-curve is backwards from VCASN case, otherwise same
968969 // 4 rows per chip
969970 this ->mScanType = ' I' ;
971+ this ->initThresholdTree ();
970972 this ->mMin = inMinIthr; // 25 is the default
971973 this ->mMax = inMaxIthr; // 100 is the default
972974 this ->N_RANGE = mMax - mMin + 1 ;
@@ -1003,27 +1005,38 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
10031005 this ->mStrobeWindow = 5 ; // it's 4 but it corresponds to 4+1 (as from alpide manual)
10041006 this ->N_RANGE = (mMax - mMin ) / mStep + 1 ;
10051007 this ->mCheckExactRow = true ;
1006- } else if (runtype == TOT_CALIBRATION || runtype == TOT_CALIBRATION_1_ROW) {
1008+ } else if (runtype == TOT_CALIBRATION_1_ROW) {
10071009 // Pulse length scan 2D (charge vs strobe delay)
10081010 this ->mScanType = ' p' ; // small p, just to distinguish from capital P
10091011 this ->initThresholdTree ();
10101012 this ->mFitType = NO_FIT;
1011- this ->mMin = (runtype == TOT_CALIBRATION) ? 300 : 0 ;
1012- this ->mMax = (runtype == TOT_CALIBRATION) ? 1100 : 2000 ; // strobe delay goes from 0 to 2000 or 1100 (included) in steps of 10
1013+ this ->mMin = 0 ;
1014+ this ->mMax = 2000 ; // strobe delay goes from 0 to 2000 in steps of 10
1015+ this ->mStep = 10 ;
1016+ this ->mStrobeWindow = 2 ; // it's 1 but it corresponds to 1+1 (as from alpide manual)
1017+ this ->N_RANGE = (mMax - mMin ) / mStep + 1 ;
1018+ this ->mMin2 = 0 ; // charge min
1019+ this ->mMax2 = 170 ; // charge max
1020+ this ->mStep2 = 1 ; // step for the charge
1021+ this ->N_RANGE2 = (mMax2 - mMin2 ) / mStep2 + 1 ;
1022+ this ->mCheckExactRow = true ;
1023+ } else if (runtype == TOT_CALIBRATION) {
1024+ // TOT calibration (like pulse shape 2D but with a reduced range in both strobe delay and charge)
1025+ this ->mScanType = ' t' ;
1026+ this ->initThresholdTree ();
1027+ this ->mFitType = NO_FIT;
1028+ this ->mMin = 300 ;
1029+ this ->mMax = 1100 ; // strobe delay goes from 300 to 1100 (included) in steps of 10
10131030 this ->mStep = 10 ;
10141031 this ->mStrobeWindow = 2 ; // it's 1 but it corresponds to 1+1 (as from alpide manual)
10151032 this ->N_RANGE = (mMax - mMin ) / mStep + 1 ;
10161033 this ->mMin2 = 30 ; // charge min
10171034 this ->mMax2 = 60 ; // charge max
10181035 this ->mStep2 = 30 ; // step for the charge
10191036 this ->mCalculate2DParams = false ; // do not calculate time over threshold, pulse length, etc..
1020- if (runtype == TOT_CALIBRATION_1_ROW) {
1021- this ->mMin2 = 0 ; // charge min
1022- this ->mMax2 = 170 ; // charge max
1023- this ->mStep2 = 1 ; // step for the charge
1024- }
10251037 this ->N_RANGE2 = (mMax2 - mMin2 ) / mStep2 + 1 ;
10261038 this ->mCheckExactRow = true ;
1039+
10271040 } else if (runtype == VRESETD_150 || runtype == VRESETD_300 || runtype == VRESETD_2D) {
10281041 this ->mScanType = ' R' ; // capital R is for 1D scan
10291042 if (runtype == VRESETD_150 || runtype == VRESETD_300) {
@@ -1060,7 +1073,7 @@ void ITSThresholdCalibrator::setRunType(const short int& runtype)
10601073 if (saveTree) {
10611074 this ->initThresholdTree ();
10621075 }
1063- this ->mFitType = (mScanType == ' D' || mScanType == ' A' || mScanType == ' P' || mScanType == ' p' ) ? NO_FIT : mFitType ;
1076+ this ->mFitType = (mScanType == ' D' || mScanType == ' A' || mScanType == ' P' || mScanType == ' p' || mScanType == ' t ' ) ? NO_FIT : mFitType ;
10641077 this ->mCheckExactRow = (mScanType == ' D' || mScanType == ' A' ) ? false : true ;
10651078 if (scaleNinj) {
10661079 nInjScaled = nInj / 3 ;
@@ -1264,7 +1277,7 @@ std::vector<float> ITSThresholdCalibrator::calculatePulseParams2D(const short in
12641277void ITSThresholdCalibrator::extractAndUpdate (const short int & chipID, const short int & row)
12651278{
12661279 // In threshold scan case, reset mThresholdTree before writing to a new file
1267- if ((this ->mScanType == ' T ' || this -> mScanType == ' D ' || this -> mScanType == ' A ' || this -> mScanType == ' P ' || this -> mScanType == ' p ' || mScanType == ' R ' || mScanType == ' r ' ) && (( this -> mRowCounter )++ == N_ROWS_PER_FILE) ) {
1280+ if ((this ->mRowCounter )++ == N_ROWS_PER_FILE) {
12681281 // Finalize output and create a new TTree and ROOT file
12691282 this ->finalizeOutput ();
12701283 this ->initThresholdTree ();
@@ -1353,7 +1366,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
13531366 loopval = !mCdwVersion ? (short int )((calib.calibUserField >> 16 ) & 0xff ) : (short int )((calib.calibUserField >> 16 ) & 0xffff );
13541367 }
13551368
1356- if (this ->mScanType == ' p' || this ->mScanType == ' r' ) {
1369+ if (this ->mScanType == ' p' || this ->mScanType == ' t ' || this -> mScanType == ' r' ) {
13571370 realcharge = 170 - ((short int )(calib.calibUserField >> 32 )) & 0x1fff ; // not existing with CDW v0
13581371 }
13591372
@@ -1363,9 +1376,12 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
13631376 cwcnt = (short int )(calib.calibCounter );
13641377 // count the last N injections
13651378 short int checkVal = (mScanType == ' I' ) ? mMin : mMax ;
1366- if ((mScanType != ' r' && loopval == checkVal) || (mScanType == ' r' && realcharge == mMax2 )) {
1379+ if ((mScanType != ' r' && mScanType != ' p' && mScanType != ' t' && loopval == checkVal) ||
1380+ (mScanType == ' r' && realcharge == mMax2 ) ||
1381+ (mScanType == ' p' && realcharge == mMin2 ) ||
1382+ (mScanType == ' t' && loopval == checkVal && realcharge == mMax2 )) {
13671383 mCdwCntRU [iRU][row]++;
1368- mLoopVal [iRU][row] = loopval; // keep loop val (relevant for VRESET2D scan only)
1384+ mLoopVal [iRU][row] = loopval; // keep loop val (relevant for VRESET2D and TOT_1ROW scan only)
13691385 }
13701386 if (this ->mVerboseOutput ) {
13711387 LOG (info) << " RU: " << iRU << " CDWcounter: " << cwcnt << " row: " << row << " Loopval: " << loopval << " realcharge: " << realcharge << " confDBv: " << mCdwVersion ;
@@ -1393,18 +1409,17 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
13931409 cwcnt = 0 ;
13941410 }
13951411
1396- if (loopval > this ->mMax || loopval < this ->mMin || ((mScanType == ' p' || mScanType == ' r' ) && (realcharge > this ->mMax2 || realcharge < this ->mMin2 ))) {
1412+ if (loopval > this ->mMax || loopval < this ->mMin || ((mScanType == ' p' || mScanType == ' t ' || mScanType == ' r' ) && (realcharge > this ->mMax2 || realcharge < this ->mMin2 ))) {
13971413 if (this ->mVerboseOutput ) {
13981414 LOG (warning) << " CW issues - loopval value " << loopval << " out of range for min " << this ->mMin
13991415 << " and max " << this ->mMax << " (range: " << N_RANGE << " )" ;
1400- if (mScanType == ' p' || mScanType == ' r' ) {
1416+ if (mScanType == ' p' || mScanType == ' r' || mScanType == ' t ' ) {
14011417 LOG (warning) << " and/or realcharge value " << realcharge << " out of range from min " << this ->mMin2
14021418 << " and max " << this ->mMax2 << " (range: " << N_RANGE2 << " )" ;
14031419 }
14041420 }
14051421 } else {
14061422 std::vector<short int > mChips ;
1407- std::map<short int , bool > mChipsForbRows ;
14081423 // loop to retrieve list of chips and start tagging bad dcols if the hits does not come from this row
14091424 for (unsigned int idig = rofIndex; idig < rofIndex + rofNEntries; idig++) { // gets chipid
14101425 auto & d = digits[idig];
@@ -1425,17 +1440,6 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
14251440 short int ru = getRUID (chipID);
14261441 mActiveLinks [ru][getLinkID (chipID, ru)] = true ;
14271442 // check rows and allocate memory
1428- if (mScanType != ' r' && mForbiddenRows .count (chipID)) {
1429- for (int iforb = mForbiddenRows [chipID].size () - 1 ; iforb >= 0 ; iforb--) {
1430- if (mForbiddenRows [chipID][iforb] == row) {
1431- mChipsForbRows [chipID] = true ;
1432- break ;
1433- }
1434- }
1435- }
1436- if (mChipsForbRows [chipID]) {
1437- continue ;
1438- }
14391443 if (!this ->mPixelHits .count (chipID)) {
14401444 if (mScanType == ' D' || mScanType == ' A' ) { // for digital and analog scan initialize the full matrix for each chipID
14411445 for (int irow = 0 ; irow < 512 ; irow++) {
@@ -1461,7 +1465,7 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
14611465 continue ;
14621466 }
14631467
1464- if (! mChipsForbRows [chipID] && (!mCheckExactRow || d.getRow () == row) && (mMeb < 0 || cwcnt % 3 == mMeb )) { // row has NOT to be forbidden and we ignore hits coming from other rows (potential masking issue on chip)
1468+ if ((!mCheckExactRow || d.getRow () == row) && (mMeb < 0 || cwcnt % 3 == mMeb )) { // row has NOT to be forbidden and we ignore hits coming from other rows (potential masking issue on chip)
14651469 // Increment the number of counts for this pixel
14661470 this ->mPixelHits [chipID][d.getRow ()][col][chgPoint][loopPoint]++;
14671471 }
@@ -1492,7 +1496,16 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
14921496 }
14931497 // Check if scan of a row is finished: only for specific scans!
14941498 bool passCondition = (mCdwCntRU [ruIndex][row] >= nInjScaled * nL);
1495- if (mScanType != ' D' && mScanType != ' A' && mScanType != ' P' && mScanType != ' p' && mScanType != ' R' && passCondition) {
1499+ if (mScanType == ' p' || mScanType == ' t' ) {
1500+ passCondition = passCondition && (mLoopVal [ruIndex][row] == mMax );
1501+ if (mVerboseOutput ) {
1502+ LOG (info) << " PassCondition: " << passCondition << " - (mCdwCntRU,mLoopVal) of RU" << ruIndex << " row " << row << " = (" << mCdwCntRU [ruIndex][row] << " , " << mLoopVal [ruIndex][row] << " )" ;
1503+ }
1504+ } else if (mVerboseOutput ) {
1505+ LOG (info) << " PassCondition: " << passCondition << " - mCdwCntRU of RU" << ruIndex << " row " << row << " = " << mCdwCntRU [ruIndex][row];
1506+ }
1507+
1508+ if (mScanType != ' D' && mScanType != ' A' && mScanType != ' P' && mScanType != ' R' && passCondition) {
14961509 // extract data from the row
14971510 for (short int iChip = 0 ; iChip < chipEnabled.size (); iChip++) {
14981511 short int chipID = chipEnabled[iChip];
@@ -1503,10 +1516,9 @@ void ITSThresholdCalibrator::run(ProcessingContext& pc)
15031516 if (mPixelHits .count (chipID)) {
15041517 if (mPixelHits [chipID].count (row)) { // make sure the row exists
15051518 extractAndUpdate (chipID, row);
1506- if (mScanType != ' r ' || (mScanType == ' r' && mLoopVal [ruIndex][row] == mMax )) {
1519+ if (mScanType != ' p ' && (mScanType != ' r' || mLoopVal [ruIndex][row] == mMax )) { // do not erase for scantype = p because in finalize() we have calculate2Dparams
15071520 mPixelHits [chipID].erase (row);
15081521 }
1509- mForbiddenRows [chipID].push_back (row);
15101522 }
15111523 }
15121524 }
@@ -1889,11 +1901,15 @@ void ITSThresholdCalibrator::finalize()
18891901 if (mVerboseOutput ) {
18901902 LOG (info) << " Extracting hits from pulse shape scan or vresetd scan, chip " << itchip->first ;
18911903 }
1892- auto itrow = this ->mPixelHits [itchip->first ].cbegin ();
1893- while (itrow != mPixelHits [itchip->first ].cend ()) { // in case there are multiple rows, for now it's 1 row
1894- this ->extractAndUpdate (itchip->first , itrow->first ); // fill the tree
1895- ++itrow;
1904+
1905+ if (mScanType != ' p' ) { // done already in run()
1906+ auto itrow = this ->mPixelHits [itchip->first ].cbegin ();
1907+ while (itrow != mPixelHits [itchip->first ].cend ()) { // in case there are multiple rows, for now it's 1 row
1908+ this ->extractAndUpdate (itchip->first , itrow->first ); // fill the tree - for mScanType = p, it is done already in run()
1909+ ++itrow;
1910+ }
18961911 }
1912+
18971913 if (mCalculate2DParams && (mScanType == ' P' || mScanType == ' p' )) {
18981914 this ->addDatabaseEntry (itchip->first , name, mScanType == ' P' ? calculatePulseParams (itchip->first ) : calculatePulseParams2D (itchip->first ), false );
18991915 }
0 commit comments