]>
Commit | Line | Data |
---|---|---|
b0d2c2d3 | 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 | /* $Id$ */ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | /// // | |
20 | /// class for VZERO reconstruction // | |
21 | /// // | |
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | ||
b44c933e | 24 | #include <TH1F.h> |
25 | #include <TF1.h> | |
26 | ||
35b120ff | 27 | #include "AliRunLoader.h" |
2eb38194 | 28 | #include "AliRawReader.h" |
fe0adf2a | 29 | #include "AliGRPObject.h" |
30 | #include "AliCDBManager.h" | |
31 | #include "AliCDBStorage.h" | |
32 | #include "AliCDBEntry.h" | |
b0d2c2d3 | 33 | #include "AliVZEROReconstructor.h" |
2eb38194 | 34 | #include "AliVZERORawStream.h" |
b44c933e | 35 | #include "AliVZEROConst.h" |
b14e6eb4 | 36 | #include "AliESDEvent.h" |
a055ee24 | 37 | #include "AliVZEROTriggerMask.h" |
b090e6a3 | 38 | #include "AliESDfriend.h" |
39 | #include "AliESDVZEROfriend.h" | |
fad64858 | 40 | #include "AliVZEROdigit.h" |
e58b4e66 | 41 | #include "AliVZEROCalibData.h" |
75b6bc77 | 42 | #include "AliRunInfo.h" |
b44c933e | 43 | #include "AliCTPTimeParams.h" |
b0d2c2d3 | 44 | |
b0d2c2d3 | 45 | ClassImp(AliVZEROReconstructor) |
46 | ||
ce7090f5 | 47 | //_____________________________________________________________________________ |
cb2228e6 | 48 | AliVZEROReconstructor:: AliVZEROReconstructor(): AliReconstructor(), |
fe0adf2a | 49 | fESDVZERO(0x0), |
50 | fESD(0x0), | |
51 | fESDVZEROfriend(0x0), | |
b44c933e | 52 | fCalibData(NULL), |
53 | fTimeSlewing(NULL), | |
fe0adf2a | 54 | fCollisionMode(0), |
dbf24214 | 55 | fBeamEnergy(0.), |
56 | fDigitsArray(0) | |
ce7090f5 | 57 | { |
58 | // Default constructor | |
ce7090f5 | 59 | // Get calibration data |
60 | ||
b44c933e | 61 | fCalibData = GetCalibData(); |
62 | ||
63 | AliCDBEntry *entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming"); | |
64 | if (!entry) AliFatal("CTP timing parameters are not found in OCDB !"); | |
65 | AliCTPTimeParams *ctpParams = (AliCTPTimeParams*)entry->GetObject(); | |
66 | Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0; | |
67 | ||
68 | AliCDBEntry *entry2 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeDelays"); | |
69 | if (!entry2) AliFatal("VZERO time delays are not found in OCDB !"); | |
70 | TH1F *delays = (TH1F*)entry2->GetObject(); | |
71 | ||
72 | AliCDBEntry *entry3 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeSlewing"); | |
73 | if (!entry3) AliFatal("VZERO time slewing function is not found in OCDB !"); | |
74 | fTimeSlewing = (TF1*)entry3->GetObject(); | |
75 | ||
76 | for(Int_t i = 0 ; i < 64; ++i) { | |
77 | Int_t board = AliVZEROCalibData::GetBoardNumber(i); | |
78 | fTimeOffset[i] = (((Float_t)fCalibData->GetTriggerCountOffset(board)- | |
79 | (Float_t)fCalibData->GetRollOver(board))*25.0+ | |
80 | fCalibData->GetTimeOffset(i)+ | |
81 | l1Delay+ | |
82 | delays->GetBinContent(i+1)+ | |
83 | kV0Offset); | |
84 | } | |
ce7090f5 | 85 | } |
86 | ||
87 | ||
88 | //_____________________________________________________________________________ | |
89 | AliVZEROReconstructor& AliVZEROReconstructor::operator = | |
90 | (const AliVZEROReconstructor& /*reconstructor*/) | |
91 | { | |
92 | // assignment operator | |
93 | ||
94 | Fatal("operator =", "assignment operator not implemented"); | |
95 | return *this; | |
96 | } | |
97 | ||
98 | //_____________________________________________________________________________ | |
99 | AliVZEROReconstructor::~AliVZEROReconstructor() | |
100 | { | |
101 | // destructor | |
44b6212f | 102 | |
b090e6a3 | 103 | delete fESDVZERO; |
104 | delete fESDVZEROfriend; | |
dbf24214 | 105 | delete fDigitsArray; |
35b120ff | 106 | } |
107 | ||
108 | //_____________________________________________________________________________ | |
d76c31f4 | 109 | void AliVZEROReconstructor::Init() |
35b120ff | 110 | { |
ef314913 | 111 | // initializer |
ce7090f5 | 112 | |
35b120ff | 113 | fESDVZERO = new AliESDVZERO; |
b090e6a3 | 114 | fESDVZEROfriend = new AliESDVZEROfriend; |
fe0adf2a | 115 | |
116 | GetCollisionMode(); // fCollisionMode =1 for Pb-Pb simulated data | |
35b120ff | 117 | } |
118 | ||
119 | //______________________________________________________________________ | |
2e0ee64a | 120 | void AliVZEROReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const |
35b120ff | 121 | { |
75b6bc77 | 122 | // converts RAW to digits |
ef314913 | 123 | |
2e0ee64a | 124 | if (!digitsTree) { |
125 | AliError("No digits tree!"); | |
126 | return; | |
127 | } | |
35b120ff | 128 | |
dbf24214 | 129 | if (!fDigitsArray) |
130 | fDigitsArray = new TClonesArray("AliVZEROdigit", 64); | |
131 | digitsTree->Branch("VZERODigit", &fDigitsArray); | |
2e0ee64a | 132 | |
b090e6a3 | 133 | fESDVZEROfriend->Reset(); |
134 | ||
2e0ee64a | 135 | rawReader->Reset(); |
136 | AliVZERORawStream rawStream(rawReader); | |
75b6bc77 | 137 | if (rawStream.Next()) { |
138 | Float_t adc[64]; | |
6c115a32 | 139 | Float_t time[64], width[64]; |
75b6bc77 | 140 | Bool_t BBFlag[64], BGFlag[64], integrator[64]; |
9d62c464 | 141 | for(Int_t i=0; i<64; i++) { |
75b6bc77 | 142 | Int_t j = rawStream.GetOfflineChannel(i); |
143 | adc[j] = 0.0; | |
144 | time[j] = 0.0; | |
145 | width[j] = 0.0; | |
146 | BBFlag[j] = kFALSE; | |
147 | BGFlag[j] = kFALSE; | |
148 | integrator[j] = kFALSE; | |
149 | // Search for the maximum charge in the train of 21 LHC clocks | |
150 | // regardless of the integrator which has been operated: | |
151 | Float_t maxadc = 0; | |
152 | Int_t imax = -1; | |
153 | Float_t adcPedSub[21]; | |
154 | for(Int_t iClock=0; iClock<21; iClock++){ | |
155 | Bool_t iIntegrator = rawStream.GetIntegratorFlag(i,iClock); | |
156 | Int_t k = j+64*iIntegrator; | |
157 | adcPedSub[iClock] = rawStream.GetPedestal(i,iClock) - fCalibData->GetPedestal(k); | |
158 | if(adcPedSub[iClock] <= GetRecoParam()->GetNSigmaPed()*fCalibData->GetSigma(k)) { | |
159 | adcPedSub[iClock] = 0; | |
160 | continue; | |
161 | } | |
162 | if(iClock < GetRecoParam()->GetStartClock() || iClock > GetRecoParam()->GetEndClock()) continue; | |
163 | if(adcPedSub[iClock] > maxadc) { | |
164 | maxadc = adcPedSub[iClock]; | |
165 | imax = iClock; | |
166 | } | |
167 | } | |
168 | ||
169 | AliDebug(2,Form("Channel %d (online), %d (offline)",i,j)); | |
170 | if (imax != -1) { | |
171 | Int_t start = imax - GetRecoParam()->GetNPreClocks(); | |
172 | if (start < 0) start = 0; | |
173 | Int_t end = imax + GetRecoParam()->GetNPostClocks(); | |
174 | if (end > 20) end = 20; | |
175 | for(Int_t iClock = start; iClock <= end; iClock++) { | |
f93f97bb | 176 | if (iClock >= imax) { |
177 | BBFlag[j] |= rawStream.GetBBFlag(i,iClock); | |
178 | BGFlag[j] |= rawStream.GetBGFlag(i,iClock); | |
179 | } | |
75b6bc77 | 180 | if (iClock == imax) |
181 | adc[j] += rawStream.GetPedestal(i,iClock); | |
182 | else | |
183 | adc[j] += adcPedSub[iClock]; | |
184 | ||
185 | AliDebug(2,Form("clock = %d adc = %f",iClock,rawStream.GetPedestal(i,iClock))); | |
186 | } | |
187 | // Convert i (FEE channel numbering) to j (aliroot channel numbering) | |
188 | ||
75b6bc77 | 189 | integrator[j] = rawStream.GetIntegratorFlag(i,imax); |
190 | } | |
b090e6a3 | 191 | |
82dae5d9 | 192 | Int_t board = j / 8; |
193 | time[j] = rawStream.GetTime(i)/ (25./256.) * fCalibData->GetTimeResolution(board); | |
194 | width[j] = rawStream.GetWidth(i) / 0.4 * fCalibData->GetWidthResolution(board); | |
195 | ||
b090e6a3 | 196 | // Filling the esd friend object |
197 | fESDVZEROfriend->SetBBScalers(j,rawStream.GetBBScalers(i)); | |
198 | fESDVZEROfriend->SetBGScalers(j,rawStream.GetBGScalers(i)); | |
199 | for (Int_t iBunch = 0; iBunch < AliESDVZEROfriend::kNBunches; iBunch++) { | |
db0db003 | 200 | fESDVZEROfriend->SetChargeMB(j,iBunch,rawStream.GetChargeMB(i,iBunch)); |
201 | fESDVZEROfriend->SetIntMBFlag(j,iBunch,rawStream.GetIntMBFlag(i,iBunch)); | |
202 | fESDVZEROfriend->SetBBMBFlag(j,iBunch,rawStream.GetBBMBFlag(i,iBunch)); | |
203 | fESDVZEROfriend->SetBGMBFlag(j,iBunch,rawStream.GetBGMBFlag(i,iBunch)); | |
b090e6a3 | 204 | } |
205 | for (Int_t iEv = 0; iEv < AliESDVZEROfriend::kNEvOfInt; iEv++) { | |
db0db003 | 206 | fESDVZEROfriend->SetPedestal(j,iEv,rawStream.GetPedestal(i,iEv)); |
207 | fESDVZEROfriend->SetIntegratorFlag(j,iEv,rawStream.GetIntegratorFlag(i,iEv)); | |
208 | fESDVZEROfriend->SetBBFlag(j,iEv,rawStream.GetBBFlag(i,iEv)); | |
209 | fESDVZEROfriend->SetBGFlag(j,iEv,rawStream.GetBGFlag(i,iEv)); | |
b090e6a3 | 210 | } |
e58b4e66 | 211 | fESDVZEROfriend->SetTime(j,time[j]); |
212 | fESDVZEROfriend->SetWidth(j,width[j]); | |
9d62c464 | 213 | } |
b090e6a3 | 214 | |
215 | // Filling the esd friend object | |
216 | fESDVZEROfriend->SetTriggerInputs(rawStream.GetTriggerInputs()); | |
217 | fESDVZEROfriend->SetTriggerInputsMask(rawStream.GetTriggerInputsMask()); | |
218 | ||
219 | for(Int_t iScaler = 0; iScaler < AliESDVZEROfriend::kNScalers; iScaler++) | |
db0db003 | 220 | fESDVZEROfriend->SetTriggerScalers(iScaler,rawStream.GetTriggerScalers(iScaler)); |
b090e6a3 | 221 | |
db0db003 | 222 | for(Int_t iBunch = 0; iBunch < AliESDVZEROfriend::kNBunches; iBunch++) |
223 | fESDVZEROfriend->SetBunchNumbersMB(iBunch,rawStream.GetBunchNumbersMB(iBunch)); | |
b090e6a3 | 224 | |
225 | ||
9d62c464 | 226 | // Channels(aliroot numbering) will be ordered in the tree |
227 | for(Int_t iChannel = 0; iChannel < 64; iChannel++) { | |
7495d2be | 228 | if(fCalibData->IsChannelDead(iChannel)){ |
229 | adc[iChannel] = (Float_t) kInvalidADC; | |
230 | time[iChannel] = (Float_t) kInvalidTime; | |
231 | } | |
75b6bc77 | 232 | if (adc[iChannel] > 0) |
dbf24214 | 233 | new ((*fDigitsArray)[fDigitsArray->GetEntriesFast()]) |
d0502ab2 | 234 | AliVZEROdigit(iChannel, adc[iChannel], time[iChannel], |
fad64858 | 235 | width[iChannel], BBFlag[iChannel], BGFlag[iChannel],integrator[iChannel]); |
7495d2be | 236 | |
f0ff6fad | 237 | } |
238 | digitsTree->Fill(); | |
2e0ee64a | 239 | } |
dbf24214 | 240 | |
241 | fDigitsArray->Clear(); | |
2e0ee64a | 242 | } |
243 | ||
244 | //______________________________________________________________________ | |
245 | void AliVZEROReconstructor::FillESD(TTree* digitsTree, TTree* /*clustersTree*/, | |
b14e6eb4 | 246 | AliESDEvent* esd) const |
2e0ee64a | 247 | { |
75b6bc77 | 248 | // fills multiplicities to the ESD - pedestal is now subtracted |
fe0adf2a | 249 | |
2e0ee64a | 250 | if (!digitsTree) { |
fe0adf2a | 251 | AliError("No digits tree!"); |
252 | return; | |
2e0ee64a | 253 | } |
a055ee24 | 254 | |
2e0ee64a | 255 | TBranch* digitBranch = digitsTree->GetBranch("VZERODigit"); |
dbf24214 | 256 | digitBranch->SetAddress(&fDigitsArray); |
35b120ff | 257 | |
44b6212f | 258 | Float_t mult[64]; |
db0db003 | 259 | Float_t adc[64]; |
260 | Float_t time[64]; | |
261 | Float_t width[64]; | |
d0502ab2 | 262 | Bool_t BBFlag[64]; |
263 | Bool_t BGFlag[64]; | |
264 | ||
35b120ff | 265 | for (Int_t i=0; i<64; i++){ |
db0db003 | 266 | adc[i] = 0.0; |
d0502ab2 | 267 | mult[i] = 0.0; |
b44c933e | 268 | time[i] = kInvalidTime; |
db0db003 | 269 | width[i] = 0.0; |
d0502ab2 | 270 | BBFlag[i] = kFALSE; |
271 | BGFlag[i] = kFALSE; | |
a055ee24 | 272 | } |
35b120ff | 273 | |
a055ee24 | 274 | // loop over VZERO entries to get multiplicity |
2e0ee64a | 275 | Int_t nEntries = (Int_t)digitsTree->GetEntries(); |
35b120ff | 276 | for (Int_t e=0; e<nEntries; e++) { |
2e0ee64a | 277 | digitsTree->GetEvent(e); |
35b120ff | 278 | |
dbf24214 | 279 | Int_t nDigits = fDigitsArray->GetEntriesFast(); |
35b120ff | 280 | |
281 | for (Int_t d=0; d<nDigits; d++) { | |
dbf24214 | 282 | AliVZEROdigit* digit = (AliVZEROdigit*) fDigitsArray->At(d); |
63627899 | 283 | Int_t pmNumber = digit->PMNumber(); |
284 | // Pedestal retrieval and suppression: | |
75b6bc77 | 285 | Bool_t integrator = digit->Integrator(); |
f93f97bb | 286 | Int_t k = pmNumber+64*integrator; |
287 | Float_t pedestal = fCalibData->GetPedestal(k); | |
db0db003 | 288 | adc[pmNumber] = digit->ADC() - pedestal; |
b44c933e | 289 | time[pmNumber] = CorrectLeadingTime(pmNumber,digit->Time(),adc[pmNumber]); |
db0db003 | 290 | width[pmNumber] = digit->Width(); |
291 | BBFlag[pmNumber]= digit->BBFlag(); | |
292 | BGFlag[pmNumber]= digit->BGFlag(); | |
75b6bc77 | 293 | |
294 | AliDebug(2,Form("PM = %d ADC = %f TDC %f",pmNumber, digit->ADC(),digit->Time())); | |
295 | ||
75b6bc77 | 296 | if(adc[pmNumber] > (fCalibData->GetPedestal(k) + GetRecoParam()->GetNSigmaPed()*fCalibData->GetSigma(k))) { |
297 | mult[pmNumber] += adc[pmNumber]*fCalibData->GetMIPperADC(pmNumber); | |
fe0adf2a | 298 | } |
35b120ff | 299 | } // end of loop over digits |
35b120ff | 300 | } // end of loop over events in digits tree |
6c6d6114 | 301 | |
b44c933e | 302 | fESDVZERO->SetBit(AliESDVZERO::kCorrectedLeadingTime,kTRUE); |
6c6d6114 | 303 | fESDVZERO->SetMultiplicity(mult); |
28fdf12c | 304 | fESDVZERO->SetADC(adc); |
305 | fESDVZERO->SetTime(time); | |
d0502ab2 | 306 | fESDVZERO->SetWidth(width); |
307 | fESDVZERO->SetBBFlag(BBFlag); | |
308 | fESDVZERO->SetBGFlag(BGFlag); | |
a055ee24 | 309 | |
b44c933e | 310 | // now fill the V0 decision and channel flags |
311 | { | |
312 | AliVZEROTriggerMask triggerMask; | |
313 | triggerMask.FillMasks(fESDVZERO, fCalibData, fTimeSlewing); | |
314 | } | |
a055ee24 | 315 | |
2e0ee64a | 316 | if (esd) { |
44b6212f | 317 | AliDebug(1, Form("Writing VZERO data to ESD tree")); |
318 | esd->SetVZEROData(fESDVZERO); | |
2e0ee64a | 319 | } |
b090e6a3 | 320 | |
321 | if (esd) { | |
fe0adf2a | 322 | AliESDfriend *fr = (AliESDfriend*)esd->FindListObject("AliESDfriend"); |
323 | if (fr) { | |
324 | AliDebug(1, Form("Writing VZERO friend data to ESD tree")); | |
325 | fr->SetVZEROfriend(fESDVZEROfriend); | |
b090e6a3 | 326 | } |
327 | } | |
dbf24214 | 328 | |
329 | fDigitsArray->Clear(); | |
35b120ff | 330 | } |
331 | ||
ce7090f5 | 332 | //_____________________________________________________________________________ |
333 | AliCDBStorage* AliVZEROReconstructor::SetStorage(const char *uri) | |
334 | { | |
ef314913 | 335 | // Sets the storage |
336 | ||
ce7090f5 | 337 | Bool_t deleteManager = kFALSE; |
338 | ||
339 | AliCDBManager *manager = AliCDBManager::Instance(); | |
340 | AliCDBStorage *defstorage = manager->GetDefaultStorage(); | |
341 | ||
342 | if(!defstorage || !(defstorage->Contains("VZERO"))){ | |
343 | AliWarning("No default storage set or default storage doesn't contain VZERO!"); | |
344 | manager->SetDefaultStorage(uri); | |
345 | deleteManager = kTRUE; | |
346 | } | |
347 | ||
348 | AliCDBStorage *storage = manager->GetDefaultStorage(); | |
349 | ||
350 | if(deleteManager){ | |
44b6212f | 351 | AliCDBManager::Instance()->UnsetDefaultStorage(); |
352 | defstorage = 0; // the storage is killed by AliCDBManager::Instance()->Destroy() | |
ce7090f5 | 353 | } |
354 | ||
355 | return storage; | |
356 | } | |
357 | ||
fe0adf2a | 358 | //____________________________________________________________________________ |
359 | void AliVZEROReconstructor::GetCollisionMode() | |
360 | { | |
75b6bc77 | 361 | // Retrieval of collision mode |
fe0adf2a | 362 | |
75b6bc77 | 363 | TString beamType = GetRunInfo()->GetBeamType(); |
fe0adf2a | 364 | if(beamType==AliGRPObject::GetInvalidString()){ |
75b6bc77 | 365 | AliError("VZERO cannot retrieve beam type"); |
fe0adf2a | 366 | return; |
367 | } | |
368 | ||
75b6bc77 | 369 | if( (beamType.CompareTo("P-P") ==0) || (beamType.CompareTo("p-p") ==0) ){ |
370 | fCollisionMode=0; | |
371 | } | |
372 | else if( (beamType.CompareTo("Pb-Pb") ==0) || (beamType.CompareTo("A-A") ==0) ){ | |
373 | fCollisionMode=1; | |
fe0adf2a | 374 | } |
fe0adf2a | 375 | |
75b6bc77 | 376 | fBeamEnergy = GetRunInfo()->GetBeamEnergy(); |
fe0adf2a | 377 | if(fBeamEnergy==AliGRPObject::GetInvalidFloat()) { |
75b6bc77 | 378 | AliError("Missing value for the beam energy ! Using 0"); |
fe0adf2a | 379 | fBeamEnergy = 0.; |
380 | } | |
381 | ||
75b6bc77 | 382 | AliDebug(1,Form("\n ++++++ Beam type and collision mode retrieved as %s %d @ %1.3f GeV ++++++\n\n",beamType.Data(), fCollisionMode, fBeamEnergy)); |
fe0adf2a | 383 | |
384 | } | |
385 | ||
ce7090f5 | 386 | //_____________________________________________________________________________ |
387 | AliVZEROCalibData* AliVZEROReconstructor::GetCalibData() const | |
388 | { | |
ef314913 | 389 | // Gets calibration object for VZERO set |
ce7090f5 | 390 | |
c0b82b5a | 391 | AliCDBManager *man = AliCDBManager::Instance(); |
ce7090f5 | 392 | |
c0b82b5a | 393 | AliCDBEntry *entry=0; |
394 | ||
395 | entry = man->Get("VZERO/Calib/Data"); | |
396 | ||
c0b82b5a | 397 | AliVZEROCalibData *calibdata = 0; |
398 | ||
399 | if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject(); | |
94a600a1 | 400 | if (!calibdata) AliFatal("No calibration data from calibration database !"); |
ce7090f5 | 401 | |
402 | return calibdata; | |
403 | } | |
44b6212f | 404 | |
b44c933e | 405 | Float_t AliVZEROReconstructor::CorrectLeadingTime(Int_t i, Float_t time, Float_t adc) const |
406 | { | |
407 | // Correct the leading time | |
408 | // for slewing effect and | |
409 | // misalignment of the channels | |
410 | if (time < 1e-6) return kInvalidTime; | |
411 | ||
412 | // Channel alignment and general offset subtraction | |
413 | if (i < 32) time -= kV0CDelayCables; | |
414 | time -= fTimeOffset[i]; | |
415 | ||
416 | // In case of pathological signals | |
417 | if (adc < 1e-6) return time; | |
418 | ||
419 | // Slewing correction | |
420 | Float_t thr = fCalibData->GetDiscriThr(i); | |
421 | time -= fTimeSlewing->Eval(adc/thr); | |
422 | ||
423 | return time; | |
424 | } |