@@ -858,12 +858,16 @@ class VarManager : public TObject
858858 enum CalibObjects {
859859 kTPCElectronMean = 0 ,
860860 kTPCElectronSigma ,
861+ kTPCElectronStatus ,
861862 kTPCPionMean ,
862863 kTPCPionSigma ,
864+ kTPCPionStatus ,
863865 kTPCKaonMean ,
864866 kTPCKaonSigma ,
867+ kTPCKaonStatus ,
865868 kTPCProtonMean ,
866869 kTPCProtonSigma ,
870+ kTPCProtonStatus ,
867871 kNCalibObjects
868872 };
869873
@@ -1148,6 +1152,16 @@ class VarManager : public TObject
11481152 fgUsedVars[kTPCnSigmaPr_Corr ] = true ;
11491153 }
11501154 }
1155+
1156+ static void SetCalibrationType (int type, bool useInterpolation = true )
1157+ {
1158+ if (type < 0 || type > 2 ) {
1159+ LOG (fatal) << " Invalid calibration type. Must be 0, 1, or 2." );
1160+ }
1161+ fgCalibrationType = type;
1162+ fgUseInterpolatedCalibration = useInterpolation;
1163+ }
1164+
11511165 static TObject* GetCalibrationObject (CalibObjects calib)
11521166 {
11531167 auto obj = fgCalibs.find (calib);
@@ -1223,11 +1237,13 @@ class VarManager : public TObject
12231237
12241238 static std::map<CalibObjects, TObject*> fgCalibs; // map of calibration histograms
12251239 static bool fgRunTPCPostCalibration[4 ]; // 0-electron, 1-pion, 2-kaon, 3-proton
1240+ static int fgCalibrationType; // 0 - no calibration, 1 - calibration vs (TPCncls,pIN,eta) typically for pp, 2 - calibration vs (eta,nPV,nLong,tLong) typically for PbPb
1241+ static bool fgUseInterpolatedCalibration; // use interpolated calibration histograms (default: true)
12261242
12271243 VarManager& operator =(const VarManager& c);
12281244 VarManager (const VarManager& c);
12291245
1230- ClassDef (VarManager, 3 );
1246+ ClassDef (VarManager, 4 );
12311247};
12321248
12331249template <typename T, typename U, typename V>
@@ -1362,6 +1378,146 @@ o2::dataformats::GlobalFwdTrack VarManager::PropagateMuon(const T& muon, const C
13621378 return propmuon;
13631379}
13641380
1381+ double VarManager::ComputePIDcalibration (int species, double nSigmaValue) {
1382+ // species: 0 - electron, 1 - pion, 2 - kaon, 3 - proton
1383+ // Depending on the PID calibration type, we use different types of calibration histograms
1384+
1385+ if (fgCalibrationType == 1 ) {
1386+ // get the calibration histograms
1387+ CalibObjects calibMean, calibSigma;
1388+ switch (species) {
1389+ case 0 :
1390+ calibMean = kTPCElectronMean ;
1391+ calibSigma = kTPCElectronSigma ;
1392+ break ;
1393+ case 1 :
1394+ calibMean = kTPCPionMean ;
1395+ calibSigma = kTPCPionSigma ;
1396+ break ;
1397+ case 2 :
1398+ calibMean = kTPCKaonMean ;
1399+ calibSigma = kTPCKaonSigma ;
1400+ break ;
1401+ case 3 :
1402+ calibMean = kTPCProtonMean ;
1403+ calibSigma = kTPCProtonSigma ;
1404+ break ;
1405+ default :
1406+ LOG (fatal) << " Invalid species for PID calibration: " << species;
1407+ return -999.0 ; // Return zero if species is invalid
1408+ };
1409+
1410+ TH3F* calibMeanHist = reinterpret_cast <TH3F*>(fgCalibs[calibMean]);
1411+ TH3F* calibSigmaHist = reinterpret_cast <TH3F*>(fgCalibs[calibSigma]);
1412+ if (!calibMeanHist || !calibSigmaHist) {
1413+ LOG (fatal) << " Calibration histograms not found for species: " << species;
1414+ return -999.0 ; // Return zero if histograms are not found
1415+ }
1416+
1417+ // Get the bin indices for the calibration histograms
1418+ int binTPCncls = calibMeanHist->GetXaxis ()->FindBin (fgValues[kTPCncls ]);
1419+ binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls);
1420+ binTPCncls = (binTPCncls > calibMeanHist->GetXaxis ()->GetNbins () ? calibMeanHist->GetXaxis ()->GetNbins () : binTPCncls);
1421+ int binPin = calibMeanHist->GetYaxis ()->FindBin (fgValues[kPin ]);
1422+ binPin = (binPin == 0 ? 1 : binPin);
1423+ binPin = (binPin > calibMeanHist->GetYaxis ()->GetNbins () ? calibMeanHist->GetYaxis ()->GetNbins () : binPin);
1424+ int binEta = calibMeanHist->GetZaxis ()->FindBin (fgValues[kEta ]);
1425+ binEta = (binEta == 0 ? 1 : binEta);
1426+ binEta = (binEta > calibMeanHist->GetZaxis ()->GetNbins () ? calibMeanHist->GetZaxis ()->GetNbins () : binEta);
1427+
1428+ double mean = calibMeanHist->GetBinContent (binTPCncls, binPin, binEta);
1429+ double sigma = calibSigmaHist->GetBinContent (binTPCncls, binPin, binEta);
1430+ return (nSigmaValue - mean) / sigma; // Return the calibrated nSigma value
1431+ }
1432+ else if (fgCalibrationType == 2 ) {
1433+ // get the calibration histograms
1434+ CalibObjects calibMean, calibSigma, calibStatus;
1435+ switch (species) {
1436+ case 0 :
1437+ calibMean = kTPCElectronMean ;
1438+ calibSigma = kTPCElectronSigma ;
1439+ calibStatus = kTPCElectronStatus ;
1440+ break ;
1441+ case 1 :
1442+ calibMean = kTPCPionMean ;
1443+ calibSigma = kTPCPionSigma ;
1444+ calibStatus = kTPCPionStatus ;
1445+ break ;
1446+ case 2 :
1447+ calibMean = kTPCKaonMean ;
1448+ calibSigma = kTPCKaonSigma ;
1449+ calibStatus = kTPCKaonStatus ;
1450+ break ;
1451+ case 3 :
1452+ calibMean = kTPCProtonMean ;
1453+ calibSigma = kTPCProtonSigma ;
1454+ calibStatus = kTPCProtonStatus ;
1455+ break ;
1456+ default :
1457+ LOG (fatal) << " Invalid species for PID calibration: " << species;
1458+ return -999.0 ; // Return zero if species is invalid
1459+ };
1460+
1461+ THnF* calibMeanHist = reinterpret_cast <THnF*>(fgCalibs[calibMean]);
1462+ THnF* calibSigmaHist = reinterpret_cast <THnF*>(fgCalibs[calibSigma]);
1463+ THnF* calibStatusHist = reinterpret_cast <THnF*>(fgCalibs[calibStatus]);
1464+ if (!calibMeanHist || !calibSigmaHist || !calibStatusHist) {
1465+ LOG (fatal) << " Calibration histograms not found for species: " << species;
1466+ return -999.0 ; // Return zero if histograms are not found
1467+ }
1468+
1469+ // Get the bin indices for the calibration histograms
1470+ int binEta = calibMeanHist->GetAxis (0 )->FindBin (fgValues[kEta ]);
1471+ binEta = (binEta == 0 ? 1 : binEta);
1472+ binEta = (binEta > calibMeanHist->GetAxis (0 )->GetNbins () ? calibMeanHist->GetAxis (0 )->GetNbins () : binEta);
1473+ int binNpv = calibMeanHist->GetAxis (1 )->FindBin (fgValues[kVtxNcontribReal ]);
1474+ binNpv = (binNpv == 0 ? 1 : binNpv);
1475+ binNpv = (binNpv > calibMeanHist->GetAxis (1 )->GetNbins () ? calibMeanHist->GetAxis (1 )->GetNbins () : binNpv);
1476+ int binNlong = calibMeanHist->GetAxis (2 )->FindBin (fgValues[kNTPCcontribLongA ]);
1477+ binNlong = (binNlong == 0 ? 1 : binNlong);
1478+ binNlong = (binNlong > calibMeanHist->GetAxis (2 )->GetNbins () ? calibMeanHist->GetAxis (2 )->GetNbins () : binNlong);
1479+ int binTlong = calibMeanHist->GetAxis (3 )->FindBin (fgValues[kNTPCmedianTimeLongA ]);
1480+ binTlong = (binTlong == 0 ? 1 : binTlong);
1481+ binTlong = (binTlong > calibMeanHist->GetAxis (3 )->GetNbins () ? calibMeanHist->GetAxis (3 )->GetNbins () : binTlong);
1482+
1483+ int bin[4 ] = {binEta, binNpv, binNlong, binTlong};
1484+ int status = reinterpret_cast <int >(calibStatusHist->GetBinContent (bin));
1485+ double mean = calibMeanHist->GetBinContent (bin);
1486+ double sigma = calibSigmaHist->GetBinContent (bin);
1487+ switch (status) {
1488+ case 0 :
1489+ // good calibration, return the calibrated nSigma value
1490+ return (nSigmaValue - mean) / sigma;
1491+ break ;
1492+ case 1 :
1493+ // calibration not valid, return the original nSigma value
1494+ return nSigmaValue;
1495+ break ;
1496+ case 2 : // calibration constant has poor stat uncertainty, consider the user option for what to do
1497+ case 3 :
1498+ // calibration constants have been interpolated
1499+ if (fgUseInterpolatedCalibration) {
1500+ return (nSigmaValue - mean) / sigma;
1501+ } else {
1502+ // return the original nSigma value
1503+ return nSigmaValue;
1504+ }
1505+ break ;
1506+ case 4 :
1507+ // calibration constants interpolation failed, return the original nSigma value
1508+ return nSigmaValue;
1509+ break ;
1510+ default :
1511+ return nSigmaValue; // unknown status, return the original nSigma value
1512+ break ;
1513+ };
1514+ } else {
1515+ // unknown calibration type, return the original nSigma value
1516+ LOG (fatal) << " Unknown calibration type: " << fgCalibrationType;
1517+ return nSigmaValue; // Return the original nSigma value
1518+ }
1519+ }
1520+
13651521template <uint32_t fillMap, typename T, typename C>
13661522void VarManager::FillMuonPDca (const T& muon, const C& collision, float * values)
13671523{
@@ -2426,92 +2582,38 @@ void VarManager::FillTrack(T const& track, float* values)
24262582 }
24272583 // compute TPC postcalibrated electron nsigma based on calibration histograms from CCDB
24282584 if (fgUsedVars[kTPCnSigmaEl_Corr ] && fgRunTPCPostCalibration[0 ]) {
2429- TH3F* calibMean = reinterpret_cast <TH3F*>(fgCalibs[kTPCElectronMean ]);
2430- TH3F* calibSigma = reinterpret_cast <TH3F*>(fgCalibs[kTPCElectronSigma ]);
2431-
2432- int binTPCncls = calibMean->GetXaxis ()->FindBin (values[kTPCncls ]);
2433- binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls);
2434- binTPCncls = (binTPCncls > calibMean->GetXaxis ()->GetNbins () ? calibMean->GetXaxis ()->GetNbins () : binTPCncls);
2435- int binPin = calibMean->GetYaxis ()->FindBin (values[kPin ]);
2436- binPin = (binPin == 0 ? 1 : binPin);
2437- binPin = (binPin > calibMean->GetYaxis ()->GetNbins () ? calibMean->GetYaxis ()->GetNbins () : binPin);
2438- int binEta = calibMean->GetZaxis ()->FindBin (values[kEta ]);
2439- binEta = (binEta == 0 ? 1 : binEta);
2440- binEta = (binEta > calibMean->GetZaxis ()->GetNbins () ? calibMean->GetZaxis ()->GetNbins () : binEta);
2441-
2442- double mean = calibMean->GetBinContent (binTPCncls, binPin, binEta);
2443- double width = calibSigma->GetBinContent (binTPCncls, binPin, binEta);
24442585 if (!isTPCCalibrated) {
2445- values[kTPCnSigmaEl_Corr ] = ( values[kTPCnSigmaEl ] - mean) / width ;
2586+ values[kTPCnSigmaEl_Corr ] = ComputePIDcalibration ( 0 , values[kTPCnSigmaEl ]) ;
24462587 } else {
2588+ LOG (fatal) << " TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration." ;
24472589 values[kTPCnSigmaEl_Corr ] = track.tpcNSigmaEl ();
24482590 }
24492591 }
2592+
24502593 // compute TPC postcalibrated pion nsigma if required
24512594 if (fgUsedVars[kTPCnSigmaPi_Corr ] && fgRunTPCPostCalibration[1 ]) {
2452- TH3F* calibMean = reinterpret_cast <TH3F*>(fgCalibs[kTPCPionMean ]);
2453- TH3F* calibSigma = reinterpret_cast <TH3F*>(fgCalibs[kTPCPionSigma ]);
2454-
2455- int binTPCncls = calibMean->GetXaxis ()->FindBin (values[kTPCncls ]);
2456- binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls);
2457- binTPCncls = (binTPCncls > calibMean->GetXaxis ()->GetNbins () ? calibMean->GetXaxis ()->GetNbins () : binTPCncls);
2458- int binPin = calibMean->GetYaxis ()->FindBin (values[kPin ]);
2459- binPin = (binPin == 0 ? 1 : binPin);
2460- binPin = (binPin > calibMean->GetYaxis ()->GetNbins () ? calibMean->GetYaxis ()->GetNbins () : binPin);
2461- int binEta = calibMean->GetZaxis ()->FindBin (values[kEta ]);
2462- binEta = (binEta == 0 ? 1 : binEta);
2463- binEta = (binEta > calibMean->GetZaxis ()->GetNbins () ? calibMean->GetZaxis ()->GetNbins () : binEta);
2464-
2465- double mean = calibMean->GetBinContent (binTPCncls, binPin, binEta);
2466- double width = calibSigma->GetBinContent (binTPCncls, binPin, binEta);
24672595 if (!isTPCCalibrated) {
2468- values[kTPCnSigmaPi_Corr ] = ( values[kTPCnSigmaPi ] - mean) / width ;
2596+ values[kTPCnSigmaPi_Corr ] = ComputePIDcalibration ( 1 , values[kTPCnSigmaPi ]) ;
24692597 } else {
2598+ LOG (fatal) << " TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration." ;
24702599 values[kTPCnSigmaPi_Corr ] = track.tpcNSigmaPi ();
24712600 }
24722601 }
24732602 if (fgUsedVars[kTPCnSigmaKa_Corr ] && fgRunTPCPostCalibration[2 ]) {
2474- TH3F* calibMean = reinterpret_cast <TH3F*>(fgCalibs[kTPCKaonMean ]);
2475- TH3F* calibSigma = reinterpret_cast <TH3F*>(fgCalibs[kTPCKaonSigma ]);
2476-
2477- int binTPCncls = calibMean->GetXaxis ()->FindBin (values[kTPCncls ]);
2478- binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls);
2479- binTPCncls = (binTPCncls > calibMean->GetXaxis ()->GetNbins () ? calibMean->GetXaxis ()->GetNbins () : binTPCncls);
2480- int binPin = calibMean->GetYaxis ()->FindBin (values[kPin ]);
2481- binPin = (binPin == 0 ? 1 : binPin);
2482- binPin = (binPin > calibMean->GetYaxis ()->GetNbins () ? calibMean->GetYaxis ()->GetNbins () : binPin);
2483- int binEta = calibMean->GetZaxis ()->FindBin (values[kEta ]);
2484- binEta = (binEta == 0 ? 1 : binEta);
2485- binEta = (binEta > calibMean->GetZaxis ()->GetNbins () ? calibMean->GetZaxis ()->GetNbins () : binEta);
2486-
2487- double mean = calibMean->GetBinContent (binTPCncls, binPin, binEta);
2488- double width = calibSigma->GetBinContent (binTPCncls, binPin, binEta);
2603+ // compute TPC postcalibrated kaon nsigma if required
24892604 if (!isTPCCalibrated) {
2490- values[kTPCnSigmaKa_Corr ] = ( values[kTPCnSigmaKa ] - mean) / width ;
2605+ values[kTPCnSigmaKa_Corr ] = ComputePIDcalibration ( 2 , values[kTPCnSigmaKa ]) ;
24912606 } else {
2607+ LOG (fatal) << " TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration." ;
24922608 values[kTPCnSigmaKa_Corr ] = track.tpcNSigmaKa ();
24932609 }
24942610 }
24952611 // compute TPC postcalibrated proton nsigma if required
24962612 if (fgUsedVars[kTPCnSigmaPr_Corr ] && fgRunTPCPostCalibration[3 ]) {
2497- TH3F* calibMean = reinterpret_cast <TH3F*>(fgCalibs[kTPCProtonMean ]);
2498- TH3F* calibSigma = reinterpret_cast <TH3F*>(fgCalibs[kTPCProtonSigma ]);
2499-
2500- int binTPCncls = calibMean->GetXaxis ()->FindBin (values[kTPCncls ]);
2501- binTPCncls = (binTPCncls == 0 ? 1 : binTPCncls);
2502- binTPCncls = (binTPCncls > calibMean->GetXaxis ()->GetNbins () ? calibMean->GetXaxis ()->GetNbins () : binTPCncls);
2503- int binPin = calibMean->GetYaxis ()->FindBin (values[kPin ]);
2504- binPin = (binPin == 0 ? 1 : binPin);
2505- binPin = (binPin > calibMean->GetYaxis ()->GetNbins () ? calibMean->GetYaxis ()->GetNbins () : binPin);
2506- int binEta = calibMean->GetZaxis ()->FindBin (values[kEta ]);
2507- binEta = (binEta == 0 ? 1 : binEta);
2508- binEta = (binEta > calibMean->GetZaxis ()->GetNbins () ? calibMean->GetZaxis ()->GetNbins () : binEta);
2509-
2510- double mean = calibMean->GetBinContent (binTPCncls, binPin, binEta);
2511- double width = calibSigma->GetBinContent (binTPCncls, binPin, binEta);
25122613 if (!isTPCCalibrated) {
2513- values[kTPCnSigmaPr_Corr ] = ( values[kTPCnSigmaPr ] - mean) / width ;
2614+ values[kTPCnSigmaPr_Corr ] = ComputePIDcalibration ( 3 , values[kTPCnSigmaPr ]) ;
25142615 } else {
2616+ LOG (fatal) << " TPC PID postcalibration is configured but the tracks are already postcalibrated. This is not allowed. Please check your configuration." ;
25152617 values[kTPCnSigmaPr_Corr ] = track.tpcNSigmaPr ();
25162618 }
25172619 }
0 commit comments