]>
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 | { | |
8cf986c8 | 45 | const Int_t kNTRU = 30; |
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 | |
de39a0ff | 134 | if (isOK1 && isOK2 && amp) (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time, amp); |
135 | } | |
136 | ||
804b828a | 137 | if (geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i; |
916f1e76 | 138 | } |
916f1e76 | 139 | |
de39a0ff | 140 | Int_t iL0 = 0; |
916f1e76 | 141 | |
804b828a | 142 | Int_t timeL0[kNTRU] = {0}, timeL0min = 999; |
143 | ||
916f1e76 | 144 | for (Int_t i=0; i<kNTRU; i++) |
145 | { | |
de39a0ff | 146 | AliDebug(999, Form("===========< TRU %2d >============\n", i)); |
916f1e76 | 147 | |
de39a0ff | 148 | AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); |
804b828a | 149 | |
150 | if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO | |
916f1e76 | 151 | { |
804b828a | 152 | iL0++; |
de39a0ff | 153 | |
804b828a | 154 | timeL0[i] = iTRU->GetL0Time(); |
de39a0ff | 155 | |
804b828a | 156 | if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i)); |
de39a0ff | 157 | |
804b828a | 158 | if (timeL0[i] < timeL0min) timeL0min = timeL0[i]; |
159 | ||
160 | data->SetL0Trigger(0, i, 1); // TRU# i has issued a L0 | |
161 | } | |
162 | else | |
163 | data->SetL0Trigger(0, i, 0); | |
164 | } | |
165 | ||
166 | AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d\n", iL0, kNTRU, timeL0min)); | |
167 | ||
168 | AliEMCALTriggerRawDigit* dig = 0x0; | |
169 | ||
170 | if (iL0 && (!data->GetMode() || !fSTU->GetDCSConfig()->GetRawData())) | |
171 | { | |
172 | // Update digits after L0 calculation | |
173 | for (Int_t i = 0; i < kNTRU; i++) | |
174 | { | |
175 | AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); | |
176 | ||
177 | Int_t reg[24][4]; | |
6fc3dfc0 | 178 | for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0; |
804b828a | 179 | |
6fc3dfc0 | 180 | iTRU->GetL0Region(timeL0min, reg); |
181 | ||
804b828a | 182 | for (int j = 0; j < iTRU->RegionSize()->X(); j++) |
183 | { | |
184 | for (int k = 0; k < iTRU->RegionSize()->Y(); k++) | |
185 | { | |
6fc3dfc0 | 186 | if (reg[j][k] |
187 | && | |
188 | geom->GetAbsFastORIndexFromPositionInTRU(i, j, k, id) | |
189 | && | |
190 | geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) | |
804b828a | 191 | { |
192 | pos = posMap[px][py]; | |
193 | ||
194 | if (pos == -1) | |
195 | { | |
196 | // Add a new digit | |
197 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); | |
198 | ||
199 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); | |
200 | } | |
201 | else | |
202 | { | |
203 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
204 | } | |
205 | ||
206 | dig->SetL1TimeSum(reg[j][k]); | |
207 | } | |
208 | } | |
209 | } | |
210 | } | |
211 | } | |
212 | ||
213 | if (iL0 && !data->GetMode()) | |
214 | { | |
de39a0ff | 215 | // transform local to global |
804b828a | 216 | |
217 | for (Int_t i = 0; i < kNTRU; i++) | |
218 | { | |
219 | AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)); | |
220 | ||
a520bcd0 | 221 | TIter next(&iTRU->Patches()); |
222 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next()) | |
de39a0ff | 223 | { |
804b828a | 224 | p->Position(px, py); |
225 | ||
226 | // Local 2 Global | |
227 | if (geom->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) && | |
228 | geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py); | |
de39a0ff | 229 | |
804b828a | 230 | Int_t peaks = p->Peaks(); |
6fc3dfc0 | 231 | |
804b828a | 232 | Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X()); |
233 | Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y()); | |
a61738e1 | 234 | |
804b828a | 235 | for (Int_t j = 0; j < sizeX * sizeY; j++) |
236 | { | |
237 | if (peaks & (1 << j)) | |
de39a0ff | 238 | { |
804b828a | 239 | pos = posMap[px + j % sizeX][py + j / sizeX]; |
de39a0ff | 240 | |
804b828a | 241 | if (pos == -1) |
242 | { | |
a61738e1 | 243 | // Add a new digit |
804b828a | 244 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
de39a0ff | 245 | |
804b828a | 246 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
247 | } | |
248 | else | |
249 | { | |
250 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
de39a0ff | 251 | } |
804b828a | 252 | |
253 | dig->SetL0Time(timeL0min); | |
a61738e1 | 254 | } |
804b828a | 255 | } |
a61738e1 | 256 | |
804b828a | 257 | pos = posMap[px][py]; |
a61738e1 | 258 | |
804b828a | 259 | if (pos == -1) |
260 | { | |
a61738e1 | 261 | // Add a new digit |
804b828a | 262 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 263 | |
804b828a | 264 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
265 | } | |
266 | else | |
267 | { | |
268 | dig = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
de39a0ff | 269 | } |
804b828a | 270 | |
271 | dig->SetTriggerBit(kL0, 0); | |
de39a0ff | 272 | } |
de39a0ff | 273 | } |
916f1e76 | 274 | } |
804b828a | 275 | |
276 | // | |
277 | // Prepare STU for L1 calculation | |
278 | ||
279 | for (int i = 0; i < (fSTU->RegionSize())->X(); i++) | |
916f1e76 | 280 | { |
804b828a | 281 | for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) |
de39a0ff | 282 | { |
804b828a | 283 | pos = posMap[i][j]; |
916f1e76 | 284 | |
804b828a | 285 | if (pos >= 0) |
286 | { | |
287 | AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos); | |
288 | ||
289 | if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum(); | |
290 | } | |
de39a0ff | 291 | } |
804b828a | 292 | } |
293 | ||
294 | fSTU->SetRegion(region); | |
295 | ||
296 | if (data->GetMode()) | |
297 | { | |
298 | fSTU->SetThreshold(kL1Gamma, data->GetL1GammaThreshold()); | |
299 | fSTU->SetThreshold(kL1Jet, data->GetL1JetThreshold() ); | |
300 | } | |
301 | else | |
302 | { | |
303 | fSTU->ComputeThFromV0(kL1Gamma, V0M); | |
304 | data->SetL1GammaThreshold( fSTU->GetThreshold(kL1Gamma)); | |
305 | fSTU->ComputeThFromV0(kL1Jet, V0M); | |
306 | data->SetL1JetThreshold( fSTU->GetThreshold(kL1Jet) ); | |
307 | } | |
916f1e76 | 308 | |
804b828a | 309 | fSTU->L1(kL1Gamma); |
a61738e1 | 310 | |
804b828a | 311 | TIterator* nP = 0x0; |
a61738e1 | 312 | |
804b828a | 313 | nP = (fSTU->Patches()).MakeIterator(); |
314 | ||
315 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) | |
316 | { | |
317 | p->Position(px, py); | |
a61738e1 | 318 | |
804b828a | 319 | if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id)) |
320 | { | |
321 | if (posMap[px][py] == -1) | |
a61738e1 | 322 | { |
a61738e1 | 323 | // Add a new digit |
804b828a | 324 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 325 | |
804b828a | 326 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
327 | } | |
328 | else | |
329 | { | |
330 | dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]); | |
a61738e1 | 331 | } |
804b828a | 332 | |
333 | dig->SetTriggerBit(kL1Gamma,0); | |
a61738e1 | 334 | } |
804b828a | 335 | } |
916f1e76 | 336 | |
804b828a | 337 | fSTU->Reset(); |
916f1e76 | 338 | |
804b828a | 339 | fSTU->L1(kL1Jet); |
916f1e76 | 340 | |
804b828a | 341 | nP = (fSTU->Patches()).MakeIterator(); |
342 | ||
343 | while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) | |
344 | { | |
345 | p->Position(px, py); | |
a61738e1 | 346 | |
804b828a | 347 | px *= (Int_t)((fSTU->SubRegionSize())->X()); |
a61738e1 | 348 | |
804b828a | 349 | py *= (Int_t)((fSTU->SubRegionSize())->Y()); |
a61738e1 | 350 | |
804b828a | 351 | if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id)) |
352 | { | |
353 | if (posMap[px][py] == -1) | |
a61738e1 | 354 | { |
a61738e1 | 355 | // Add a new digit |
804b828a | 356 | new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0); |
a61738e1 | 357 | |
804b828a | 358 | dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1); |
359 | } | |
360 | else | |
de39a0ff | 361 | { |
804b828a | 362 | dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]); |
de39a0ff | 363 | } |
804b828a | 364 | |
365 | dig->SetTriggerBit(kL1Jet, 0); | |
de39a0ff | 366 | } |
916f1e76 | 367 | } |
368 | ||
de39a0ff | 369 | if (AliDebugLevel() >= 999) data->Scan(); |
39c05eac | 370 | |
916f1e76 | 371 | // Now reset the electronics for a fresh start with next event |
372 | Reset(); | |
373 | } | |
374 | ||
375 | //__________________ | |
376 | void AliEMCALTriggerElectronics::Reset() | |
377 | { | |
79b05051 | 378 | // Reset |
379 | ||
a520bcd0 | 380 | TIter nextTRU(fTRU); |
381 | while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset(); | |
916f1e76 | 382 | |
383 | fSTU->Reset(); | |
384 | } |