@@ -201,6 +201,154 @@ class TOFResoParamsV2 : public o2::tof::Parameters<13>
201201 printMomentumChargeShiftParameters ();
202202 }
203203
204+ // Time shift for post calibration
205+ void setTimeShiftParameters (std::unordered_map<std::string, float > const & pars, bool positive)
206+ {
207+ std::string baseOpt = positive ? " TimeShift.Pos." : " TimeShift.Neg." ;
208+
209+ 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
210+ return ;
211+ }
212+ const int nPoints = static_cast <int >(pars.at (baseOpt + " GetN" ));
213+ if (nPoints <= 0 ) {
214+ LOG (fatal) << " TOFResoParamsV2 shift: time must be positive" ;
215+ }
216+ TGraph graph;
217+ for (int i = 0 ; i < nPoints; ++i) {
218+ graph.AddPoint (pars.at (Form (" TimeShift.eta%i" , i)), pars.at (Form (" TimeShift.cor%i" , i)));
219+ }
220+ setTimeShiftParameters (&graph, positive);
221+ }
222+ void setTimeShiftParameters (std::string const & filename, std::string const & objname, bool positive)
223+ {
224+ TFile f (filename.c_str (), " READ" );
225+ if (f.IsOpen ()) {
226+ if (positive) {
227+ f.GetObject (objname.c_str (), gPosEtaTimeCorr );
228+ } else {
229+ f.GetObject (objname.c_str (), gNegEtaTimeCorr );
230+ }
231+ f.Close ();
232+ }
233+ LOG (info) << " Set the Time Shift parameters from file " << filename << " and object " << objname << " for " << (positive ? " positive" : " negative" );
234+ }
235+ void setTimeShiftParameters (TGraph* g, bool positive)
236+ {
237+ if (positive) {
238+ gPosEtaTimeCorr = g;
239+ } else {
240+ gNegEtaTimeCorr = g;
241+ }
242+ LOG (info) << " Set the Time Shift parameters from object " << g->GetName () << " " << g->GetTitle () << " for " << (positive ? " positive" : " negative" );
243+ }
244+ float getTimeShift (float eta, int16_t sign) const
245+ {
246+ if (sign > 0 ) {
247+ if (!gPosEtaTimeCorr ) {
248+ return 0 .f ;
249+ }
250+ return gPosEtaTimeCorr ->Eval (eta);
251+ }
252+ if (!gNegEtaTimeCorr ) {
253+ return 0 .f ;
254+ }
255+ return gNegEtaTimeCorr ->Eval (eta);
256+ }
257+
258+ private:
259+ // Charge calibration
260+ int mEtaN = 0 ; // Number of eta bins, 0 means no correction
261+ float mEtaStart = 0 .f;
262+ float mEtaStop = 0 .f;
263+ float mInvEtaWidth = 9999 .f;
264+ std::vector<float > mContent ;
265+
266+ // Time shift for post calibration
267+ TGraph* gPosEtaTimeCorr = nullptr ; // / Time shift correction for positive tracks
268+ TGraph* gNegEtaTimeCorr = nullptr ; // / Time shift correction for negative tracks
269+ };
270+
271+ // / \brief Next implementation class to store TOF response parameters for exp. times
272+ class TOFResoParamsV3 : public o2 ::tof::Parameters<13 >
273+ {
274+ public:
275+ TOFResoParamsV3 () : Parameters(std::array<std::string, 13 >{" TrkRes.Pi.P0" , " TrkRes.Pi.P1" , " TrkRes.Pi.P2" , " TrkRes.Pi.P3" , " time_resolution" ,
276+ " TrkRes.Ka.P0" , " TrkRes.Ka.P1" , " TrkRes.Ka.P2" , " TrkRes.Ka.P3" ,
277+ " TrkRes.Pr.P0" , " TrkRes.Pr.P1" , " TrkRes.Pr.P2" , " TrkRes.Pr.P3" },
278+ " TOFResoParamsV3" )
279+ {
280+ setParameters (std::array<float , 13 >{0.008 , 0.008 , 0.002 , 40.0 , 60.0 ,
281+ 0.008 , 0.008 , 0.002 , 40.0 ,
282+ 0.008 , 0.008 , 0.002 , 40.0 });
283+ } // Default constructor with default parameters
284+
285+ ~TOFResoParamsV3 () = default ;
286+
287+ // Momentum shift for charge calibration
288+ void setMomentumChargeShiftParameters (std::unordered_map<std::string, float > const & pars)
289+ {
290+ 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
291+ mEtaN = 0 ;
292+ return ;
293+ }
294+ mEtaN = static_cast <int >(pars.at (" Shift.etaN" ));
295+ if (mEtaN <= 0 ) {
296+ LOG (fatal) << " TOFResoParamsV3 shift: etaN must be positive" ;
297+ }
298+ mEtaStart = pars.at (" Shift.etaStart" );
299+ mEtaStop = pars.at (" Shift.etaStop" );
300+ if (mEtaStart >= mEtaStop ) {
301+ LOG (fatal) << " TOFResoParamsV3 shift: etaStart must be smaller than etaStop" ;
302+ }
303+ mInvEtaWidth = 1 .f / ((mEtaStop - mEtaStart ) / mEtaN );
304+ mContent .clear ();
305+ mContent .resize (mEtaN );
306+ for (int i = 0 ; i < mEtaN ; ++i) {
307+ mContent [i] = pars.at (Form (" Shift.etaC%i" , i));
308+ }
309+ }
310+
311+ float getMomentumChargeShift (float eta) const
312+ {
313+ if (mEtaN == 0 ) { // No correction
314+ // LOG(info) << "TOFResoParamsV3 shift: no correction mEtaN is " << mEtaN;
315+ return 0 .f ;
316+ }
317+ const int & etaIndex = (eta <= mEtaStart ) ? 0 : (eta >= mEtaStop ? (mEtaN - 1 ) : (eta - mEtaStart ) * mInvEtaWidth );
318+ // LOG(info) << "TOFResoParamsV3 shift: correction for eta " << eta << " is for index " << etaIndex << " = " << shift;
319+ return mContent .at (etaIndex);
320+ }
321+
322+ void printMomentumChargeShiftParameters () const
323+ {
324+ LOG (info) << " TOF momentum shift parameters" ;
325+ LOG (info) << " etaN: " << mEtaN ;
326+ LOG (info) << " etaStart: " << mEtaStart ;
327+ LOG (info) << " etaStop: " << mEtaStop ;
328+ LOG (info) << " content size " << mContent .size ();
329+ for (int i = 0 ; i < mEtaN ; ++i) {
330+ LOG (info) << " etaC" << i << " : " << mContent [i];
331+ }
332+ }
333+
334+ // Time shift for post calibration
335+ void setTimeShiftParameters (std::unordered_map<std::string, float > const & pars, bool positive)
336+ {
337+ std::string baseOpt = positive ? " TimeShift.Pos." : " TimeShift.Neg." ;
338+
339+ 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
340+ return ;
341+ }
342+ const int nPoints = static_cast <int >(pars.at (baseOpt + " GetN" ));
343+ if (nPoints <= 0 ) {
344+ LOG (fatal) << " TOFResoParamsV3 shift: time must be positive" ;
345+ }
346+ TGraph graph;
347+ for (int i = 0 ; i < nPoints; ++i) {
348+ graph.AddPoint (pars.at (Form (" TimeShift.eta%i" , i)), pars.at (Form (" TimeShift.cor%i" , i)));
349+ }
350+ setTimeShiftParameters (&graph, positive);
351+ }
204352 void setTimeShiftParameters (std::string const & filename, std::string const & objname, bool positive)
205353 {
206354 TFile f (filename.c_str (), " READ" );
@@ -291,6 +439,21 @@ class ExpTimes
291439 return ComputeExpectedTime (track.tofExpMom () / (1 .f + track.sign () * parameters.getShift (track.eta ())), track.length ()) + parameters.getTimeShift (track.eta (), track.sign ());
292440 }
293441
442+ // / Gets the expected signal of the track of interest under the PID assumption corrected for shifts in expected momentum
443+ // / \param parameters Parameters to correct for the momentum shift
444+ // / \param track Track of interest
445+ static float GetCorrectedExpectedSignal (const TOFResoParamsV3& parameters, const TrackType& track)
446+ {
447+ if (!track.hasTOF ()) {
448+ return defaultReturnValue;
449+ }
450+ if (track.trackType () == o2::aod::track::Run2Track) {
451+ return ComputeExpectedTime (track.tofExpMom () * kCSPEDDInv / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ())), track.length ());
452+ }
453+ LOG (debug) << " TOF exp. mom. " << track.tofExpMom () << " shifted = " << track.tofExpMom () / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ()));
454+ return ComputeExpectedTime (track.tofExpMom () / (1 .f + track.sign () * parameters.getMomentumChargeShift (track.eta ())), track.length ()) + parameters.getTimeShift (track.eta (), track.sign ());
455+ }
456+
294457 // / Gets the expected resolution of the t-texp-t0
295458 // / Given a TOF signal and collision time resolutions
296459 // / \param parameters Detector response parameters
0 commit comments