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