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