1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // TOF tender: - load updated calibrations (for TOF and T0)
20 // - set tofHeader if missing in ESDs (2010 data)
23 // Contacts: Pietro.Antonioli@bo.infn.it //
24 // Francesco.Noferini@bo.infn.it //
25 ///////////////////////////////////////////////////////////////////////////////
29 #include <AliESDEvent.h>
30 #include <AliESDtrack.h>
31 #include <AliESDInputHandler.h>
32 #include <AliAnalysisManager.h>
33 #include <AliESDpid.h>
34 #include <AliTender.h>
36 #include <AliTOFcalib.h>
37 #include <AliTOFT0maker.h>
39 #include <AliCDBManager.h>
40 #include <AliCDBEntry.h>
41 #include <AliT0CalibSeasonTimeShift.h>
43 #include "AliTOFTenderSupply.h"
45 ClassImp(AliTOFTenderSupply)
47 Float_t AliTOFTenderSupply::fgT0Aresolution = 75.;
48 Float_t AliTOFTenderSupply::fgT0Cresolution = 65.;
50 AliTOFTenderSupply::AliTOFTenderSupply() :
54 fTimeZeroType(AliESDpid::kBest_T0),
55 fCorrectExpTimes(kTRUE),
57 fT0DetectorAdjust(kFALSE),
59 fAutomaticSettings(kTRUE),
63 fT0IntercalibrationShift(0)
76 //_____________________________________________________
77 AliTOFTenderSupply::AliTOFTenderSupply(const char *name, const AliTender *tender) :
78 AliTenderSupply(name,tender),
81 fTimeZeroType(AliESDpid::kBest_T0),
82 fCorrectExpTimes(kTRUE),
84 fT0DetectorAdjust(kFALSE),
86 fAutomaticSettings(kTRUE),
90 fT0IntercalibrationShift(0)
103 //_____________________________________________________
104 void AliTOFTenderSupply::Init()
107 Bool_t tenderUnsupported = kFALSE;
108 // Initialise TOF tender (this is called at each detected run change)
109 AliLog::SetClassDebugLevel("AliTOFTenderSupply",10);
111 // Setup PID object, check for MC, set AliTOFcalib and TOFT0 maker conf
112 Int_t run = fTender->GetRun();
113 if (run == 0) return; // to skip first init, when we don't have yet a run number
115 if (fAutomaticSettings) {
117 tenderUnsupported = kTRUE;
119 else if (run>=114737&&run<=117223) { //period="LHC10B";
120 fCorrectExpTimes=kTRUE;
123 fTimeZeroType=AliESDpid::kTOF_T0;
124 fT0IntercalibrationShift = 0;
125 fT0DetectorAdjust=kTRUE;
127 else if (run>=118503&&run<=121040) { //period="LHC10C";
128 fCorrectExpTimes=kTRUE;
131 fTimeZeroType=AliESDpid::kTOF_T0;
132 fT0IntercalibrationShift = 0;
133 fT0DetectorAdjust=kFALSE;
135 else if (run>=122195&&run<=126437) { //period="LHC10D";
136 fCorrectExpTimes=kFALSE;
139 fTimeZeroType=AliESDpid::kBest_T0;
140 fT0IntercalibrationShift = 0;
141 fT0DetectorAdjust=kTRUE;
143 else if (run>=127719&&run<=130850) { //period="LHC10E";
144 fCorrectExpTimes=kFALSE;
147 fTimeZeroType=AliESDpid::kBest_T0;
148 fT0IntercalibrationShift = 30.;
149 fT0DetectorAdjust=kTRUE;
151 else if (run>=133004&&run<=135029) { //period="LHC10F";
152 fCorrectExpTimes=kFALSE;
155 fTimeZeroType=AliESDpid::kBest_T0;
156 fT0IntercalibrationShift = 0.;
157 fT0DetectorAdjust=kTRUE;
158 AliWarning("TOF tender not supported for LHC10F period!! Settings are just a guess!!");
160 else if (run>=135654&&run<=136377) { //period="LHC10G";
161 fCorrectExpTimes=kFALSE;
164 fTimeZeroType=AliESDpid::kBest_T0;
165 fT0IntercalibrationShift = 0.;
166 fT0DetectorAdjust=kTRUE;
167 AliWarning("TOF tender not supported for LHC10G period!! Settings are just a guess!!");
169 else if (run>=136851&&run<=139517) { //period="LHC10H" - pass2;
170 fCorrectExpTimes=kFALSE;
173 fTimeZeroType=AliESDpid::kTOF_T0;
174 fT0IntercalibrationShift = 0.;
175 fT0DetectorAdjust=kTRUE;
177 else if (run>=139699) { //period="LHC11A";
179 fCorrectExpTimes=kFALSE;
182 fTimeZeroType=AliESDpid::kBest_T0;
183 fT0IntercalibrationShift = 0.;
184 fT0DetectorAdjust=kFALSE;
185 AliWarning("TOF tender not supported for LHC11A period!! Settings are just a guess!!");
187 AliError("TOF tender not supported for 2011 data!!!!!");
188 tenderUnsupported = kTRUE;
192 if (tenderUnsupported) {
193 AliInfo(" |---------------------------------------------------------------------------|");
195 AliInfo(Form(" | TOF tender is not supported for run %d |",run));
196 AliInfo(" | You cannot use TOF tender for this run, your results can be spoiled |");
197 AliInfo(" | Check TOF tender usage for run/periods at: |");
198 AliInfo(" | https://twiki.cern.ch/twiki/bin/view/ALICE/TOF. |");
199 AliInfo(" |---------------------------------------------------------------------------|");
201 AliFatal(" ------- TOF tender not to be used in this run, issuing FATAL error -------- ");
204 // Check if another detector already created the esd pid object
205 // if not we create it and set it to the ESD input handler
206 fESDpid=fTender->GetESDhandler()->GetESDpid();
208 fESDpid=new AliESDpid;
209 fTender->GetESDhandler()->SetESDpid(fESDpid);
212 // Even if the user didn't set fIsMC, we force it on if we find the MC handler
213 AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
214 if (mgr->GetMCtruthEventHandler() && !(fIsMC) ) {
215 AliWarning("This ESD is MC, fIsMC found OFF: fIsMC turned ON");
219 // Configure TOF calibration class
220 if (!fTOFCalib)fTOFCalib=new AliTOFcalib(); // create if needed
221 fTOFCalib->SetRemoveMeanT0(!(fIsMC)); // must be kFALSE on MC (default is kTRUE)
222 fTOFCalib->SetCalibrateTOFsignal(!(fIsMC)); // must be kFALSE on MC (no new calibration) (default is kTRUE)
223 fTOFCalib->SetCorrectTExp(fCorrectExpTimes); // apply a fine tuning on the expected times at low momenta
226 // Configure TOFT0 maker class
227 // if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid,fTOFCalib); // create if needed
228 if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid); // without passing AliTOFCalib it uses the diamond
229 fTOFT0maker->SetTimeResolution(fTOFres); // set TOF resolution for the PID
232 AliInfo("|******************************************************|");
233 AliInfo(Form("| Alice TOF Tender Initialisation (Run %d) |",fTender->GetRun()));
234 AliInfo("| Settings: |");
235 AliInfo(Form("| Correct Exp Times : %d |",fCorrectExpTimes));
236 AliInfo(Form("| LHC10d patch : %d |",fLHC10dPatch));
237 AliInfo(Form("| TOF resolution for TOFT0 maker : %5.2f (ps) |",fTOFres));
238 AliInfo(Form("| timeZero selection : %d |",fTimeZeroType));
239 AliInfo(Form("| MC flag : %d |",fIsMC));
240 AliInfo(Form("| T0 detector offsets applied : %d |",fT0DetectorAdjust));
241 AliInfo(Form("| TOF/T0 intecalibration shift : %5.2f (ps) |",fT0IntercalibrationShift));
242 AliInfo("|******************************************************|");
247 //_____________________________________________________
248 void AliTOFTenderSupply::ProcessEvent()
251 // Use updated calibrations for TOF and T0, reapply PID information
252 // For MC: timeZero sampling and additional smearing for T0
254 if (fDebugLevel > 1) AliInfo("process event");
256 AliESDEvent *event=fTender->GetEvent();
258 if (fDebugLevel > 1) AliInfo("event read");
262 if (fTender->RunChanged()){
266 fTOFCalib->Init(fTender->GetRun());
268 if(event->GetT0TOF()){ // read T0 detector correction from OCDB
270 if (fT0DetectorAdjust) {
271 AliCDBManager* ocdbMan = AliCDBManager::Instance();
272 ocdbMan->SetRun(fTender->GetRun());
273 AliCDBEntry *entry = ocdbMan->Get("T0/Calib/TimeAdjust/");
275 AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*) entry->GetObject();
276 Float_t *t0means= clb->GetT0Means();
277 // Float_t *t0sigmas = clb->GetT0Sigmas();
278 fT0shift[0] = t0means[0] + fT0IntercalibrationShift;
279 fT0shift[1] = t0means[1] + fT0IntercalibrationShift;
280 fT0shift[2] = t0means[2] + fT0IntercalibrationShift;
281 fT0shift[3] = t0means[3] + fT0IntercalibrationShift;
283 for (Int_t i=0;i<4;i++) fT0shift[i]=0;
284 AliWarning("TofTender no T0 entry found T0shift set to 0");
287 for (Int_t i=0;i<4;i++) fT0shift[i]=0;
293 fTOFCalib->CalibrateESD(event); //recalculate TOF signal (no harm for MC, see settings inside init)
294 if (fLHC10dPatch && !(fIsMC)) RecomputeTExp(event);
296 Double_t startTime = 0.;
297 if(fIsMC) startTime = fTOFCalib->TuneForMC(event,fTOFres);
299 if (fDebugLevel > 1) Printf(" TofTender: startTime %f",startTime);
300 if (fDebugLevel > 1) Printf(" TofTender: T0 time (orig) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
301 // event by event TO detector treatment
302 if(event->GetT0TOF()){ // protection: we adjust T0 only if it is there....
304 if (event->GetT0TOF(0) == 0) event->SetT0TOF(0, 9999999.); // in case no information we set to unknown
305 if (event->GetT0TOF(1) == 0) event->SetT0TOF(1, 99999.);
306 if (event->GetT0TOF(2) == 0) event->SetT0TOF(2, 99999.);
308 if(!fIsMC){ // data: apply shifts to align around Zero
309 event->SetT0TOF(0,event->GetT0TOF(0) - fT0shift[0]);
310 event->SetT0TOF(1,event->GetT0TOF(1) - fT0shift[1]);
311 event->SetT0TOF(2,event->GetT0TOF(2) - fT0shift[2]);
313 // MC: add smearing for realistic T0A and T0C resolution
314 Double_t defResolutionT0A = 33.; // in future we will get this from ESDrun data structure or via OCDB
315 Double_t defResolutionT0C = 30.; // for the moment we don't trust them
316 if ( (fgT0Aresolution > defResolutionT0A) && (event->GetT0TOF(1)<90000.) ) { // add smearing only if signal is there
317 Double_t addedSmearingT0A = TMath::Sqrt(fgT0Aresolution*fgT0Aresolution - defResolutionT0A*defResolutionT0A);
318 Double_t smearingT0A = gRandom->Gaus(0.,addedSmearingT0A);
319 event->SetT0TOF(1,event->GetT0TOF(1) + smearingT0A);
321 if ( (fgT0Cresolution > defResolutionT0C) && (event->GetT0TOF(2)<90000.) ) { // add smearing only if signal is there
322 Double_t addedSmearingT0C = TMath::Sqrt(fgT0Cresolution*fgT0Cresolution - defResolutionT0C*defResolutionT0C);
323 Double_t smearingT0C = gRandom->Gaus(0.,addedSmearingT0C);
324 event->SetT0TOF(2,event->GetT0TOF(2) + smearingT0C);
326 if (event->GetT0TOF(0)<90000.) { // we recompute the AND only if it is already there...
327 Double_t smearedT0AC = (event->GetT0TOF(1)+event->GetT0TOF(2))/2.;
328 event->SetT0TOF(0,smearedT0AC);
330 if (fDebugLevel > 1) Printf(" TofTender: T0 time (postSmear) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
331 // add finally the timeZero offset also to the T0 detector information
332 event->SetT0TOF(0,event->GetT0TOF(0) + startTime);
333 event->SetT0TOF(1,event->GetT0TOF(1) + startTime);
334 event->SetT0TOF(2,event->GetT0TOF(2) + startTime);
335 if (fDebugLevel > 1) Printf(" TofTender: T0 time (postStart) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
337 // after shifts adjust (data) or smearing+offset (MC) we 'clean' to default if signals not there
338 if(event->GetT0TOF(0) > 900000) event->SetT0TOF(0, 999999.);
339 if(event->GetT0TOF(1) > 90000) event->SetT0TOF(1, 99999.);
340 if(event->GetT0TOF(2) > 90000) event->SetT0TOF(2, 99999.);
342 if (fDebugLevel > 1) Printf(" TofTender: T0 time (FINAL) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
344 //compute timeZero of the event via TOF-TO
345 fTOFT0maker->ComputeT0TOF(event);
346 fTOFT0maker->WriteInESD(event);
348 // recalculate PID probabilities
349 fESDpid->SetTOFResponse(event, (AliESDpid::EStartTimeType_t)fTimeZeroType);
351 // this is for safety, especially if the user doesn't attach a PID tender after TOF tender
352 Int_t ntracks=event->GetNumberOfTracks();
353 for(Int_t itrack = 0; itrack < ntracks; itrack++){
354 fESDpid->MakeTOFPID(event->GetTrack(itrack),0);
361 //_____________________________________________________
362 void AliTOFTenderSupply::RecomputeTExp(AliESDEvent *event) const
369 /* loop over tracks */
370 AliESDtrack *track = NULL;
371 for (Int_t itrk = 0; itrk < event->GetNumberOfTracks(); itrk++) {
372 /* get track and calibrate */
373 track = event->GetTrack(itrk);
374 RecomputeTExp(track);
379 //_____________________________________________________
380 void AliTOFTenderSupply::RecomputeTExp(AliESDtrack *track) const
383 THIS METHOD IS BASED ON THEORETICAL EXPECTED TIME COMPUTED
384 USING AVERAGE MOMENTUM BETWEEN INNER/OUTER TRACK PARAMS
385 IT IS A ROUGH APPROXIMATION APPLIED TO FIX LHC10d-pass2 DATA
386 WHERE A WRONG GEOMETRY (FULL TRD) WAS INSERTED
389 Double_t texp[AliPID::kSPECIES];
390 if (!track || !(track->GetStatus() & AliESDtrack::kTOFout)) return;
393 /* get track params */
394 Float_t l = track->GetIntegratedLength();
395 Float_t p = track->P();
396 if (track->GetInnerParam() && track->GetOuterParam()) {
397 Float_t pin = track->GetInnerParam()->P();
398 Float_t pout = track->GetOuterParam()->P();
399 p = 0.5 * (pin + pout);
401 /* loop over particle types and compute expected time */
402 for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
403 texp[ipart] = GetExpTimeTh(AliPID::ParticleMass(ipart), p, l) - 37.;
404 // 37 is a final semiempirical offset to further adjust (calibrations were
405 // done with "standard" integratedTimes)
406 /* set integrated times */
407 track->SetIntegratedTimes(texp);