]>
Commit | Line | Data |
---|---|---|
f9a1843e | 1 | // $Id: AliEmcalTriggerMaker.cxx 64593 2013-10-18 10:23:58Z loizides $ |
00c77045 | 2 | // |
3 | // Class to make emcal particles in AOD/ESD events. | |
4 | // | |
5 | // Author: J.Kral | |
6 | ||
7 | #include <TClonesArray.h> | |
00c77045 | 8 | |
9 | #include "AliLog.h" | |
10 | #include "AliEmcalTriggerPatchInfo.h" | |
11 | #include "AliEmcalTriggerSetupInfo.h" | |
12 | ||
13 | #include "AliEmcalTriggerMaker.h" | |
14 | #include "AliEMCALTriggerTypes.h" | |
15 | #include "AliEMCALGeometry.h" | |
16 | ||
17 | #include "AliVCaloTrigger.h" | |
001765f7 | 18 | #include "AliAODCaloTrigger.h" |
00c77045 | 19 | #include "AliVCaloCells.h" |
001765f7 | 20 | #include "AliVVZERO.h" |
00c77045 | 21 | |
22 | ClassImp(AliEmcalTriggerMaker) | |
23 | ||
24 | using namespace std; | |
25 | ||
26 | //________________________________________________________________________ | |
27 | AliEmcalTriggerMaker::AliEmcalTriggerMaker() : | |
9239b066 | 28 | AliAnalysisTaskEmcal("AliEmcalTriggerMaker",kFALSE), |
00c77045 | 29 | fCaloTriggersOutName("EmcalTriggers"), |
30 | fCaloTriggerSetupOutName("EmcalTriggersSetup"), | |
001765f7 | 31 | fV0InName("AliAODVZERO"), |
00c77045 | 32 | fCaloTriggersOut(0), |
001765f7 | 33 | fCaloTriggerSetupOut(0), |
34 | fSimpleOfflineTriggers(0), | |
f9a1843e | 35 | fV0(0), |
36 | fITrigger(0) | |
00c77045 | 37 | { |
38 | // Constructor. | |
001765f7 | 39 | for( int i = 0; i < 4; i++ ) |
40 | for( int j = 0; j < 3; j++ ) | |
41 | fThresholdConstants[i][j] = 0; | |
00c77045 | 42 | } |
43 | ||
44 | //________________________________________________________________________ | |
45 | AliEmcalTriggerMaker::AliEmcalTriggerMaker(const char *name) : | |
9239b066 | 46 | AliAnalysisTaskEmcal(name,kFALSE), |
00c77045 | 47 | fCaloTriggersOutName("EmcalTriggers"), |
48 | fCaloTriggerSetupOutName("EmcalTriggersSetup"), | |
001765f7 | 49 | fV0InName("AliAODVZERO"), |
00c77045 | 50 | fCaloTriggersOut(0), |
001765f7 | 51 | fCaloTriggerSetupOut(0), |
52 | fSimpleOfflineTriggers(0), | |
f9a1843e | 53 | fV0(0), |
54 | fITrigger(0) | |
00c77045 | 55 | { |
56 | // Constructor. | |
001765f7 | 57 | for( int i = 0; i < 4; i++ ) |
58 | for( int j = 0; j < 3; j++ ) | |
59 | fThresholdConstants[i][j] = 0; | |
00c77045 | 60 | } |
61 | ||
62 | //________________________________________________________________________ | |
63 | AliEmcalTriggerMaker::~AliEmcalTriggerMaker() | |
64 | { | |
65 | // Destructor. | |
66 | } | |
67 | ||
68 | //________________________________________________________________________ | |
69 | void AliEmcalTriggerMaker::ExecOnce() | |
70 | { | |
71 | // Init the analysis. | |
72 | ||
9239b066 | 73 | AliAnalysisTaskEmcal::ExecOnce(); |
00c77045 | 74 | |
75 | if (!fInitialized) | |
76 | return; | |
77 | ||
78 | if (!fCaloTriggersOutName.IsNull()) { | |
79 | fCaloTriggersOut = new TClonesArray("AliEmcalTriggerPatchInfo"); | |
80 | fCaloTriggersOut->SetName(fCaloTriggersOutName); | |
81 | ||
82 | if (!(InputEvent()->FindListObject(fCaloTriggersOutName))) { | |
83 | InputEvent()->AddObject(fCaloTriggersOut); | |
84 | } | |
85 | else { | |
86 | fInitialized = kFALSE; | |
87 | AliFatal(Form("%s: Container with same name %s already present. Aborting", GetName(), fCaloTriggersOutName.Data())); | |
88 | return; | |
89 | } | |
90 | } | |
91 | ||
92 | if (!fCaloTriggerSetupOutName.IsNull()) { | |
93 | fCaloTriggerSetupOut = new AliEmcalTriggerSetupInfo(); | |
94 | fCaloTriggerSetupOut->SetName(fCaloTriggerSetupOutName); | |
95 | ||
96 | if (!(InputEvent()->FindListObject(fCaloTriggerSetupOutName))) { | |
97 | InputEvent()->AddObject(fCaloTriggerSetupOut); | |
98 | } | |
99 | else { | |
100 | fInitialized = kFALSE; | |
101 | AliFatal(Form("%s: Container with same name %s already present. Aborting", GetName(), fCaloTriggerSetupOutName.Data())); | |
102 | return; | |
103 | } | |
104 | } | |
105 | ||
001765f7 | 106 | if ( ! fV0InName.IsNull()) { |
107 | fV0 = (AliVVZERO*)InputEvent()->FindListObject( fV0InName ); | |
108 | } | |
109 | ||
110 | // container for simple offline trigger processing | |
111 | fSimpleOfflineTriggers = new AliAODCaloTrigger(); | |
112 | fSimpleOfflineTriggers->Allocate( 0 ); | |
00c77045 | 113 | } |
114 | ||
115 | //________________________________________________________________________ | |
116 | Bool_t AliEmcalTriggerMaker::Run() | |
117 | { | |
118 | // Create the emcal particles | |
119 | ||
001765f7 | 120 | Short_t cellId; |
f9a1843e | 121 | Int_t globCol, globRow, v0[2]; |
122 | Int_t absId, adcAmp, tBits; | |
123 | Int_t i, j, nCell, iCell; | |
124 | Double_t amp; | |
001765f7 | 125 | ULong64_t v0S, thresh; |
126 | Bool_t isOfflineSimple; | |
00c77045 | 127 | |
4a51ca21 | 128 | AliEmcalTriggerPatchInfo *trigger, *triggerMainJet, *triggerMainGamma, *triggerMainLevel0; |
f9a1843e | 129 | AliEmcalTriggerPatchInfo *triggerMainJetSimple, *triggerMainGammaSimple; |
00c77045 | 130 | |
131 | // delete patch array, clear setup object | |
132 | fCaloTriggersOut->Delete(); | |
133 | fCaloTriggerSetupOut->Clean(); | |
134 | ||
135 | if( !fCaloTriggers ){ | |
136 | AliError(Form("Calo triggers container %s not available.", fCaloTriggersName.Data())); | |
137 | return kTRUE; | |
138 | } | |
139 | if( !fCaloCells ){ | |
140 | AliError(Form("Calo cells container %s not available.", fCaloCellsName.Data())); | |
141 | return kTRUE; | |
142 | } | |
001765f7 | 143 | if( !fCaloCells ){ |
144 | AliError(Form("V0 container %s not available.", fV0InName.Data())); | |
145 | return kTRUE; | |
146 | } | |
f9a1843e | 147 | |
148 | // do not process, if sooner than 11h period | |
149 | // 160683 ?? | |
150 | if( InputEvent()->GetRunNumber() < 167693 ) | |
151 | return kTRUE; | |
152 | ||
153 | // // do not process any MC, since no MC was generated with correct | |
154 | // // EMCal trigger L1 jet trigger simulation, yet | |
155 | // // productions will be enabled, once some correct once are produced | |
156 | // if( MCEvent() != 0 ) | |
157 | // return kTRUE; | |
158 | ||
00c77045 | 159 | // must reset before usage, or the class will fail |
160 | fCaloTriggers->Reset(); | |
f9a1843e | 161 | |
162 | // first run over the patch array to compose a map of 2x2 patch energies | |
cf9ee6ed | 163 | // which is then needed to construct the full patch ADC energy |
164 | // class is not empty | |
165 | if( fCaloTriggers->GetEntries() > 0 ){ | |
166 | ||
f9a1843e | 167 | // zero the array |
168 | for( i = 0; i < 48; i++ ) | |
169 | for( j = 0; j < 64; j++ ) | |
170 | fPatchADC[i][j] = 0; | |
cf9ee6ed | 171 | |
172 | // go throuth the trigger channels | |
173 | while( fCaloTriggers->Next() ){ | |
174 | // get position in global 2x2 tower coordinates | |
175 | // A0 left bottom (0,0) | |
176 | fCaloTriggers->GetPosition( globCol, globRow ); | |
177 | ||
178 | // for some strange reason some ADC amps are initialized in reconstruction | |
179 | // as -1, neglect those :\\ wth | |
180 | fCaloTriggers->GetL1TimeSum( adcAmp ); | |
181 | if( adcAmp > -1 ) | |
f9a1843e | 182 | fPatchADC[globCol][globRow] = adcAmp; |
4e67b745 | 183 | |
f9a1843e | 184 | } // patches |
185 | } // array not empty | |
cf9ee6ed | 186 | |
001765f7 | 187 | // fill the array for offline trigger processing |
188 | // using calibrated cell energies | |
189 | for( i = 0; i < 48; i++ ) | |
190 | for( j = 0; j < 64; j++ ) | |
191 | fPatchADCSimple[i][j] = 0; | |
192 | ||
193 | // fill the patch ADCs from cells | |
194 | nCell = fCaloCells->GetNumberOfCells(); | |
195 | ||
196 | for( iCell = 0; iCell < nCell; iCell++ ){ | |
197 | // get the cell info, based in index in array | |
198 | cellId = fCaloCells->GetCellNumber( iCell ); | |
199 | amp = fCaloCells->GetAmplitude( iCell ); | |
200 | ||
201 | // get position | |
202 | fGeom->GetFastORIndexFromCellIndex( cellId, absId ); | |
203 | fGeom->GetPositionInEMCALFromAbsFastORIndex( absId, globCol, globRow ); | |
204 | ||
205 | // add | |
206 | fPatchADCSimple[globCol][globRow] += amp/kEMCL1ADCtoGeV; | |
207 | } | |
cf9ee6ed | 208 | |
00c77045 | 209 | // dig out common data (thresholds) |
210 | // 0 - jet high, 1 - gamma high, 2 - jet low, 3 - gamma low | |
211 | fCaloTriggerSetupOut->SetThresholds( fCaloTriggers->GetL1Threshold( 0 ), | |
212 | fCaloTriggers->GetL1Threshold( 1 ), | |
213 | fCaloTriggers->GetL1Threshold( 2 ), | |
214 | fCaloTriggers->GetL1Threshold( 3 )); | |
215 | ||
001765f7 | 216 | // get the V0 value and compute and set the offline thresholds |
217 | // get V0, compute thresholds and save them as global parameters | |
218 | v0[0] = fV0->GetTriggerChargeA(); | |
219 | v0[1] = fV0->GetTriggerChargeC(); | |
220 | v0S = v0[0] + v0[1]; | |
221 | ||
222 | fSimpleOfflineTriggers->SetL1V0( v0 ); | |
223 | ||
224 | for( i = 0; i < 4; i++ ){ | |
225 | // A*V0^2/2^32+B*V0/2^16+C | |
226 | thresh = ( ((ULong64_t)fThresholdConstants[i][0]) * v0S * v0S ) >> 32; | |
227 | thresh += ( ((ULong64_t)fThresholdConstants[i][1]) * v0S ) >> 16; | |
228 | thresh += ((ULong64_t)fThresholdConstants[i][2]); | |
229 | fSimpleOfflineTriggers->SetL1Threshold( i, thresh ); | |
230 | } | |
231 | ||
232 | // save the thresholds in output object | |
233 | fCaloTriggerSetupOut->SetThresholdsSimple( fSimpleOfflineTriggers->GetL1Threshold( 0 ), | |
234 | fSimpleOfflineTriggers->GetL1Threshold( 1 ), | |
235 | fSimpleOfflineTriggers->GetL1Threshold( 2 ), | |
236 | fSimpleOfflineTriggers->GetL1Threshold( 3 )); | |
237 | ||
238 | // run the trigger | |
239 | RunSimpleOfflineTrigger(); | |
240 | ||
241 | // reset for re-run | |
242 | fCaloTriggers->Reset(); | |
243 | fSimpleOfflineTriggers->Reset(); | |
244 | ||
00c77045 | 245 | // class is not empty |
001765f7 | 246 | if( fCaloTriggers->GetEntries() > 0 || fSimpleOfflineTriggers->GetEntries() > 0 ){ |
f9a1843e | 247 | fITrigger = 0; |
248 | triggerMainGamma = 0; | |
249 | triggerMainJet = 0; | |
250 | triggerMainGammaSimple = 0; | |
251 | triggerMainJetSimple = 0; | |
8ee32bb2 | 252 | triggerMainLevel0 = 0; |
00c77045 | 253 | |
001765f7 | 254 | // go throuth the trigger channels, real first, then offline |
255 | while( NextTrigger( isOfflineSimple ) ){ | |
f9a1843e | 256 | // process jet |
4a51ca21 | 257 | trigger = ProcessPatch( kTMEMCalJet, isOfflineSimple ); |
f9a1843e | 258 | |
259 | // save main jet triggers in event | |
260 | if( trigger != 0 ){ | |
261 | // check if more energetic than others for main patch marking | |
262 | if( ! isOfflineSimple ){ | |
263 | if( triggerMainJet == 0 ) | |
264 | triggerMainJet = trigger; | |
265 | else if( triggerMainJet->GetPatchE() < trigger->GetPatchE() ) | |
266 | triggerMainJet = trigger; | |
267 | } | |
268 | else{ | |
269 | if( triggerMainJetSimple == 0 ) | |
270 | triggerMainJetSimple = trigger; | |
271 | else if( triggerMainJetSimple->GetPatchE() < trigger->GetPatchE() ) | |
272 | triggerMainJetSimple = trigger; | |
273 | } | |
274 | } | |
00c77045 | 275 | |
f9a1843e | 276 | // process gamma |
4a51ca21 | 277 | trigger = ProcessPatch( kTMEMCalGamma, isOfflineSimple ); |
f9a1843e | 278 | |
279 | // save main gamma triggers in event | |
280 | if( trigger != 0 ){ | |
281 | // check if more energetic than others for main patch marking | |
282 | if( ! isOfflineSimple ){ | |
283 | if( triggerMainGamma == 0 ) | |
284 | triggerMainGamma = trigger; | |
285 | else if( triggerMainGamma->GetPatchE() < trigger->GetPatchE() ) | |
286 | triggerMainGamma = trigger; | |
287 | } | |
288 | else{ | |
289 | if( triggerMainGammaSimple == 0 ) | |
290 | triggerMainGammaSimple = trigger; | |
291 | else if( triggerMainGammaSimple->GetPatchE() < trigger->GetPatchE() ) | |
292 | triggerMainGammaSimple = trigger; | |
293 | } | |
294 | } | |
295 | ||
4a51ca21 | 296 | // level 0 triggers |
297 | trigger = ProcessPatch(kTMEMCalLevel0, isOfflineSimple); | |
298 | ||
299 | // save main level0 trigger in the event | |
300 | if(trigger){ | |
301 | if(!triggerMainLevel0) triggerMainLevel0 = trigger; | |
302 | else if(triggerMainLevel0->GetPatchE() < trigger->GetPatchE()) triggerMainLevel0 = trigger; | |
303 | } | |
304 | ||
f9a1843e | 305 | // cout << " pi:" << trigger->GetPhiMin() << " px:" << trigger->GetPhiMax(); |
306 | // cout << " pg:" << trigger->GetPhiGeo() << " " << (trigger->GetPhiMin()+trigger->GetPhiMax()) / 2.; | |
307 | // cout << " pc:" << trigger->GetPhiCM(); | |
308 | // cout << " ei:" << trigger->GetEtaMin() << " ex:" << trigger->GetEtaMax(); | |
309 | // cout << " eg:" << trigger->GetEtaGeo() << " " << (trigger->GetEtaMin()+trigger->GetEtaMax()) / 2.; | |
310 | // cout << " ec:" << trigger->GetEtaCM(); | |
311 | // cout << " e:" << trigger->GetPatchE(); | |
312 | // cout << " jl:" << trigger->IsJetLow() << " jh:" << trigger->IsJetHigh() << endl; | |
00c77045 | 313 | |
00c77045 | 314 | } // triggers |
315 | ||
316 | // mark the most energetic patch as main | |
001765f7 | 317 | // for real and also simple offline |
f9a1843e | 318 | if( triggerMainJet != 0 ){ |
319 | tBits = triggerMainJet->GetTriggerBits(); | |
320 | // main trigger flag | |
321 | tBits = tBits | ( 1 << 24 ); | |
322 | triggerMainJet->SetTriggerBits( tBits ); | |
323 | } | |
324 | if( triggerMainJetSimple != 0 ){ | |
325 | tBits = triggerMainJetSimple->GetTriggerBits(); | |
00c77045 | 326 | // main trigger flag |
327 | tBits = tBits | ( 1 << 24 ); | |
f9a1843e | 328 | triggerMainJetSimple->SetTriggerBits( tBits ); |
00c77045 | 329 | } |
f9a1843e | 330 | if( triggerMainGamma != 0 ){ |
331 | tBits = triggerMainGamma->GetTriggerBits(); | |
001765f7 | 332 | // main trigger flag |
333 | tBits = tBits | ( 1 << 24 ); | |
f9a1843e | 334 | triggerMainGamma->SetTriggerBits( tBits ); |
335 | } | |
336 | if( triggerMainGammaSimple != 0 ){ | |
337 | tBits = triggerMainGammaSimple->GetTriggerBits(); | |
338 | // main trigger flag | |
339 | tBits = tBits | ( 1 << 24 ); | |
340 | triggerMainGammaSimple->SetTriggerBits( tBits ); | |
001765f7 | 341 | } |
4a51ca21 | 342 | if(triggerMainLevel0){ |
343 | tBits = triggerMainLevel0->GetTriggerBits(); | |
344 | // main trigger flag | |
345 | tBits |= (1 << 24); | |
346 | triggerMainLevel0->SetTriggerBits(tBits); | |
347 | } | |
00c77045 | 348 | |
349 | } // there are some triggers | |
350 | ||
351 | return kTRUE; | |
352 | } | |
001765f7 | 353 | |
f9a1843e | 354 | //________________________________________________________________________ |
4a51ca21 | 355 | AliEmcalTriggerPatchInfo* AliEmcalTriggerMaker::ProcessPatch( TriggerMakerTriggerType_t type, Bool_t isOfflineSimple ){ |
f9a1843e | 356 | |
357 | ||
8ee32bb2 | 358 | Int_t globCol, globRow, tBits, cellAbsId[4], posOffset(0); |
f9a1843e | 359 | Int_t absId, adcAmp; |
360 | Int_t i, j, k, cmCol, cmRow, cmiCellCol, cmiCellRow; | |
361 | Double_t amp, ca, cmiCol, cmiRow; | |
362 | ||
363 | TVector3 centerGeo, center1, center2, centerMass, edge1, edge2, vertex, cellCoor; | |
364 | ||
365 | AliEmcalTriggerPatchInfo *trigger; | |
366 | ||
367 | // check if jet trigger low or high | |
368 | if( ! isOfflineSimple ) | |
369 | fCaloTriggers->GetTriggerBits( tBits ); | |
370 | else | |
371 | fSimpleOfflineTriggers->GetTriggerBits( tBits ); | |
372 | ||
4a51ca21 | 373 | if(( type == kTMEMCalJet && ! IsEJE( tBits )) || ( type == kTMEMCalGamma && ! IsEGA( tBits )) || (type == kTMEMCalLevel0 && !IsLevel0(tBits))) |
f9a1843e | 374 | return 0; |
375 | ||
376 | // save primary vertex in vector | |
377 | vertex.SetXYZ( fVertex[0], fVertex[1], fVertex[2] ); | |
378 | ||
379 | // get position in global 2x2 tower coordinates | |
380 | // A0 left bottom (0,0) | |
381 | if( ! isOfflineSimple ) | |
382 | fCaloTriggers->GetPosition( globCol, globRow ); | |
383 | else | |
384 | fSimpleOfflineTriggers->GetPosition( globCol, globRow ); | |
385 | ||
386 | // get the absolute trigger ID | |
387 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol, globRow, absId ); | |
388 | // convert to the 4 absId of the cells composing the trigger channel | |
389 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
390 | ||
391 | // get low left edge (eta max, phi min) | |
392 | fGeom->GetGlobal( cellAbsId[0], edge1 ); | |
393 | ||
394 | // sum the available energy in the 32/32 window of cells | |
395 | // step over trigger channels and get all the corresponding cells | |
396 | // make CM | |
397 | amp = 0; | |
398 | cmiCol = 0; | |
399 | cmiRow = 0; | |
400 | adcAmp = 0; | |
4a51ca21 | 401 | if( IsEJE( tBits ) && type == kTMEMCalJet ){ |
f9a1843e | 402 | for( i = 0; i < 16; i++ ){ |
403 | for( j = 0; j < 16; j++ ){ | |
404 | // get the 4 cells composing the trigger channel | |
405 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId ); | |
406 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
407 | // add amplitudes and find patch edges | |
408 | for( k = 0; k < 4; k++ ){ | |
409 | ca = fCaloCells->GetCellAmplitude( cellAbsId[k] ); | |
410 | fGeom->GetGlobal( cellAbsId[k], cellCoor ); | |
411 | amp += ca; | |
412 | cmiCol += ca*(Double_t)i; | |
413 | cmiRow += ca*(Double_t)j; | |
414 | } | |
415 | // add the STU ADCs in the patch | |
416 | if( ! isOfflineSimple ) | |
417 | adcAmp += fPatchADC[globCol+i][globRow+j]; | |
418 | else | |
419 | adcAmp += fPatchADCSimple[globCol+i][globRow+j]; | |
420 | } | |
421 | } // 32x32 cell window | |
422 | } | |
423 | ||
4a51ca21 | 424 | if( (IsEGA( tBits ) && type == kTMEMCalGamma) || (IsLevel0( tBits ) && type == kTMEMCalLevel0)){ |
f9a1843e | 425 | for( i = 0; i < 2; i++ ){ |
426 | for( j = 0; j < 2; j++ ){ | |
427 | // get the 4 cells composing the trigger channel | |
428 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+i, globRow+j, absId ); | |
429 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
430 | // add amplitudes and find patch edges | |
431 | for( k = 0; k < 4; k++ ){ | |
432 | ca = fCaloCells->GetCellAmplitude( cellAbsId[k] ); | |
433 | fGeom->GetGlobal( cellAbsId[k], cellCoor ); | |
434 | amp += ca; | |
435 | cmiCol += ca*(Double_t)i; | |
436 | cmiRow += ca*(Double_t)j; | |
437 | } | |
438 | // add the STU ADCs in the patch | |
439 | if( ! isOfflineSimple ) | |
440 | adcAmp += fPatchADC[globCol+i][globRow+j]; | |
441 | else | |
442 | adcAmp += fPatchADCSimple[globCol+i][globRow+j]; | |
443 | } | |
444 | } // 4x4 cell window | |
445 | } | |
4a51ca21 | 446 | |
f9a1843e | 447 | if( amp == 0 ){ |
448 | AliDebug(2,"EMCal trigger patch with 0 energy."); | |
449 | return 0; | |
450 | } | |
451 | ||
452 | // get the CM and patch index | |
453 | cmiCol /= amp; | |
454 | cmiRow /= amp; | |
455 | cmCol = globCol + (Int_t)cmiCol; | |
456 | cmRow = globRow + (Int_t)cmiRow; | |
457 | ||
458 | // get the patch and corresponding cells | |
459 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( cmCol, cmRow, absId ); | |
460 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
461 | ||
462 | // find which out of the 4 cells is closest to CM and get it's position | |
463 | cmiCellCol = TMath::Nint( cmiCol * 2. ); | |
464 | cmiCellRow = TMath::Nint( cmiRow * 2. ); | |
465 | fGeom->GetGlobal( cellAbsId[(cmiCellRow%2)*2 + cmiCellCol%2], centerMass ); | |
466 | ||
467 | // get up right edge (eta min, phi max) | |
468 | // get the absolute trigger ID | |
4a51ca21 | 469 | switch(type){ |
470 | case kTMEMCalJet: | |
471 | posOffset = 15; | |
472 | break; | |
473 | case kTMEMCalGamma: | |
474 | posOffset = 1; | |
475 | break; | |
476 | case kTMEMCalLevel0: | |
477 | posOffset = 1; | |
478 | break; | |
8ee32bb2 | 479 | default: |
480 | posOffset = 0; | |
481 | break; | |
4a51ca21 | 482 | }; |
483 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+posOffset, globRow+posOffset, absId ); | |
f9a1843e | 484 | // convert to the 4 absId of the cells composing the trigger channel |
485 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
486 | ||
487 | fGeom->GetGlobal( cellAbsId[3], edge2 ); | |
488 | ||
489 | // get the geometrical center as an average of two diagonally | |
490 | // adjacent patches in the center | |
491 | // picking two diagonally closest cells from the patches | |
4a51ca21 | 492 | switch(type){ |
493 | case kTMEMCalJet: | |
494 | posOffset = 7; | |
495 | break; | |
496 | case kTMEMCalGamma: | |
497 | posOffset = 0; | |
498 | break; | |
499 | case kTMEMCalLevel0: | |
500 | posOffset = 0; | |
501 | break; | |
8ee32bb2 | 502 | default: |
503 | posOffset = 0; | |
504 | break; | |
4a51ca21 | 505 | }; |
506 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+posOffset, globRow+posOffset, absId ); | |
507 | ||
f9a1843e | 508 | |
509 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
510 | fGeom->GetGlobal( cellAbsId[3], center1 ); | |
511 | ||
4a51ca21 | 512 | switch(type){ |
513 | case kTMEMCalJet: | |
514 | posOffset = 8; | |
515 | break; | |
516 | case kTMEMCalGamma: | |
517 | posOffset = 1; | |
518 | break; | |
519 | case kTMEMCalLevel0: | |
520 | posOffset = 1; | |
521 | break; | |
522 | }; | |
523 | fGeom->GetAbsFastORIndexFromPositionInEMCAL( globCol+posOffset, globRow+posOffset, absId ); | |
f9a1843e | 524 | |
525 | fGeom->GetCellIndexFromFastORIndex( absId, cellAbsId ); | |
526 | fGeom->GetGlobal( cellAbsId[0], center2 ); | |
527 | ||
528 | centerGeo = center1; | |
529 | centerGeo += center2; | |
530 | centerGeo *= 0.5; | |
531 | ||
532 | // relate all to primary vertex | |
533 | centerGeo -= vertex; | |
534 | centerMass -= vertex; | |
535 | edge1 -= vertex; | |
536 | edge2 -= vertex; | |
537 | ||
538 | // fix tbits .. remove the unwanted type triggers | |
4a51ca21 | 539 | // for Jet and Gamma triggers we remove also the level 0 bit since it will be stored in the level 0 patch |
540 | // for level 0 we remove all gamma and jet trigger bits | |
541 | switch(type){ | |
542 | case kTMEMCalJet: | |
543 | tBits = tBits & ~( 1 << (kTriggerTypeEnd + kL1GammaLow) | 1 << (kTriggerTypeEnd + kL1GammaHigh) | 1 << (kL1GammaLow) | 1 << (kL1GammaHigh) | | |
544 | 1 << (kTriggerTypeEnd + kL0) | 1 << (kL0)); | |
545 | break; | |
546 | case kTMEMCalGamma: | |
547 | tBits = tBits & ~( 1 << (kTriggerTypeEnd + kL1JetLow) | 1 << (kTriggerTypeEnd + kL1JetHigh) | 1 << (kL1JetLow) | 1 << (kL1JetHigh) | | |
548 | 1 << (kTriggerTypeEnd + kL0) | 1 << (kL0)); | |
549 | break; | |
550 | case kTMEMCalLevel0: | |
551 | tBits = tBits & ~( 1 << (kTriggerTypeEnd + kL1JetLow) | 1 << (kTriggerTypeEnd + kL1JetHigh) | 1 << (kL1JetLow) | 1 << (kL1JetHigh) | | |
552 | 1 << (kTriggerTypeEnd + kL1GammaLow) | 1 << (kTriggerTypeEnd + kL1GammaHigh) | 1 << (kL1GammaLow) | 1 << (kL1GammaHigh)); | |
553 | break; | |
554 | }; | |
f9a1843e | 555 | |
556 | // save the trigger object | |
557 | new ((*fCaloTriggersOut)[fITrigger])AliEmcalTriggerPatchInfo(); | |
558 | trigger = (AliEmcalTriggerPatchInfo*)fCaloTriggersOut->At( fITrigger ); | |
559 | fITrigger++; | |
560 | ||
f63def67 | 561 | Int_t isMC = MCEvent() ? 1 : 0; |
562 | Int_t offSet = (1 - isMC) * kTriggerTypeEnd; | |
563 | ||
f9a1843e | 564 | trigger->SetCenterGeo( centerGeo, amp ); |
565 | trigger->SetCenterMass( centerMass, amp ); | |
566 | trigger->SetEdge1( edge1, amp ); | |
567 | trigger->SetEdge2( edge2, amp ); | |
568 | trigger->SetADCAmp( adcAmp ); | |
569 | trigger->SetTriggerBits( tBits ); | |
f63def67 | 570 | trigger->SetOffSet(offSet); |
f9a1843e | 571 | trigger->SetEdgeCell( globCol*2, globRow*2 ); // from triggers to cells |
572 | ||
573 | return trigger; | |
574 | ||
575 | } | |
576 | ||
577 | ||
001765f7 | 578 | //________________________________________________________________________ |
579 | void AliEmcalTriggerMaker::RunSimpleOfflineTrigger() | |
580 | { | |
581 | // runs simple offline trigger algorithm | |
f9a1843e | 582 | |
583 | // it creates separate patches for jet and gamma triggers | |
584 | // on the same positions (different from STU reconstruction behavior) | |
585 | // TODO:: change to merge | |
001765f7 | 586 | |
587 | Int_t i, j, k, l, tBits, tSum; | |
588 | TArrayI tBitsArray, rowArray, colArray; | |
589 | ||
590 | // 0 thresholds = no processing | |
591 | if( fCaloTriggerSetupOut->GetThresholdJetLowSimple() == 0 && | |
592 | fCaloTriggerSetupOut->GetThresholdJetHighSimple() == 0 ) | |
593 | return; | |
594 | ||
595 | // run the trigger algo, stepping by 8 towers (= 4 trigger channels) | |
596 | for( i = 0; i < 32; i += 4 ){ | |
597 | for( j = 0; j < 48; j += 4 ){ | |
598 | ||
599 | tSum = 0; | |
600 | tBits = 0; | |
601 | ||
602 | // window | |
603 | for( k = 0; k < 16; k++ ) | |
604 | for( l = 0; l < 16; l++ ) | |
605 | tSum += (ULong64_t)fPatchADCSimple[i+k][j+l]; | |
606 | ||
607 | // check thresholds | |
608 | if( tSum > fCaloTriggerSetupOut->GetThresholdJetLowSimple() ) | |
f9a1843e | 609 | tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1JetLow )); |
001765f7 | 610 | if( tSum > fCaloTriggerSetupOut->GetThresholdJetHighSimple() ) |
f9a1843e | 611 | tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1JetHigh )); |
001765f7 | 612 | |
613 | // add trigger values | |
614 | if( tBits != 0 ){ | |
615 | // add offline bit | |
616 | tBits = tBits | ( 1 << 25 ); | |
617 | ||
618 | tBitsArray.Set( tBitsArray.GetSize() + 1 ); | |
619 | colArray.Set( colArray.GetSize() + 1 ); | |
620 | rowArray.Set( rowArray.GetSize() + 1 ); | |
621 | ||
622 | tBitsArray[tBitsArray.GetSize()-1] = tBits; | |
623 | colArray[colArray.GetSize()-1] = i; | |
624 | rowArray[rowArray.GetSize()-1] = j; | |
625 | } | |
626 | } | |
627 | } // trigger algo | |
628 | ||
f9a1843e | 629 | // 4x4 trigger algo, stepping by 2 towers (= 1 trigger channel) |
630 | for( i = 0; i < 46; i ++ ){ | |
631 | for( j = 0; j < 62; j ++ ){ | |
632 | ||
633 | tSum = 0; | |
634 | tBits = 0; | |
635 | ||
636 | // window | |
637 | for( k = 0; k < 2; k++ ) | |
638 | for( l = 0; l < 2; l++ ) | |
639 | tSum += (ULong64_t)fPatchADCSimple[i+k][j+l]; | |
640 | ||
641 | // check thresholds | |
642 | if( tSum > fCaloTriggerSetupOut->GetThresholdGammaLowSimple() ) | |
643 | tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1GammaLow )); | |
644 | if( tSum > fCaloTriggerSetupOut->GetThresholdGammaHighSimple() ) | |
645 | tBits = tBits | ( 1 << ( kTriggerTypeEnd + kL1GammaHigh )); | |
646 | ||
647 | // add trigger values | |
648 | if( tBits != 0 ){ | |
649 | // add offline bit | |
650 | tBits = tBits | ( 1 << 25 ); | |
651 | ||
652 | tBitsArray.Set( tBitsArray.GetSize() + 1 ); | |
653 | colArray.Set( colArray.GetSize() + 1 ); | |
654 | rowArray.Set( rowArray.GetSize() + 1 ); | |
655 | ||
656 | tBitsArray[tBitsArray.GetSize()-1] = tBits; | |
657 | colArray[colArray.GetSize()-1] = i; | |
658 | rowArray[rowArray.GetSize()-1] = j; | |
659 | } | |
660 | } | |
661 | } // trigger algo | |
662 | ||
663 | ||
001765f7 | 664 | // save in object |
665 | fSimpleOfflineTriggers->DeAllocate(); | |
666 | fSimpleOfflineTriggers->Allocate( tBitsArray.GetSize() ); | |
667 | ||
668 | for( i = 0; i < tBitsArray.GetSize(); i++ ){ | |
669 | fSimpleOfflineTriggers->Add( colArray[i], rowArray[i], 0, 0, 0, 0, 0, tBitsArray[i] ); | |
670 | } | |
671 | ||
672 | } | |
673 | ||
674 | //________________________________________________________________________ | |
675 | Bool_t AliEmcalTriggerMaker::NextTrigger( Bool_t &isOfflineSimple ) | |
676 | { | |
677 | // get next trigger | |
678 | ||
679 | Bool_t loopContinue; | |
680 | ||
681 | loopContinue = fCaloTriggers->Next(); | |
682 | isOfflineSimple = kFALSE; | |
683 | ||
684 | if( ! loopContinue ){ | |
685 | loopContinue = fSimpleOfflineTriggers->Next(); | |
686 | isOfflineSimple = kTRUE; | |
687 | } | |
688 | ||
689 | return loopContinue; | |
690 | } |