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