]>
Commit | Line | Data |
---|---|---|
916f1e76 | 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 | /* | |
17 | ||
18 | ||
19 | EMCal trigger electronics manager L0/L1 | |
20 | can handle both simulated digits and raw data | |
21 | Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 | |
22 | */ | |
23 | ||
24 | #include "AliEMCALTriggerElectronics.h" | |
25 | #include "AliEMCALTriggerTRU.h" | |
26 | #include "AliEMCALTriggerSTU.h" | |
27 | #include "AliEMCALGeometry.h" | |
28 | #include "AliRunLoader.h" | |
29 | #include "AliEMCAL.h" | |
30 | #include "AliRun.h" | |
fff39dd1 | 31 | #include "AliEMCALTriggerDCSConfig.h" |
916f1e76 | 32 | #include "AliEMCALTriggerData.h" |
33 | #include "AliEMCALDigit.h" | |
34 | #include "AliCaloRawStreamV3.h" | |
916f1e76 | 35 | #include "AliEMCALTriggerSTURawStream.h" |
36 | #include "AliEMCALDigit.h" | |
de39a0ff | 37 | #include "AliEMCALTriggerRawDigit.h" |
38 | #include "AliEMCALTriggerPatch.h" | |
804b828a | 39 | #include "AliEMCALTriggerSTUDCSConfig.h" |
916f1e76 | 40 | |
41 | #include <TVector2.h> | |
916f1e76 | 42 | |
43 | namespace | |
44 | { | |
8cc543cb | 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 |
916f1e76 | 46 | } |
47 | ||
48 | ClassImp(AliEMCALTriggerElectronics) | |
49 | ||
50 | //__________________ | |
fff39dd1 | 51 | AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(const AliEMCALTriggerDCSConfig *dcsConf) : TObject(), |
916f1e76 | 52 | fTRU(new TClonesArray("AliEMCALTriggerTRU",32)), |
88b52ece | 53 | fSTU(0x0), |
54 | fGeometry(0) | |
916f1e76 | 55 | { |
79b05051 | 56 | // Ctor |
57 | ||
916f1e76 | 58 | TVector2 rSize; |
59 | ||
60 | rSize.Set( 24., 4. ); | |
88b52ece | 61 | |
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(); | |
66 | } | |
67 | ||
68 | if (!fGeometry) { | |
69 | fGeometry = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName()); | |
70 | AliError("Cannot access geometry, create a new default one!"); | |
71 | } | |
72 | ||
916f1e76 | 73 | // 32 TRUs |
88b52ece | 74 | for (Int_t i = 0; i < kNTRU; i++) { |
8cc543cb | 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 |
88b52ece | 76 | AliEMCALTriggerTRUDCSConfig *truConf = dcsConf->GetTRUDCSConfig(fGeometry->GetOnlineIndexFromTRUIndex(i)); |
77 | if (truConf) new ((*fTRU)[i]) AliEMCALTriggerTRU(truConf, rSize, i % 2); | |
fff39dd1 | 78 | } |
79 | ||
916f1e76 | 80 | rSize.Set( 48., 64. ); |
81 | ||
82 | // 1 STU | |
fff39dd1 | 83 | AliEMCALTriggerSTUDCSConfig* stuConf = dcsConf->GetSTUDCSConfig(); |
84 | fSTU = new AliEMCALTriggerSTU(stuConf, rSize); | |
916f1e76 | 85 | |
de39a0ff | 86 | TString str = "map"; |
88b52ece | 87 | for (Int_t i = 0; i < kNTRU; i++) { |
88 | AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); | |
89 | if (!iTRU) continue; | |
90 | ||
91 | fSTU->Build(str, | |
92 | i, | |
93 | iTRU->Map(), | |
94 | iTRU->RegionSize() | |
95 | ); | |
96 | } | |
916f1e76 | 97 | } |
98 | ||
99 | //________________ | |
100 | AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics() | |
101 | { | |
79b05051 | 102 | // Dtor |
103 | ||
916f1e76 | 104 | fTRU->Delete(); |
105 | delete fSTU; | |
106 | } | |
107 | ||
108 | //__________________ | |
de39a0ff | 109 | void AliEMCALTriggerElectronics::Digits2Trigger(TClonesArray* digits, const Int_t V0M[], AliEMCALTriggerData* data) |
916f1e76 | 110 | { |
79b05051 | 111 | // Digits to trigger |
916f1e76 | 112 | |
804b828a | 113 | Int_t pos, px, py, id; |
de39a0ff | 114 | |
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++) | |
117 | { | |
118 | region[i][j] = 0; | |
119 | posMap[i][j] = -1; | |
120 | } | |
121 | ||
122 | for (Int_t i = 0; i < digits->GetEntriesFast(); i++) | |
916f1e76 | 123 | { |
de39a0ff | 124 | AliEMCALTriggerRawDigit* digit = (AliEMCALTriggerRawDigit*)digits->At(i); |
125 | ||
804b828a | 126 | id = digit->GetId(); |
de39a0ff | 127 | |
128 | Int_t iTRU, iADC; | |
129 | ||
88b52ece | 130 | Bool_t isOK1 = fGeometry->GetTRUFromAbsFastORIndex(id, iTRU, iADC); |
de39a0ff | 131 | |
88b52ece | 132 | if (!isOK1) continue; |
c33e980f | 133 | |
de39a0ff | 134 | for (Int_t j = 0; j < digit->GetNSamples(); j++) |
916f1e76 | 135 | { |
de39a0ff | 136 | Int_t time, amp; |
137 | Bool_t isOK2 = digit->GetTimeSample(j, time, amp); | |
916f1e76 | 138 | |
63c22917 | 139 | if (isOK1 && isOK2 && amp) { |
140 | AliDebug(999, Form("=== TRU# %2d ADC# %2d time# %2d signal %d ===", iTRU, iADC, time, amp)); | |
8cc543cb | 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 |
16a1edf5 | 142 | AliEMCALTriggerTRU * etr = (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU))); |
143 | if (etr) { | |
144 | if (data->GetMode()) | |
145 | etr->SetADC(iADC, time, 4 * amp); | |
146 | else | |
147 | etr->SetADC(iADC, time, amp); | |
148 | } | |
63c22917 | 149 | } |
de39a0ff | 150 | } |
151 | ||
88b52ece | 152 | if (fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i; |
916f1e76 | 153 | } |
916f1e76 | 154 | |
de39a0ff | 155 | Int_t iL0 = 0; |
916f1e76 | 156 | |
804b828a | 157 | Int_t timeL0[kNTRU] = {0}, timeL0min = 999; |
158 | ||
88b52ece | 159 | for (Int_t i = 0; i < kNTRU; i++) |
916f1e76 | 160 | { |
88b52ece | 161 | AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); |
162 | if (!iTRU) continue; | |
916f1e76 | 163 | |
88b52ece | 164 | AliDebug(999, Form("===========< TRU %2d >============", i)); |
804b828a | 165 | |
166 | if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO | |
916f1e76 | 167 | { |
804b828a | 168 | iL0++; |
de39a0ff | 169 | |
804b828a | 170 | timeL0[i] = iTRU->GetL0Time(); |
de39a0ff | 171 | |
804b828a | 172 | if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i)); |
de39a0ff | 173 | |
804b828a | 174 | if (timeL0[i] < timeL0min) timeL0min = timeL0[i]; |
175 | ||
176 | data->SetL0Trigger(0, i, 1); // TRU# i has issued a L0 | |
177 | } | |
178 | else | |
179 | data->SetL0Trigger(0, i, 0); | |
180 | } | |
181 | ||
88b52ece | 182 | AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d", iL0, fTRU->GetEntriesFast(), timeL0min)); |
804b828a | 183 | |
184 | AliEMCALTriggerRawDigit* dig = 0x0; | |
185 | ||
186 | if (iL0 && (!data->GetMode() || !fSTU->GetDCSConfig()->GetRawData())) | |
187 | { | |
188 | // Update digits after L0 calculation | |
189 | for (Int_t i = 0; i < kNTRU; i++) | |
190 | { | |
191 | AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); | |
88b52ece | 192 | if (!iTRU) continue; |
193 | ||
804b828a | 194 | Int_t reg[24][4]; |
6fc3dfc0 | 195 | for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0; |
804b828a | 196 | |
6fc3dfc0 | 197 | iTRU->GetL0Region(timeL0min, reg); |
198 | ||
804b828a | 199 | for (int j = 0; j < iTRU->RegionSize()->X(); j++) |
200 | { | |
201 | for (int k = 0; k < iTRU->RegionSize()->Y(); k++) | |
202 | { | |
6fc3dfc0 | 203 | if (reg[j][k] |
63c22917 | 204 | && |
88b52ece | 205 | fGeometry->GetAbsFastORIndexFromPositionInTRU(i, j, k, id) |
63c22917 | 206 | && |
88b52ece | 207 | fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) |
804b828a | 208 | { |
209 | pos = posMap[px][py]; | |
210 | ||
211 | if (pos == -1) | |
212 | { | |
213 | // Add a new digit | |
63c22917 | 214 | posMap[px][py] = digits->GetEntriesFast(); |
215 | ||
804b828a | 216 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
217 | ||
63c22917 | 218 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
804b828a | 219 | } |
220 | else | |
221 | { | |
222 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
223 | } | |
224 | ||
63c22917 | 225 | // 14b to 12b STU time sums |
226 | reg[j][k] >>= 2; | |
227 | ||
804b828a | 228 | dig->SetL1TimeSum(reg[j][k]); |
229 | } | |
230 | } | |
231 | } | |
232 | } | |
233 | } | |
234 | ||
235 | if (iL0 && !data->GetMode()) | |
236 | { | |
804b828a | 237 | for (Int_t i = 0; i < kNTRU; i++) |
238 | { | |
88b52ece | 239 | AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); |
240 | if (!iTRU) continue; | |
804b828a | 241 | |
63c22917 | 242 | AliDebug(999, Form("=== TRU# %2d found %d patches", i, (iTRU->Patches()).GetEntriesFast())); |
243 | ||
a520bcd0 | 244 | TIter next(&iTRU->Patches()); |
245 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next()) | |
de39a0ff | 246 | { |
804b828a | 247 | p->Position(px, py); |
248 | ||
63c22917 | 249 | // Local 2 Global |
88b52ece | 250 | if (fGeometry->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) |
63c22917 | 251 | && |
88b52ece | 252 | fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py); |
de39a0ff | 253 | |
63c22917 | 254 | if (AliDebugLevel()) p->Print(""); |
6fc3dfc0 | 255 | |
63c22917 | 256 | Int_t peaks = p->Peaks(); |
257 | ||
804b828a | 258 | Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X()); |
259 | Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y()); | |
a61738e1 | 260 | |
804b828a | 261 | for (Int_t j = 0; j < sizeX * sizeY; j++) |
262 | { | |
263 | if (peaks & (1 << j)) | |
de39a0ff | 264 | { |
804b828a | 265 | pos = posMap[px + j % sizeX][py + j / sizeX]; |
de39a0ff | 266 | |
63c22917 | 267 | if (pos == -1) { |
268 | // Add a new digit | |
269 | posMap[px + j % sizeX][py + j / sizeX] = digits->GetEntriesFast(); | |
270 | ||
804b828a | 271 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
de39a0ff | 272 | |
63c22917 | 273 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
274 | } else { | |
804b828a | 275 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); |
de39a0ff | 276 | } |
804b828a | 277 | |
63c22917 | 278 | dig->SetL0Time(p->Time()); |
a61738e1 | 279 | } |
804b828a | 280 | } |
a61738e1 | 281 | |
804b828a | 282 | pos = posMap[px][py]; |
a61738e1 | 283 | |
63c22917 | 284 | if (pos == -1) { |
285 | // Add a new digit | |
286 | posMap[px][py] = digits->GetEntriesFast(); | |
287 | ||
804b828a | 288 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 289 | |
804b828a | 290 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
63c22917 | 291 | |
804b828a | 292 | } |
293 | else | |
294 | { | |
295 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
de39a0ff | 296 | } |
804b828a | 297 | |
298 | dig->SetTriggerBit(kL0, 0); | |
de39a0ff | 299 | } |
de39a0ff | 300 | } |
916f1e76 | 301 | } |
804b828a | 302 | |
804b828a | 303 | // Prepare STU for L1 calculation |
63c22917 | 304 | for (int i = 0; i < (fSTU->RegionSize())->X(); i++) { |
305 | for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) { | |
306 | ||
804b828a | 307 | pos = posMap[i][j]; |
916f1e76 | 308 | |
63c22917 | 309 | if (pos >= 0) { |
310 | ||
804b828a | 311 | AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos); |
312 | ||
313 | if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum(); | |
314 | } | |
de39a0ff | 315 | } |
804b828a | 316 | } |
317 | ||
63c22917 | 318 | AliDebug(999,"==================== STU ===================="); |
319 | if (AliDebugLevel() >= 999) fSTU->Scan(); | |
320 | AliDebug(999,"=============================================="); | |
321 | ||
804b828a | 322 | fSTU->SetRegion(region); |
323 | ||
324 | if (data->GetMode()) | |
325 | { | |
63c22917 | 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))); | |
328 | ||
329 | fSTU->SetThreshold(kL1GammaHigh + ithr, data->GetL1GammaThreshold(ithr)); | |
330 | fSTU->SetThreshold(kL1JetHigh + ithr, data->GetL1JetThreshold( ithr)); | |
331 | } | |
804b828a | 332 | } |
333 | else | |
334 | { | |
63c22917 | 335 | for (int ithr = 0; ithr < 2; ithr++) { |
336 | // | |
337 | fSTU->ComputeThFromV0(kL1GammaHigh + ithr, V0M); | |
338 | data->SetL1GammaThreshold(ithr, fSTU->GetThreshold(kL1GammaHigh + ithr)); | |
339 | ||
340 | fSTU->ComputeThFromV0(kL1JetHigh + ithr, V0M); | |
341 | data->SetL1JetThreshold(ithr, fSTU->GetThreshold(kL1JetHigh + ithr) ); | |
342 | ||
343 | AliDebug(999, Form("STU THR %d EGA %d EJE %d", ithr, fSTU->GetThreshold(kL1GammaHigh + ithr), fSTU->GetThreshold(kL1JetHigh + ithr))); | |
344 | } | |
804b828a | 345 | } |
916f1e76 | 346 | |
63c22917 | 347 | for (int ithr = 0; ithr < 2; ithr++) { |
348 | // | |
349 | fSTU->Reset(); | |
a61738e1 | 350 | |
63c22917 | 351 | fSTU->L1(kL1GammaHigh + ithr); |
a61738e1 | 352 | |
63c22917 | 353 | TIterator* nP = 0x0; |
354 | ||
355 | nP = (fSTU->Patches()).MakeIterator(); | |
356 | ||
357 | AliDebug(999, Form("=== STU found %d gamma patches", (fSTU->Patches()).GetEntriesFast())); | |
358 | ||
359 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) | |
360 | { | |
361 | p->Position(px, py); | |
a61738e1 | 362 | |
63c22917 | 363 | if (AliDebugLevel()) p->Print(""); |
364 | ||
88b52ece | 365 | if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id)) |
a61738e1 | 366 | { |
63c22917 | 367 | if (posMap[px][py] == -1) |
368 | { | |
369 | posMap[px][py] = digits->GetEntriesFast(); | |
370 | ||
a61738e1 | 371 | // Add a new digit |
63c22917 | 372 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 373 | |
63c22917 | 374 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
375 | } | |
376 | else | |
377 | { | |
378 | dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]); | |
379 | } | |
380 | ||
381 | if (AliDebugLevel()) dig->Print(""); | |
804b828a | 382 | |
63c22917 | 383 | dig->SetTriggerBit(kL1GammaHigh + ithr, 0); |
384 | } | |
a61738e1 | 385 | } |
916f1e76 | 386 | |
63c22917 | 387 | fSTU->Reset(); |
388 | ||
389 | fSTU->L1(kL1JetHigh + ithr); | |
390 | ||
391 | nP = (fSTU->Patches()).MakeIterator(); | |
392 | ||
393 | AliDebug(999, Form("=== STU found %d jet patches", (fSTU->Patches()).GetEntriesFast())); | |
394 | ||
395 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) | |
396 | { | |
397 | p->Position(px, py); | |
804b828a | 398 | |
63c22917 | 399 | if (AliDebugLevel()) p->Print(""); |
a61738e1 | 400 | |
88b52ece | 401 | if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id)) |
a61738e1 | 402 | { |
63c22917 | 403 | if (posMap[px][py] == -1) |
404 | { | |
405 | posMap[px][py] = digits->GetEntriesFast(); | |
406 | ||
a61738e1 | 407 | // Add a new digit |
63c22917 | 408 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 409 | |
63c22917 | 410 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
411 | } | |
412 | else | |
413 | { | |
414 | dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]); | |
415 | } | |
416 | ||
417 | if (AliDebugLevel()) dig->Print(""); | |
804b828a | 418 | |
63c22917 | 419 | dig->SetTriggerBit(kL1JetHigh + ithr, 0); |
420 | } | |
de39a0ff | 421 | } |
916f1e76 | 422 | } |
39c05eac | 423 | |
916f1e76 | 424 | // Now reset the electronics for a fresh start with next event |
425 | Reset(); | |
426 | } | |
427 | ||
428 | //__________________ | |
429 | void AliEMCALTriggerElectronics::Reset() | |
430 | { | |
79b05051 | 431 | // Reset |
432 | ||
a520bcd0 | 433 | TIter nextTRU(fTRU); |
434 | while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset(); | |
916f1e76 | 435 | |
436 | fSTU->Reset(); | |
437 | } |