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