]>
Commit | Line | Data |
---|---|---|
a65a7e70 | 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 | // Class AliVZEROTriggerSimulator | |
17 | // ------------------------------ | |
18 | // Simulate the VZERO Trigger response | |
19 | // Use FEE parameters stored in Database | |
20 | // Can work on real data or in simulation | |
21 | // | |
22 | ||
23 | #include <TTree.h> | |
24 | #include <TClonesArray.h> | |
25 | #include <TParameter.h> | |
26 | ||
27 | #include "AliLog.h" | |
28 | #include "AliCDBManager.h" | |
29 | #include "AliCDBEntry.h" | |
30 | #include "AliCDBStorage.h" | |
31 | #include "AliCDBId.h" | |
32 | #include "AliVZEROTriggerData.h" | |
33 | #include "AliVZEROLogicalSignal.h" | |
34 | #include "AliVZEROTriggerSimulator.h" | |
35 | #include "AliVZEROdigit.h" | |
36 | #include "AliVZEROCalibData.h" | |
37 | #include "AliVZEROConst.h" | |
38 | #include "AliCTPTimeParams.h" | |
39 | ||
40 | ClassImp(AliVZEROTriggerSimulator) | |
41 | ||
42 | //_____________________________________________________________________________ | |
43 | AliVZEROTriggerSimulator::AliVZEROTriggerSimulator(TTree * digitsTree, TClonesArray* digits) : | |
44 | TObject(),fTriggerData(NULL),fDigitsTree(digitsTree),fDigits(digits),fTriggerWord(0) | |
45 | { | |
46 | // constructor | |
47 | fTriggerData = LoadTriggerData(); | |
48 | LoadClockOffset(); | |
49 | ||
50 | for(int i=0;i<64;i++) { | |
51 | fBBFlags[i] = fBGFlags[i] = kFALSE; | |
52 | fCharges[i] = 0.; | |
53 | } | |
54 | GenerateBBWindows(); | |
55 | GenerateBGWindows(); | |
56 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
57 | fBBLatch[i] = new AliVZEROLogicalSignal(fTriggerData->GetLatchWin1(i),0); | |
58 | fBGLatch[i] = new AliVZEROLogicalSignal(fTriggerData->GetLatchWin2(i),0); | |
59 | fBBReset[i] = new AliVZEROLogicalSignal(fTriggerData->GetResetWin1(i),0); | |
60 | fBGReset[i] = new AliVZEROLogicalSignal(fTriggerData->GetResetWin2(i),0); | |
61 | } | |
62 | } | |
63 | //_____________________________________________________________________________ | |
64 | AliVZEROTriggerSimulator::AliVZEROTriggerSimulator() : | |
65 | TObject(),fTriggerData(NULL),fDigitsTree(NULL),fDigits(NULL),fTriggerWord(0) | |
66 | { | |
67 | // Default constructor | |
68 | fTriggerData = LoadTriggerData(); | |
69 | LoadClockOffset(); | |
70 | ||
71 | for(int i=0;i<64;i++) { | |
72 | fBBFlags[i] = fBGFlags[i] = kFALSE; | |
73 | fCharges[i] = 0; | |
74 | } | |
75 | GenerateBBWindows(); | |
76 | GenerateBGWindows(); | |
77 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
78 | fBBLatch[i] = new AliVZEROLogicalSignal(fTriggerData->GetLatchWin1(i),0); | |
79 | fBGLatch[i] = new AliVZEROLogicalSignal(fTriggerData->GetLatchWin2(i),0); | |
80 | fBBReset[i] = new AliVZEROLogicalSignal(fTriggerData->GetResetWin1(i),0); | |
81 | fBGReset[i] = new AliVZEROLogicalSignal(fTriggerData->GetResetWin2(i),0); | |
82 | } | |
83 | } | |
84 | ||
85 | //_____________________________________________________________________________ | |
86 | AliVZEROTriggerSimulator::~AliVZEROTriggerSimulator(){ | |
87 | // Destructor | |
88 | for (Int_t i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
89 | delete fBBGate[i]; | |
90 | delete fBGGate[i]; | |
91 | delete fBBLatch[i]; | |
92 | delete fBBReset[i]; | |
93 | delete fBGLatch[i]; | |
94 | delete fBGReset[i]; | |
95 | } | |
96 | } | |
97 | ||
98 | //_____________________________________________________________________________ | |
99 | void AliVZEROTriggerSimulator::GenerateBBWindows() | |
100 | { | |
101 | // Generates the BB observation window | |
102 | // In case gates are open the windows are equal to 25ns | |
103 | if (AreGatesOpen()) { | |
104 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
105 | fBBGate[i] = new AliVZEROLogicalSignal(); | |
106 | fBBGate[i]->SetStartTime(0.); | |
107 | fBBGate[i]->SetStopTime(25.0); | |
108 | } | |
109 | } | |
110 | else { | |
111 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
112 | AliVZEROLogicalSignal clk1BB(fTriggerData->GetClk1Win1(i),fTriggerData->GetDelayClk1Win1(i)); | |
113 | AliVZEROLogicalSignal clk2BB(fTriggerData->GetClk2Win1(i),fTriggerData->GetDelayClk2Win1(i)); | |
114 | fBBGate[i] = new AliVZEROLogicalSignal(clk1BB & clk2BB); | |
115 | } | |
116 | } | |
117 | } | |
118 | //_____________________________________________________________________________ | |
119 | void AliVZEROTriggerSimulator::GenerateBGWindows() | |
120 | { | |
121 | // Generates the BG observation window | |
122 | // In case gates are open the windows are equal to 25ns | |
123 | if (AreGatesOpen()) { | |
124 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
125 | fBGGate[i] = new AliVZEROLogicalSignal(); | |
126 | fBGGate[i]->SetStartTime(0.); | |
127 | fBGGate[i]->SetStopTime(25.0); | |
128 | } | |
129 | } | |
130 | else { | |
131 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
132 | AliVZEROLogicalSignal clk1BG(fTriggerData->GetClk1Win2(i),fTriggerData->GetDelayClk1Win2(i)); | |
133 | AliVZEROLogicalSignal clk2BG(fTriggerData->GetClk2Win2(i),fTriggerData->GetDelayClk2Win2(i)); | |
134 | fBGGate[i] = new AliVZEROLogicalSignal(clk1BG & clk2BG); | |
135 | // In VZERO-A we have a shift by -25ns which is controlled by | |
136 | // 'Delay Win2' = 7 instead of default 6. | |
137 | // The flag is not stored in OCDB so we have manually shift the | |
138 | // trigger windows | |
139 | if (i < 4) { | |
140 | fBGGate[i]->SetStartTime(fBGGate[i]->GetStartTime()-25.0); | |
141 | fBGGate[i]->SetStopTime(fBGGate[i]->GetStopTime()-25.0); | |
142 | } | |
143 | } | |
144 | } | |
145 | } | |
146 | ||
147 | //_____________________________________________________________________________ | |
148 | AliVZEROTriggerData * AliVZEROTriggerSimulator::LoadTriggerData() const | |
149 | { | |
150 | // Gets Trigger object for VZERO set | |
151 | AliDebug(1,"Loading Trigger parameters"); | |
152 | AliCDBManager *man = AliCDBManager::Instance(); | |
153 | ||
154 | ||
155 | AliCDBEntry *entry=0; | |
156 | ||
157 | entry = man->Get("VZERO/Trigger/Data"); | |
158 | if(!entry){ | |
159 | AliFatal("Load of trigger calibration data from default storage failed!"); | |
160 | return NULL; | |
161 | } | |
162 | ||
163 | // Retrieval of data in directory VZERO/Calib/Trigger: | |
164 | ||
165 | AliVZEROTriggerData *triggerData = NULL; | |
166 | ||
167 | if (entry) triggerData = (AliVZEROTriggerData*) entry->GetObject(); | |
168 | if (!triggerData) AliError("No Trigger data from database !"); | |
169 | ||
170 | return triggerData; | |
171 | } | |
172 | ||
173 | ||
174 | //_____________________________________________________________________________ | |
175 | void AliVZEROTriggerSimulator::LoadClockOffset() | |
176 | { | |
177 | // This method is used in order to | |
178 | // retrieve the TDC clock offset including | |
179 | // roll-over, trig count and CTP L0->L1 delay | |
180 | ||
181 | AliCDBEntry *entry0 = AliCDBManager::Instance()->Get("VZERO/Calib/Data"); | |
182 | if (!entry0) { | |
183 | AliFatal("V0 Calib object is not found in OCDB !"); | |
184 | return; | |
185 | } | |
186 | AliVZEROCalibData *calibdata = (AliVZEROCalibData*) entry0->GetObject(); | |
187 | ||
188 | AliCDBEntry *entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming"); | |
189 | if (!entry) { | |
190 | AliFatal("CTP timing parameters are not found in OCDB !"); | |
191 | return; | |
192 | } | |
193 | AliCTPTimeParams *ctpParams = (AliCTPTimeParams*)entry->GetObject(); | |
194 | Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0; | |
195 | ||
196 | AliCDBEntry *entry1 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign"); | |
197 | if (!entry1) { | |
198 | AliFatal("CTP time-alignment is not found in OCDB !"); | |
199 | return; | |
200 | } | |
201 | AliCTPTimeParams *ctpTimeAlign = (AliCTPTimeParams*)entry1->GetObject(); | |
202 | l1Delay += ((Float_t)ctpTimeAlign->GetDelayL1L0()*25.0); | |
203 | ||
204 | for(Int_t board = 0; board < AliVZEROTriggerData::kNCIUBoards; ++board) { | |
205 | fClockOffset[board] = (((Float_t)calibdata->GetRollOver(board)- | |
206 | (Float_t)calibdata->GetTriggerCountOffset(board))*25.0- | |
207 | l1Delay+ | |
208 | kV0Offset); | |
209 | AliDebug(1,Form("Board %d Offset %f",board,fClockOffset[board])); | |
210 | } | |
211 | } | |
212 | ||
213 | //_____________________________________________________________________________ | |
214 | void AliVZEROTriggerSimulator::Run() { | |
215 | //AliInfo("Generating VZERO Triggers"); | |
216 | ||
217 | // Loop over VZERO entries | |
218 | Int_t nEntries = (Int_t)fDigitsTree->GetEntries(); | |
219 | for (Int_t ievt=0; ievt<nEntries; ievt++) { | |
220 | fDigitsTree->GetEvent(ievt); | |
221 | ||
222 | Int_t nDigits = fDigits->GetEntriesFast(); | |
223 | ||
224 | for (Int_t iDigit=0; iDigit<nDigits; iDigit++) { | |
225 | AliVZEROdigit* digit = (AliVZEROdigit*)fDigits->At(iDigit); | |
226 | ||
227 | Int_t integrator = digit->Integrator(); | |
228 | Int_t pmNumber = digit->PMNumber(); | |
229 | Int_t board = AliVZEROCalibData::GetBoardNumber(pmNumber); | |
230 | Int_t channel = AliVZEROCalibData::GetFEEChannelNumber(pmNumber); | |
231 | if (board < 0 || channel < 0) continue; | |
232 | ||
233 | if(fTriggerData->GetEnableCharge(board,channel)) { | |
234 | fCharges[pmNumber] = digit->ChargeADC(AliVZEROdigit::kNClocks/2); | |
235 | if(fTriggerData->GetPedestalSubtraction(board)) { | |
236 | if(fCharges[pmNumber]>=(Float_t) fTriggerData->GetPedestalCut(integrator,board,channel)){ | |
237 | fCharges[pmNumber] -= (Float_t) fTriggerData->GetPedestal(integrator,board,channel); | |
238 | } else { | |
239 | fCharges[pmNumber] = 0.; | |
240 | } | |
241 | } | |
242 | } else { | |
243 | fCharges[pmNumber] = 0.; | |
244 | } | |
245 | ||
246 | Float_t time = digit->Time(); | |
247 | time -= fClockOffset[board]; | |
248 | ||
249 | AliDebug(10,Form(" Digit: %f %d %d %d %d %d %d %d %d",digit->Time(), | |
250 | digit->ChargeADC(8),digit->ChargeADC(9),digit->ChargeADC(10), | |
251 | digit->ChargeADC(11),digit->ChargeADC(12),digit->ChargeADC(13), | |
252 | digit->ChargeADC(14),digit->ChargeADC(15))); | |
253 | AliDebug(10,Form(" PM nb : %d ; TDC= %f(%f) Enable Time %d charge %d inCoin %d charge %f", | |
254 | pmNumber,time,digit->Time(), | |
255 | fTriggerData->GetEnableTiming(board,channel),fTriggerData->GetEnableCharge(board,channel), | |
256 | fBBGate[board]->IsInCoincidence(time),fCharges[pmNumber])); | |
257 | fBBFlags[pmNumber] = fTriggerData->GetEnableTiming(board,channel) && fBBGate[board]->IsInCoincidence(time); | |
258 | fBGFlags[pmNumber] = fTriggerData->GetEnableTiming(board,channel) && fBGGate[board]->IsInCoincidence(time); | |
259 | ||
260 | } // end of loop over digits | |
261 | } // end of loop over events in digits tree | |
262 | ||
263 | Int_t nBBflagsV0A = 0; | |
264 | Int_t nBBflagsV0C = 0; | |
265 | Int_t nBGflagsV0A = 0; | |
266 | Int_t nBGflagsV0C = 0; | |
267 | Float_t chargeV0A = 0.; | |
268 | Float_t chargeV0C = 0.; | |
269 | Int_t aBBflagsV0A = 0; | |
270 | Int_t aBBflagsV0C = 0; | |
271 | Int_t aBGflagsV0A = 0; | |
272 | Int_t aBGflagsV0C = 0; | |
273 | ||
274 | for(int i=0;i<64;i++) { | |
275 | if(i<32) { | |
276 | nBBflagsV0C += fBBFlags[i]; | |
277 | nBGflagsV0C += fBGFlags[i]; | |
278 | chargeV0C += fCharges[i]; | |
279 | if (fBBFlags[i]) aBBflagsV0C |= (1 << i); | |
280 | if (fBGFlags[i]) aBGflagsV0C |= (1 << i); | |
281 | } else { | |
282 | nBBflagsV0A += fBBFlags[i]; | |
283 | nBGflagsV0A += fBGFlags[i]; | |
284 | chargeV0A += fCharges[i]; | |
285 | if (fBBFlags[i]) aBBflagsV0A |= (1 << (i-32)); | |
286 | if (fBGFlags[i]) aBGflagsV0A |= (1 << (i-32)); | |
287 | } | |
288 | //AliInfo(Form("Ch %d BB=%d BG=%d",i,fBBFlags[i],fBGFlags[i] )); | |
289 | } | |
290 | ||
291 | // Store the BB and BG flags in the digits tree (user info) | |
292 | fDigitsTree->GetUserInfo()->Add(new TParameter<int>("BBflagsV0A",aBBflagsV0A)); | |
293 | fDigitsTree->GetUserInfo()->Add(new TParameter<int>("BBflagsV0C",aBBflagsV0C)); | |
294 | fDigitsTree->GetUserInfo()->Add(new TParameter<int>("BGflagsV0A",aBGflagsV0A)); | |
295 | fDigitsTree->GetUserInfo()->Add(new TParameter<int>("BGflagsV0C",aBGflagsV0C)); | |
296 | ||
297 | // BBA | |
298 | if(nBBflagsV0A>=fTriggerData->GetBBAThreshold()) SetBBA(); | |
299 | ||
300 | // BBC | |
301 | if(nBBflagsV0C>=fTriggerData->GetBBCThreshold()) SetBBC(); | |
302 | ||
303 | // BBA_AND_BBC | |
304 | if(GetBBA() && GetBBC()) SetBBAandBBC(); | |
305 | ||
306 | // BBA_OR_BBC | |
307 | if(GetBBA() || GetBBC()) SetBBAorBBC(); | |
308 | ||
309 | // BGA | |
310 | if(nBGflagsV0A>=fTriggerData->GetBGAThreshold()) SetBGA(); | |
311 | ||
312 | // BGC | |
313 | if(nBGflagsV0C>=fTriggerData->GetBGCThreshold()) SetBGC(); | |
314 | ||
315 | // BGA_AND_BBC (Beam Gas from RB24 side) | |
316 | if(nBBflagsV0C>=fTriggerData->GetBBCForBGThreshold() && GetBGA()) SetBGAandBBC(); | |
317 | ||
318 | // BGC_AND_BBA (Beam Gas from RB26 side) | |
319 | if(nBBflagsV0A>=fTriggerData->GetBBAForBGThreshold() && GetBGC()) SetBGCandBBA(); | |
320 | ||
321 | // CTA1_AND_CTC1 (Centrality trigger 1) | |
322 | if(chargeV0A>=fTriggerData->GetCentralityV0AThrLow() && chargeV0C>=fTriggerData->GetCentralityV0CThrLow()) SetCTA1andCTC1(); | |
323 | ||
324 | // CTA1_OR_CTC1 (Centrality trigger 1) | |
325 | if(chargeV0A>=fTriggerData->GetCentralityV0AThrLow() || chargeV0C>=fTriggerData->GetCentralityV0CThrLow()) SetCTA1orCTC1(); | |
326 | ||
327 | // CTA2_AND_CTC2 (Centrality trigger 2) | |
328 | if(chargeV0A>=fTriggerData->GetCentralityV0AThrHigh() && chargeV0C>=fTriggerData->GetCentralityV0CThrHigh()) SetCTA2andCTC2(); | |
329 | ||
330 | // CTA2_OR_CTC2 (Centrality trigger 2) | |
331 | if(chargeV0A>=fTriggerData->GetCentralityV0AThrHigh() || chargeV0C>=fTriggerData->GetCentralityV0CThrHigh()) SetCTA2orCTC2(); | |
332 | ||
333 | // MTA_AND_MTC (Multiplicity Trigger) | |
334 | if((nBBflagsV0A<=fTriggerData->GetMultV0AThrHigh() && nBBflagsV0A>=fTriggerData->GetMultV0AThrLow()) | |
335 | && (nBBflagsV0C<=fTriggerData->GetMultV0CThrHigh() && nBBflagsV0C>=fTriggerData->GetMultV0CThrLow()) ) | |
336 | SetMTAandMTC(); | |
337 | ||
338 | // MTA_OR_MTC (Multiplicity Trigger) | |
339 | if((nBBflagsV0A<=fTriggerData->GetMultV0AThrHigh() && nBBflagsV0A>=fTriggerData->GetMultV0AThrLow()) | |
340 | || (nBBflagsV0C<=fTriggerData->GetMultV0CThrHigh() && nBBflagsV0C>=fTriggerData->GetMultV0CThrLow()) ) | |
341 | SetMTAorMTC(); | |
342 | ||
343 | // BGA_OR_BGC | |
344 | if(GetBGA() || GetBGC()) SetBGAorBGC(); | |
345 | ||
346 | // (BGA and BBC) or (BGC and BBA) (Beam Gas from one of the two sides) | |
347 | if(GetBGAandBBC() || GetBGCandBBA()) SetBeamGas(); | |
348 | ||
349 | // AliInfo(Form("BB Flags : V0A = %d V0C = %d ",nBBflagsV0A, nBBflagsV0C )); | |
350 | // AliInfo(Form("BG Flags : V0A = %d V0C = %d ",nBGflagsV0A, nBGflagsV0C )); | |
351 | // AliInfo(Form("Charges : V0A = %d V0C = %d ",chargeV0A, chargeV0C )); | |
352 | ||
353 | } | |
354 | ||
355 | //_____________________________________________________________________________ | |
356 | Bool_t AliVZEROTriggerSimulator::AreGatesOpen() const { | |
357 | // The method check if the gates are suppossed to be open | |
358 | // (corresponding to 'Test Window' flag in DCS). | |
359 | // Since the flag is not stored in OCDB, we just check if | |
360 | // all the clock delays are 0 or not. | |
361 | // This rules should be followed when setting up the detector | |
362 | // at the level of DCS | |
363 | ||
364 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
365 | if (fTriggerData->GetDelayClk1Win1(i)!=0 || | |
366 | fTriggerData->GetDelayClk2Win1(i)!=0 || | |
367 | fTriggerData->GetDelayClk1Win2(i)!=0 || | |
368 | fTriggerData->GetDelayClk2Win2(i)!=0) | |
369 | return kFALSE; | |
370 | } | |
371 | return kTRUE; | |
372 | } | |
373 | ||
374 | //_____________________________________________________________________________ | |
375 | void AliVZEROTriggerSimulator::Print(Option_t* /* opt */) const | |
376 | { | |
377 | // Prints the trigger windows as | |
378 | // initialized from the OCDB | |
379 | for (int i=0; i<AliVZEROTriggerData::kNCIUBoards; i++) { | |
380 | std::cout << "Board=" << i << " BB (" << fBBGate[i]->GetStartTime() << " -> " << fBBGate[i]->GetStopTime() << ") BG (" << fBGGate[i]->GetStartTime() << " -> " << fBGGate[i]->GetStopTime() << ")" << std::endl; | |
381 | } | |
382 | std::cout << std::endl; | |
383 | } | |
384 | ||
385 |