@@ -250,6 +250,136 @@ class TOFResoParamsV2 : public o2::tof::Parameters<13>
250250 TGraph* gNegEtaTimeCorr = nullptr ; // / Time shift correction for negative tracks
251251};
252252
253+ // / \brief Next implementation class to store TOF response parameters for exp. times
254+ class TOFResoParamsV3 : public o2 ::tof::Parameters<13 >
255+ {
256+ public:
257+ TOFResoParamsV3 () : Parameters(std::array<std::string, 13 >{" TrkRes.Pi.P0" , " TrkRes.Pi.P1" , " TrkRes.Pi.P2" , " TrkRes.Pi.P3" , " time_resolution" ,
258+ " TrkRes.Ka.P0" , " TrkRes.Ka.P1" , " TrkRes.Ka.P2" , " TrkRes.Ka.P3" ,
259+ " TrkRes.Pr.P0" , " TrkRes.Pr.P1" , " TrkRes.Pr.P2" , " TrkRes.Pr.P3" },
260+ " TOFResoParamsV3" )
261+ {
262+ setParameters (std::array<float , 13 >{0.008 , 0.008 , 0.002 , 40.0 , 60.0 ,
263+ 0.008 , 0.008 , 0.002 , 40.0 ,
264+ 0.008 , 0.008 , 0.002 , 40.0 });
265+ } // Default constructor with default parameters
266+
267+ ~TOFResoParamsV3 () = default ;
268+
269+ // Momentum shift for charge calibration
270+ void setMomentumChargeShiftParameters (std::unordered_map<std::string, float > const & pars)
271+ {
272+ if (pars.count (" Shift.etaN" ) == 0 ) { // If the map does not contain the number of eta bins, we assume that no correction has to be applied
273+ mEtaN = 0 ;
274+ return ;
275+ }
276+ mEtaN = static_cast <int >(pars.at (" Shift.etaN" ));
277+ if (mEtaN <= 0 ) {
278+ LOG (fatal) << " TOFResoParamsV3 shift: etaN must be positive" ;
279+ }
280+ mEtaStart = pars.at (" Shift.etaStart" );
281+ mEtaStop = pars.at (" Shift.etaStop" );
282+ if (mEtaStart >= mEtaStop ) {
283+ LOG (fatal) << " TOFResoParamsV3 shift: etaStart must be smaller than etaStop" ;
284+ }
285+ mInvEtaWidth = 1 .f / ((mEtaStop - mEtaStart ) / mEtaN );
286+ mContent .clear ();
287+ mContent .resize (mEtaN );
288+ for (int i = 0 ; i < mEtaN ; ++i) {
289+ mContent [i] = pars.at (Form (" Shift.etaC%i" , i));
290+ }
291+ }
292+
293+ float getMomentumChargeShift (float eta) const
294+ {
295+ if (mEtaN == 0 ) { // No correction
296+ // LOG(info) << "TOFResoParamsV3 shift: no correction mEtaN is " << mEtaN;
297+ return 0 .f ;
298+ }
299+ const int & etaIndex = (eta <= mEtaStart ) ? 0 : (eta >= mEtaStop ? (mEtaN - 1 ) : (eta - mEtaStart ) * mInvEtaWidth );
300+ // LOG(info) << "TOFResoParamsV3 shift: correction for eta " << eta << " is for index " << etaIndex << " = " << shift;
301+ return mContent .at (etaIndex);
302+ }
303+
304+ void printMomentumChargeShiftParameters () const
305+ {
306+ LOG (info) << " TOF momentum shift parameters" ;
307+ LOG (info) << " etaN: " << mEtaN ;
308+ LOG (info) << " etaStart: " << mEtaStart ;
309+ LOG (info) << " etaStop: " << mEtaStop ;
310+ LOG (info) << " content size " << mContent .size ();
311+ for (int i = 0 ; i < mEtaN ; ++i) {
312+ LOG (info) << " etaC" << i << " : " << mContent [i];
313+ }
314+ }
315+
316+ // Time shift for post calibration
317+ void setTimeShiftParameters (std::unordered_map<std::string, float > const & pars, bool positive)
318+ {
319+ std::string baseOpt = positive ? " TimeShift.Pos." : " TimeShift.Neg." ;
320+
321+ if (pars.count (baseOpt + " GetN" ) == 0 ) { // If the map does not contain the number of eta bins, we assume that no correction has to be applied
322+ return ;
323+ }
324+ const int nPoints = static_cast <int >(pars.at (baseOpt + " GetN" ));
325+ if (nPoints <= 0 ) {
326+ LOG (fatal) << " TOFResoParamsV3 shift: time must be positive" ;
327+ }
328+ TGraph graph;
329+ for (int i = 0 ; i < nPoints; ++i) {
330+ graph.AddPoint (pars.at (Form (" TimeShift.eta%i" , i)), pars.at (Form (" TimeShift.cor%i" , i)));
331+ }
332+ setTimeShiftParameters (&graph, positive);
333+ }
334+ void setTimeShiftParameters (std::string const & filename, std::string const & objname, bool positive)
335+ {
336+ TFile f (filename.c_str (), " READ" );
337+ if (f.IsOpen ()) {
338+ if (positive) {
339+ f.GetObject (objname.c_str (), gPosEtaTimeCorr );
340+ } else {
341+ f.GetObject (objname.c_str (), gNegEtaTimeCorr );
342+ }
343+ f.Close ();
344+ }
345+ LOG (info) << " Set the Time Shift parameters from file " << filename << " and object " << objname << " for " << (positive ? " positive" : " negative" );
346+ }
347+ void setTimeShiftParameters (TGraph* g, bool positive)
348+ {
349+ if (positive) {
350+ gPosEtaTimeCorr = g;
351+ } else {
352+ gNegEtaTimeCorr = g;
353+ }
354+ LOG (info) << " Set the Time Shift parameters from object " << g->GetName () << " " << g->GetTitle () << " for " << (positive ? " positive" : " negative" );
355+ }
356+ float getTimeShift (float eta, int16_t sign) const
357+ {
358+ if (sign > 0 ) {
359+ if (!gPosEtaTimeCorr ) {
360+ return 0 .f ;
361+ }
362+ return gPosEtaTimeCorr ->Eval (eta);
363+ }
364+ if (!gNegEtaTimeCorr ) {
365+ return 0 .f ;
366+ }
367+ return gNegEtaTimeCorr ->Eval (eta);
368+ }
369+
370+ private:
371+ // Charge calibration
372+ int mEtaN = 0 ; // Number of eta bins, 0 means no correction
373+ float mEtaStart = 0 .f;
374+ float mEtaStop = 0 .f;
375+ float mInvEtaWidth = 9999 .f;
376+ std::vector<float > mContent ;
377+
378+ // Time shift for post calibration
379+ TGraph* gPosEtaTimeCorr = nullptr ; // / Time shift correction for positive tracks
380+ TGraph* gNegEtaTimeCorr = nullptr ; // / Time shift correction for negative tracks
381+ };
382+
253383// / \brief Class to handle the the TOF detector response for the expected time
254384template <typename TrackType, o2::track::PID ::ID id>
255385class ExpTimes
@@ -279,16 +409,17 @@ class ExpTimes
279409 // / Gets the expected signal of the track of interest under the PID assumption corrected for shifts in expected momentum
280410 // / \param parameters Parameters to correct for the momentum shift
281411 // / \param track Track of interest
282- static float GetCorrectedExpectedSignal (const TOFResoParamsV2& parameters, const TrackType& track)
412+ template <typename ParamType>
413+ static float GetCorrectedExpectedSignal (const ParamType& parameters, const TrackType& track)
283414 {
284415 if (!track.hasTOF ()) {
285416 return defaultReturnValue;
286417 }
287418 if (track.trackType () == o2::aod::track::Run2Track) {
288- return ComputeExpectedTime (track.tofExpMom () * kCSPEDDInv / (1 .f + track.sign () * parameters.getShift (track.eta ())), track.length ());
419+ return ComputeExpectedTime (track.tofExpMom () * kCSPEDDInv / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ())), track.length ());
289420 }
290- LOG (debug) << " TOF exp. mom. " << track.tofExpMom () << " shifted = " << track.tofExpMom () / (1 .f + track.sign () * parameters.getShift (track.eta ()));
291- return ComputeExpectedTime (track.tofExpMom () / (1 .f + track.sign () * parameters.getShift (track.eta ())), track.length ()) + parameters.getTimeShift (track.eta (), track.sign ());
421+ LOG (debug) << " TOF exp. mom. " << track.tofExpMom () << " shifted = " << track.tofExpMom () / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ()));
422+ return ComputeExpectedTime (track.tofExpMom () / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ())), track.length ()) + parameters.getTimeShift (track.eta (), track.sign ());
292423 }
293424
294425 // / Gets the expected resolution of the t-texp-t0
@@ -297,7 +428,8 @@ class ExpTimes
297428 // / \param track Track of interest
298429 // / \param tofSignal TOF signal of the track of interest
299430 // / \param collisionTimeRes Collision time resolution of the track of interest
300- static float GetExpectedSigma (const TOFResoParamsV2& parameters, const TrackType& track, const float tofSignal, const float collisionTimeRes)
431+ template <typename ParamType>
432+ static float GetExpectedSigma (const ParamType& parameters, const TrackType& track, const float tofSignal, const float collisionTimeRes)
301433 {
302434 const float & mom = track.p ();
303435 if (mom <= 0 ) {
@@ -323,29 +455,49 @@ class ExpTimes
323455 // / Gets the expected resolution of the t-texp-t0
324456 // / \param parameters Detector response parameters
325457 // / \param track Track of interest
326- static float GetExpectedSigma (const TOFResoParamsV2& parameters, const TrackType& track) { return GetExpectedSigma (parameters, track, track.tofSignal (), track.tofEvTimeErr ()); }
458+ template <typename ParamType>
459+ static float GetExpectedSigma (const ParamType& parameters, const TrackType& track)
460+ {
461+ return GetExpectedSigma (parameters, track, track.tofSignal (), track.tofEvTimeErr ());
462+ }
327463
328464 // / Gets the expected resolution of the time measurement, uses the expected time and no event time resolution
329465 // / \param parameters Parameters to use to compute the expected resolution
330466 // / \param track Track of interest
331- static float GetExpectedSigmaTracking (const TOFResoParamsV2& parameters, const TrackType& track) { return GetExpectedSigma (parameters, track, GetCorrectedExpectedSignal (parameters, track), 0 .f ); }
467+ template <typename ParamType>
468+ static float GetExpectedSigmaTracking (const ParamType& parameters, const TrackType& track)
469+ {
470+ return GetExpectedSigma (parameters, track, GetCorrectedExpectedSignal (parameters, track), 0 .f );
471+ }
332472
333473 // / Gets the number of sigmas with respect the expected time
334474 // / \param parameters Detector response parameters
335475 // / \param track Track of interest
336476 // / \param collisionTime Collision time
337477 // / \param collisionTimeRes Collision time resolution of the track of interest
338- static float GetSeparation (const TOFResoParamsV2& parameters, const TrackType& track, const float collisionTime, const float resolution) { return track.hasTOF () ? (track.tofSignal () - collisionTime - GetCorrectedExpectedSignal (parameters, track)) / resolution : defaultReturnValue; }
478+ template <typename ParamType>
479+ static float GetSeparation (const ParamType& parameters, const TrackType& track, const float collisionTime, const float resolution)
480+ {
481+ return track.hasTOF () ? (track.tofSignal () - collisionTime - GetCorrectedExpectedSignal (parameters, track)) / resolution : defaultReturnValue;
482+ }
339483
340484 // / Gets the number of sigmas with respect the expected time
341485 // / \param parameters Detector response parameters
342486 // / \param track Track of interest
343- static float GetSeparation (const TOFResoParamsV2& parameters, const TrackType& track, const float resolution) { return GetSeparation (parameters, track, track.tofEvTime (), resolution); }
487+ template <typename ParamType>
488+ static float GetSeparation (const ParamType& parameters, const TrackType& track, const float resolution)
489+ {
490+ return GetSeparation (parameters, track, track.tofEvTime (), resolution);
491+ }
344492
345493 // / Gets the number of sigmas with respect the expected time
346494 // / \param parameters Detector response parameters
347495 // / \param track Track of interest
348- static float GetSeparation (const TOFResoParamsV2& parameters, const TrackType& track) { return GetSeparation (parameters, track, track.tofEvTime (), GetExpectedSigma (parameters, track)); }
496+ template <typename ParamType>
497+ static float GetSeparation (const ParamType& parameters, const TrackType& track)
498+ {
499+ return GetSeparation (parameters, track, track.tofEvTime (), GetExpectedSigma (parameters, track));
500+ }
349501};
350502
351503// / \brief Class to convert the trackTime to the tofSignal used for PID
0 commit comments