o updates (Pietro)
[u/mrichter/AliRoot.git] / ANALYSIS / TenderSupplies / AliTOFTenderSupply.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 // TOF tender: - load updated calibrations (for TOF and T0)
20 //             - set tofHeader if missing in ESDs (2010 data)
21 //             - re-apply PID 
22 //             
23 // Contacts: Pietro.Antonioli@bo.infn.it                                     //
24 //           Francesco.Noferini@bo.infn.it                                   //
25 ///////////////////////////////////////////////////////////////////////////////
26 #include <TMath.h>
27 #include <TRandom.h>
28 #include <AliLog.h>
29 #include <AliESDEvent.h>
30 #include <AliESDtrack.h>
31 #include <AliESDInputHandler.h>
32 #include <AliAnalysisManager.h>
33 #include <AliESDpid.h>
34 #include <AliTender.h>
35
36 #include <AliTOFcalib.h>
37 #include <AliTOFT0maker.h>
38
39 #include <AliCDBManager.h>
40 #include <AliCDBEntry.h>
41 #include <AliT0CalibSeasonTimeShift.h>
42
43 #include "AliTOFTenderSupply.h"
44
45 ClassImp(AliTOFTenderSupply)
46
47 Float_t AliTOFTenderSupply::fgT0Aresolution = 75.;
48 Float_t AliTOFTenderSupply::fgT0Cresolution = 65.;
49
50 AliTOFTenderSupply::AliTOFTenderSupply() :
51   AliTenderSupply(),
52   fESDpid(0x0),
53   fIsMC(kFALSE),
54   fTimeZeroType(AliESDpid::kBest_T0),
55   fCorrectExpTimes(kTRUE),
56   fLHC10dPatch(kFALSE),
57   fDebugLevel(0),
58   fAutomaticSettings(kTRUE),
59   fTOFCalib(0x0),
60   fTOFT0maker(0x0),
61   fTOFres(100.),
62   fT0IntercalibrationShift(0)
63
64
65 {
66   //
67   // default ctor
68   //
69   fT0shift[0] = 0;
70   fT0shift[1] = 0;
71   fT0shift[2] = 0;
72   fT0shift[3] = 0;
73 }
74
75 //_____________________________________________________
76 AliTOFTenderSupply::AliTOFTenderSupply(const char *name, const AliTender *tender) :
77   AliTenderSupply(name,tender),
78   fESDpid(0x0),
79   fIsMC(kFALSE),
80   fTimeZeroType(AliESDpid::kBest_T0),
81   fCorrectExpTimes(kTRUE),
82   fLHC10dPatch(kFALSE),
83   fDebugLevel(0),
84   fAutomaticSettings(kTRUE),
85   fTOFCalib(0x0),
86   fTOFT0maker(0x0),
87   fTOFres(100.),
88   fT0IntercalibrationShift(0)
89  
90 {
91   //
92   // named ctor
93   //
94
95   fT0shift[0] = 0;
96   fT0shift[1] = 0;
97   fT0shift[2] = 0;
98   fT0shift[3] = 0;
99 }
100
101 //_____________________________________________________
102 void AliTOFTenderSupply::Init()
103 {
104
105   
106   // Initialise TOF tender (this is called at each detected run change)
107   AliLog::SetClassDebugLevel("AliTOFTenderSupply",10); 
108
109   // Setup PID object, check for MC, set AliTOFcalib and TOFT0 maker conf
110   Int_t run = fTender->GetRun();
111   if (run == 0) return;                // to skip first init, when we don't have yet a run number
112
113   if (fAutomaticSettings) {
114     if (run>=114737&&run<=117223) {      //period="LHC10B";
115       fCorrectExpTimes=kTRUE;
116       fLHC10dPatch=kFALSE;
117       fTOFres=100.;
118       fTimeZeroType=AliESDpid::kTOF_T0;
119       fT0IntercalibrationShift = 0;
120     }
121     else if (run>=118503&&run<=121040) { //period="LHC10C";
122       fCorrectExpTimes=kTRUE;
123       fLHC10dPatch=kFALSE;
124       fTOFres=100.;
125       fTimeZeroType=AliESDpid::kTOF_T0;
126       fT0IntercalibrationShift = 0;
127     }
128     else if (run>=122195&&run<=126437) { //period="LHC10D";
129       fCorrectExpTimes=kFALSE;
130       fLHC10dPatch=kTRUE;
131       fTOFres=100.;
132       fTimeZeroType=AliESDpid::kBest_T0;
133       fT0IntercalibrationShift = 0;
134     }
135     else if (run>=127719&&run<=130850) { //period="LHC10E";
136       fCorrectExpTimes=kFALSE;
137       fLHC10dPatch=kFALSE;
138       fTOFres=100.;
139       fTimeZeroType=AliESDpid::kBest_T0;
140       fT0IntercalibrationShift = 30.;
141     }
142     else if (run>=133004&&run<=135029) { //period="LHC10F";
143       fCorrectExpTimes=kFALSE;
144       fLHC10dPatch=kFALSE;
145       fTOFres=100.;
146       fTimeZeroType=AliESDpid::kBest_T0;
147       fT0IntercalibrationShift = 0.;
148       AliWarning("TOF tender not supported for LHC10F period!! Settings are just a guess!!");
149     }
150     else if (run>=135654&&run<=136377) { //period="LHC10G";
151       fCorrectExpTimes=kFALSE;
152       fLHC10dPatch=kFALSE;
153       fTOFres=100.;
154       fTimeZeroType=AliESDpid::kBest_T0;
155       fT0IntercalibrationShift = 0.;
156       AliWarning("TOF tender not supported for LHC10G period!! Settings are just a guess!!");
157     }
158     else if (run>=136851&&run<=139517) { //period="LHC10H" - pass2;
159       fCorrectExpTimes=kFALSE;
160       fLHC10dPatch=kFALSE;                
161       fTOFres=90.;
162       fTimeZeroType=AliESDpid::kTOF_T0;
163       fT0IntercalibrationShift = 0.;
164     }
165     else if (run>=139699) {              //period="LHC11A";
166       fCorrectExpTimes=kFALSE;
167       fLHC10dPatch=kFALSE;
168       fTOFres=100.;
169       fTimeZeroType=AliESDpid::kBest_T0;
170       fT0IntercalibrationShift = 0.;
171       AliWarning("TOF tender not supported for LHC11A period!! Settings are just a guess!!");
172     }
173   }
174
175   // Check if another detector already created the esd pid object
176   // if not we create it and set it to the ESD input handler
177   fESDpid=fTender->GetESDhandler()->GetESDpid();
178   if (!fESDpid) {
179     fESDpid=new AliESDpid;
180     fTender->GetESDhandler()->SetESDpid(fESDpid);
181   }
182
183   // Even if the user didn't set fIsMC, we force it on if we find the MC handler 
184   AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
185   if (mgr->GetMCtruthEventHandler() && !(fIsMC) ) {
186     AliWarning("This ESD is MC, fIsMC found OFF: fIsMC turned ON");
187     fIsMC=kTRUE;
188   }
189
190   // Configure TOF calibration class
191   if (!fTOFCalib)fTOFCalib=new AliTOFcalib();  // create if needed
192   fTOFCalib->SetRemoveMeanT0(!(fIsMC));        // must be kFALSE on MC (default is kTRUE)
193   fTOFCalib->SetCalibrateTOFsignal(!(fIsMC));  // must be kFALSE on MC (no new calibration) (default is kTRUE)
194   fTOFCalib->SetCorrectTExp(fCorrectExpTimes); // apply a fine tuning on the expected times at low momenta
195   
196
197   // Configure TOFT0 maker class
198   //  if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid,fTOFCalib); // create if needed
199   if (!fTOFT0maker) fTOFT0maker = new AliTOFT0maker(fESDpid); // without passing AliTOFCalib it uses the diamond
200   fTOFT0maker->SetTimeResolution(fTOFres);     // set TOF resolution for the PID
201   
202
203   AliInfo("|******************************************************|");
204   AliInfo(Form("|    Alice TOF Tender Initialisation (Run %d)  |",fTender->GetRun()));
205   AliInfo("|    Settings:                                         |");
206   AliInfo(Form("|    Correct Exp Times              :  %d               |",fCorrectExpTimes));
207   AliInfo(Form("|    LHC10d patch                   :  %d               |",fLHC10dPatch));
208   AliInfo(Form("|    TOF resolution for TOFT0 maker :  %5.2f (ps)     |",fTOFres));
209   AliInfo(Form("|    timeZero selection             :  %d               |",fTimeZeroType));
210   AliInfo(Form("|    MC flag                        :  %d               |",fIsMC));
211   AliInfo(Form("|    TOF/T0 intecalibration shift   :  %5.2f (ps)     |",fT0IntercalibrationShift));
212   AliInfo("|******************************************************|");
213
214
215 }
216
217 //_____________________________________________________
218 void AliTOFTenderSupply::ProcessEvent()
219 {
220   //
221   // Use updated calibrations for TOF and T0, reapply PID information
222   // For MC: timeZero sampling and additional smearing for T0
223
224   if (fDebugLevel > 1) AliInfo("process event");
225
226   AliESDEvent *event=fTender->GetEvent();
227   if (!event) return;
228   if (fDebugLevel > 1) AliInfo("event read");
229
230
231     
232   if (fTender->RunChanged()){ 
233
234     Init();            
235
236     fTOFCalib->Init(fTender->GetRun());
237     
238     if(event->GetT0TOF()){ // read T0 detector correction from OCDB
239       // OCDB instance
240       AliCDBManager* ocdbMan = AliCDBManager::Instance();
241       ocdbMan->SetRun(fTender->GetRun());    
242       AliCDBEntry *entry = ocdbMan->Get("T0/Calib/TimeAdjust/");
243       if(entry) {
244         AliT0CalibSeasonTimeShift *clb = (AliT0CalibSeasonTimeShift*) entry->GetObject();
245         Float_t *t0means= clb->GetT0Means();
246         //      Float_t *t0sigmas = clb->GetT0Sigmas();
247         fT0shift[0] = t0means[0] + fT0IntercalibrationShift;
248         fT0shift[1] = t0means[1] + fT0IntercalibrationShift;
249         fT0shift[2] = t0means[2] + fT0IntercalibrationShift;
250         fT0shift[3] = t0means[3] + fT0IntercalibrationShift;
251       } else {
252         for (Int_t i=0;i<4;i++) fT0shift[i]=0;
253         AliWarning("TofTender no T0 entry found T0shift set to 0");
254       }
255     }
256   }
257
258
259   fTOFCalib->CalibrateESD(event);   //recalculate TOF signal (no harm for MC, see settings inside init)
260   if (fLHC10dPatch && !(fIsMC)) RecomputeTExp(event);
261
262   Double_t startTime = 0.;
263   if(fIsMC) startTime = fTOFCalib->TuneForMC(event,fTOFres);
264
265   if (fDebugLevel > 1) Printf(" TofTender: startTime %f",startTime);
266   if (fDebugLevel > 1) Printf(" TofTender: T0 time (orig) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
267   // event by event TO detector treatment  
268   if(event->GetT0TOF()){   // protection: we adjust T0 only if it is there....
269
270     if (event->GetT0TOF(0) == 0) event->SetT0TOF(0, 9999999.); // in case no information we set to unknown
271     if (event->GetT0TOF(1) == 0) event->SetT0TOF(1, 99999.);
272     if (event->GetT0TOF(2) == 0) event->SetT0TOF(2, 99999.);
273
274     if(!fIsMC){   // data: apply shifts to align around Zero
275       event->SetT0TOF(0,event->GetT0TOF(0) - fT0shift[0]);
276       event->SetT0TOF(1,event->GetT0TOF(1) - fT0shift[1]);
277       event->SetT0TOF(2,event->GetT0TOF(2) - fT0shift[2]);
278     } else {
279       // MC: add smearing for realistic T0A and T0C resolution
280       Double_t defResolutionT0A = 33.;   // in future we will get this from ESDrun data structure or via OCDB
281       Double_t defResolutionT0C = 30.;   // for the moment we don't trust them
282       if ( (fgT0Aresolution > defResolutionT0A) && (event->GetT0TOF(1)<90000.) ) { // add smearing only if signal is there
283         Double_t addedSmearingT0A = TMath::Sqrt(fgT0Aresolution*fgT0Aresolution - defResolutionT0A*defResolutionT0A);
284         Double_t smearingT0A = gRandom->Gaus(0.,addedSmearingT0A);
285         event->SetT0TOF(1,event->GetT0TOF(1) + smearingT0A);
286       }
287       if ( (fgT0Cresolution > defResolutionT0C) && (event->GetT0TOF(2)<90000.) ) { // add smearing only if signal is there
288         Double_t addedSmearingT0C = TMath::Sqrt(fgT0Cresolution*fgT0Cresolution - defResolutionT0C*defResolutionT0C);
289         Double_t smearingT0C = gRandom->Gaus(0.,addedSmearingT0C);
290         event->SetT0TOF(2,event->GetT0TOF(2) + smearingT0C);
291       }
292       if (event->GetT0TOF(0)<90000.) { // we recompute the AND only if it is already there...
293         Double_t smearedT0AC = (event->GetT0TOF(1)+event->GetT0TOF(2))/2.;
294         event->SetT0TOF(0,smearedT0AC); 
295       }
296       if (fDebugLevel > 1) Printf(" TofTender: T0 time (postSmear) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
297       // add finally the timeZero offset also to the T0 detector information
298       event->SetT0TOF(0,event->GetT0TOF(0) + startTime);
299       event->SetT0TOF(1,event->GetT0TOF(1) + startTime);
300       event->SetT0TOF(2,event->GetT0TOF(2) + startTime);  
301       if (fDebugLevel > 1) Printf(" TofTender: T0 time (postStart) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
302     }
303     // after shifts adjust (data) or smearing+offset (MC) we 'clean' to default if signals not there 
304     if(event->GetT0TOF(0) > 900000) event->SetT0TOF(0, 999999.);
305     if(event->GetT0TOF(1) > 90000)  event->SetT0TOF(1, 99999.);
306     if(event->GetT0TOF(2) > 90000)  event->SetT0TOF(2, 99999.);
307   }
308   if (fDebugLevel > 1) Printf(" TofTender: T0 time (FINAL) %f %f %f",event->GetT0TOF(0),event->GetT0TOF(1),event->GetT0TOF(2));
309   
310   //compute timeZero of the event via TOF-TO
311   fTOFT0maker->ComputeT0TOF(event);
312   fTOFT0maker->WriteInESD(event);
313
314   // recalculate PID probabilities
315   fESDpid->SetTOFResponse(event, (AliESDpid::EStartTimeType_t)fTimeZeroType);
316
317   // this is for safety, especially if the user doesn't attach a PID tender after TOF tender  
318   Int_t ntracks=event->GetNumberOfTracks();
319   for(Int_t itrack = 0; itrack < ntracks; itrack++){
320     fESDpid->MakeTOFPID(event->GetTrack(itrack),0);   
321   }
322   
323   
324 }
325
326
327 //_____________________________________________________
328 void AliTOFTenderSupply::RecomputeTExp(AliESDEvent *event) const
329 {
330   /*
331    * calibrate TExp
332    */
333
334   
335   /* loop over tracks */
336   AliESDtrack *track = NULL;
337   for (Int_t itrk = 0; itrk < event->GetNumberOfTracks(); itrk++) {
338     /* get track and calibrate */
339     track = event->GetTrack(itrk);
340     RecomputeTExp(track);
341   }
342   
343 }
344
345 //_____________________________________________________
346 void AliTOFTenderSupply::RecomputeTExp(AliESDtrack *track) const
347 {
348   /*** 
349        THIS METHOD IS BASED ON THEORETICAL EXPECTED TIME COMPUTED
350        USING AVERAGE MOMENTUM BETWEEN INNER/OUTER TRACK PARAMS 
351        IT IS A ROUGH APPROXIMATION APPLIED TO FIX LHC10d-pass2 DATA
352        WHERE A WRONG GEOMETRY (FULL TRD) WAS INSERTED
353   ***/
354
355   Double_t texp[AliPID::kSPECIES];
356   if (!track || !(track->GetStatus() & AliESDtrack::kTOFout)) return;
357
358
359   /* get track params */
360   Float_t l = track->GetIntegratedLength();
361   Float_t p = track->P();
362   if (track->GetInnerParam() && track->GetOuterParam()) {
363     Float_t pin = track->GetInnerParam()->P();
364     Float_t pout = track->GetOuterParam()->P();
365     p = 0.5 * (pin + pout);
366   }
367   /* loop over particle types and compute expected time */
368   for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
369     texp[ipart] = GetExpTimeTh(AliPID::ParticleMass(ipart), p, l) - 37.; 
370   // 37 is a final semiempirical offset to further adjust (calibrations were
371   // done with "standard" integratedTimes)
372   /* set integrated times */
373   track->SetIntegratedTimes(texp);
374
375 }
376
377