Skip to content

Commit 34384e0

Browse files
authored
ITS Calib: ROOT trees for VCASN and ITHR scan + new features (#14008)
* ROOT tree for vcasn and ithr scan + processing of tot_full and ps_2d scans row by row instead of EOR * allow calculation of 2D params in finalize() for pulse shape 2D scan
1 parent 5d76679 commit 34384e0

File tree

2 files changed

+65
-50
lines changed

2 files changed

+65
-50
lines changed

Detectors/ITSMFT/ITS/workflow/include/ITSWorkflow/ThresholdCalibratorSpec.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ class ITSThresholdCalibrator : public Task
148148

149149
// Hash tables to store the hit and threshold information per pixel
150150
std::map<short int, std::map<int, std::vector<std::vector<std::vector<unsigned short int>>>>> mPixelHits;
151-
std::map<short int, std::deque<short int>> mForbiddenRows;
152151
// Unordered map for saving sum of values (thr/ithr/vcasn) for avg calculation
153152
std::map<short int, std::array<long int, 6>> mThresholds;
154153
// Map including PixID for noisy pixels

Detectors/ITSMFT/ITS/workflow/src/ThresholdCalibratorSpec.cxx

Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -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
//////////////////////////////////////////////////////////////////////////////
800802
void 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
12641277
void 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

Comments
 (0)