1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 EMCal trigger electronics manager L0/L1
20 can handle both simulated digits and raw data
21 Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
24 #include "AliEMCALTriggerElectronics.h"
25 #include "AliEMCALTriggerTRU.h"
26 #include "AliEMCALTriggerSTU.h"
27 #include "AliEMCALGeometry.h"
28 #include "AliRunLoader.h"
31 #include "AliEMCALTriggerDCSConfig.h"
32 #include "AliEMCALTriggerData.h"
33 #include "AliEMCALDigit.h"
34 #include "AliCaloRawStreamV3.h"
35 #include "AliEMCALTriggerSTURawStream.h"
36 #include "AliEMCALDigit.h"
37 #include "AliEMCALTriggerRawDigit.h"
38 #include "AliEMCALTriggerPatch.h"
39 #include "AliEMCALTriggerSTUDCSConfig.h"
45 const Int_t kNTRU = 32; // TODO: kNTRU should be set to / replaced by fGeometry->GetNTotalTRU() (total number of TRU for a given geom) after adding 1 STU for DCAL
48 ClassImp(AliEMCALTriggerElectronics)
51 AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(const AliEMCALTriggerDCSConfig *dcsConf) : TObject(),
52 fTRU(new TClonesArray("AliEMCALTriggerTRU",32)),
62 AliRunLoader *rl = AliRunLoader::Instance();
63 if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) {
64 AliEMCAL *emcal = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"));
65 if (emcal) fGeometry = emcal->GetGeometry();
69 fGeometry = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName());
70 AliError("Cannot access geometry, create a new default one!");
74 for (Int_t i = 0; i < kNTRU; i++) {
75 if(i>=(fGeometry->GetNTotalTRU())) continue; // i <= kNTRU < 62. Prevents fTRU to go out of bonds with EMCALFirstYEARV1 of EMCALCompleteV1 (NTRU<32) TODO: fix the logic
76 AliEMCALTriggerTRUDCSConfig *truConf = dcsConf->GetTRUDCSConfig(fGeometry->GetOnlineIndexFromTRUIndex(i));
77 if (truConf) new ((*fTRU)[i]) AliEMCALTriggerTRU(truConf, rSize, i % 2);
80 rSize.Set( 48., 64. );
83 AliEMCALTriggerSTUDCSConfig* stuConf = dcsConf->GetSTUDCSConfig();
84 fSTU = new AliEMCALTriggerSTU(stuConf, rSize);
87 for (Int_t i = 0; i < kNTRU; i++) {
88 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
100 AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics()
109 void AliEMCALTriggerElectronics::Digits2Trigger(TClonesArray* digits, const Int_t V0M[], AliEMCALTriggerData* data)
113 Int_t pos, px, py, id;
115 Int_t region[48][64], posMap[48][64];
116 for (Int_t i = 0; i < 48; i++) for (Int_t j = 0; j < 64; j++)
122 for (Int_t i = 0; i < digits->GetEntriesFast(); i++)
124 AliEMCALTriggerRawDigit* digit = (AliEMCALTriggerRawDigit*)digits->At(i);
130 Bool_t isOK1 = fGeometry->GetTRUFromAbsFastORIndex(id, iTRU, iADC);
132 if (!isOK1) continue;
134 for (Int_t j = 0; j < digit->GetNSamples(); j++)
137 Bool_t isOK2 = digit->GetTimeSample(j, time, amp);
139 if (isOK1 && isOK2 && amp) {
140 AliDebug(999, Form("=== TRU# %2d ADC# %2d time# %2d signal %d ===", iTRU, iADC, time, amp));
141 if(iTRU>32) continue; // kNTRU < iTRU < 62. Prevents fTRU to go out of bonds with DCAL TODO: add STU for DCAL and fix the logic
142 AliEMCALTriggerTRU * etr = (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)));
145 etr->SetADC(iADC, time, 4 * amp);
147 etr->SetADC(iADC, time, amp);
152 if (fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i;
157 Int_t timeL0[kNTRU] = {0}, timeL0min = 999;
159 for (Int_t i = 0; i < kNTRU; i++)
161 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
164 AliDebug(999, Form("===========< TRU %2d >============", i));
166 if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO
170 timeL0[i] = iTRU->GetL0Time();
172 if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i));
174 if (timeL0[i] < timeL0min) timeL0min = timeL0[i];
176 data->SetL0Trigger(0, i, 1); // TRU# i has issued a L0
179 data->SetL0Trigger(0, i, 0);
182 AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d", iL0, fTRU->GetEntriesFast(), timeL0min));
184 AliEMCALTriggerRawDigit* dig = 0x0;
186 if (iL0 && (!data->GetMode() || !fSTU->GetDCSConfig()->GetRawData()))
188 // Update digits after L0 calculation
189 for (Int_t i = 0; i < kNTRU; i++)
191 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
195 for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0;
197 iTRU->GetL0Region(timeL0min, reg);
199 for (int j = 0; j < iTRU->RegionSize()->X(); j++)
201 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
205 fGeometry->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
207 fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
209 pos = posMap[px][py];
214 posMap[px][py] = digits->GetEntriesFast();
216 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
218 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
222 dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
225 // 14b to 12b STU time sums
228 dig->SetL1TimeSum(reg[j][k]);
235 if (iL0 && !data->GetMode())
237 for (Int_t i = 0; i < kNTRU; i++)
239 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
242 AliDebug(999, Form("=== TRU# %2d found %d patches", i, (iTRU->Patches()).GetEntriesFast()));
244 TIter next(&iTRU->Patches());
245 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next())
250 if (fGeometry->GetAbsFastORIndexFromPositionInTRU(i, px, py, id)
252 fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
254 if (AliDebugLevel()) p->Print("");
256 Int_t peaks = p->Peaks();
258 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
259 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
261 for (Int_t j = 0; j < sizeX * sizeY; j++)
263 if (peaks & (1 << j))
265 pos = posMap[px + j % sizeX][py + j / sizeX];
269 posMap[px + j % sizeX][py + j / sizeX] = digits->GetEntriesFast();
271 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
273 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
275 dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
278 dig->SetL0Time(p->Time());
282 pos = posMap[px][py];
286 posMap[px][py] = digits->GetEntriesFast();
288 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
290 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
295 dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
298 dig->SetTriggerBit(kL0, 0);
303 // Prepare STU for L1 calculation
304 for (int i = 0; i < (fSTU->RegionSize())->X(); i++) {
305 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) {
311 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
313 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
318 AliDebug(999,"==================== STU ====================");
319 if (AliDebugLevel() >= 999) fSTU->Scan();
320 AliDebug(999,"==============================================");
322 fSTU->SetRegion(region);
326 for (int ithr = 0; ithr < 2; ithr++) {
327 AliDebug(999, Form(" THR %d / EGA %d / EJE %d", ithr, data->GetL1GammaThreshold(ithr), data->GetL1JetThreshold(ithr)));
329 fSTU->SetThreshold(kL1GammaHigh + ithr, data->GetL1GammaThreshold(ithr));
330 fSTU->SetThreshold(kL1JetHigh + ithr, data->GetL1JetThreshold( ithr));
335 for (int ithr = 0; ithr < 2; ithr++) {
337 fSTU->ComputeThFromV0(kL1GammaHigh + ithr, V0M);
338 data->SetL1GammaThreshold(ithr, fSTU->GetThreshold(kL1GammaHigh + ithr));
340 fSTU->ComputeThFromV0(kL1JetHigh + ithr, V0M);
341 data->SetL1JetThreshold(ithr, fSTU->GetThreshold(kL1JetHigh + ithr) );
343 AliDebug(999, Form("STU THR %d EGA %d EJE %d", ithr, fSTU->GetThreshold(kL1GammaHigh + ithr), fSTU->GetThreshold(kL1JetHigh + ithr)));
347 for (int ithr = 0; ithr < 2; ithr++) {
351 fSTU->L1(kL1GammaHigh + ithr);
355 nP = (fSTU->Patches()).MakeIterator();
357 AliDebug(999, Form("=== STU found %d gamma patches", (fSTU->Patches()).GetEntriesFast()));
359 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next())
363 if (AliDebugLevel()) p->Print("");
365 if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
367 if (posMap[px][py] == -1)
369 posMap[px][py] = digits->GetEntriesFast();
372 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
374 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
378 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);
381 if (AliDebugLevel()) dig->Print("");
383 dig->SetTriggerBit(kL1GammaHigh + ithr, 0);
389 fSTU->L1(kL1JetHigh + ithr);
391 nP = (fSTU->Patches()).MakeIterator();
393 AliDebug(999, Form("=== STU found %d jet patches", (fSTU->Patches()).GetEntriesFast()));
395 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next())
399 if (AliDebugLevel()) p->Print("");
401 if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
403 if (posMap[px][py] == -1)
405 posMap[px][py] = digits->GetEntriesFast();
408 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
410 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
414 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);
417 if (AliDebugLevel()) dig->Print("");
419 dig->SetTriggerBit(kL1JetHigh + ithr, 0);
424 // Now reset the electronics for a fresh start with next event
429 void AliEMCALTriggerElectronics::Reset()
434 while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset();