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