]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALTriggerElectronics.cxx
Do not create dead digits
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALTriggerElectronics.cxx
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" 
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"
40
41 #include <TVector2.h>
42
43 namespace
44 {
45         const Int_t kNTRU = 32;
46 }
47
48 ClassImp(AliEMCALTriggerElectronics)
49
50 //__________________
51 AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(const AliEMCALTriggerDCSConfig *dcsConf) : TObject(),
52 fTRU(new TClonesArray("AliEMCALTriggerTRU",32)),
53 fSTU(0x0),
54 fGeometry(0)
55 {
56         // Ctor
57         
58         TVector2 rSize;
59         
60         rSize.Set( 24.,  4. );
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         
73         // 32 TRUs
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);
77         }
78         
79         rSize.Set( 48., 64. );
80         
81         // 1 STU
82         AliEMCALTriggerSTUDCSConfig* stuConf = dcsConf->GetSTUDCSConfig();
83         fSTU = new AliEMCALTriggerSTU(stuConf, rSize);
84         
85         TString str = "map";
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         }
96 }
97
98 //________________
99 AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics()
100 {
101         // Dtor
102         
103         fTRU->Delete();
104         delete fSTU;
105 }
106
107 //__________________
108 void AliEMCALTriggerElectronics::Digits2Trigger(TClonesArray* digits, const Int_t V0M[], AliEMCALTriggerData* data)
109 {
110         // Digits to trigger
111         
112         Int_t pos, px, py, id; 
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++)
122         {
123                 AliEMCALTriggerRawDigit* digit = (AliEMCALTriggerRawDigit*)digits->At(i);
124                 
125                 id = digit->GetId();
126                 
127                 Int_t iTRU, iADC;
128                 
129                 Bool_t isOK1 = fGeometry->GetTRUFromAbsFastORIndex(id, iTRU, iADC);
130                 
131                 if (!isOK1) continue;
132
133                 for (Int_t j = 0; j < digit->GetNSamples(); j++)
134                 {
135                         Int_t time, amp;
136                         Bool_t isOK2 = digit->GetTimeSample(j, time, amp);
137                         
138                         if (isOK1 && isOK2 && amp) {
139                                 AliDebug(999, Form("=== TRU# %2d ADC# %2d time# %2d signal %d ===", iTRU, iADC, time, amp));
140                                 
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                                 }
148                         }
149                 }
150                 
151                 if (fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i;
152         }
153
154         Int_t iL0 = 0;
155
156         Int_t timeL0[kNTRU] = {0}, timeL0min = 999;
157         
158         for (Int_t i = 0; i < kNTRU; i++) 
159         {
160                 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
161                 if (!iTRU) continue;
162                 
163                 AliDebug(999, Form("===========< TRU %2d >============", i));
164                 
165                 if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO
166                 {
167                         iL0++;
168                         
169                         timeL0[i] = iTRU->GetL0Time();
170                         
171                         if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i));
172                         
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
181         AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d", iL0, fTRU->GetEntriesFast(), timeL0min));
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));
191                         if (!iTRU) continue;
192                         
193                         Int_t reg[24][4];
194                         for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0;
195                                         
196                         iTRU->GetL0Region(timeL0min, reg);
197                         
198                         for (int j = 0; j < iTRU->RegionSize()->X(); j++)
199                         {
200                                 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
201                                 {
202                                         if (reg[j][k]
203                                                 && 
204                                                 fGeometry->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
205                                                 &&
206                                                 fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
207                                         {
208                                                 pos = posMap[px][py];
209                                                                         
210                                                 if (pos == -1)
211                                                 {
212                                                         // Add a new digit
213                                                         posMap[px][py] = digits->GetEntriesFast();
214
215                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
216                                                                                 
217                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
218                                                 }
219                                                 else
220                                                 {
221                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
222                                                 }
223                                                 
224                                                 // 14b to 12b STU time sums
225                                                 reg[j][k] >>= 2; 
226                                                 
227                                                 dig->SetL1TimeSum(reg[j][k]);
228                                         }
229                                 }
230                         }
231                 }
232         }
233
234         if (iL0 && !data->GetMode())
235         {
236                 for (Int_t i = 0; i < kNTRU; i++)
237                 {
238                         AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
239                         if (!iTRU) continue;
240                         
241                         AliDebug(999, Form("=== TRU# %2d found %d patches", i, (iTRU->Patches()).GetEntriesFast()));
242                         
243                         TIter next(&iTRU->Patches());
244                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next())
245                         {
246                                 p->Position(px, py);
247                         
248                                 // Local 2 Global
249                                 if (fGeometry->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) 
250                                         && 
251                                         fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
252                                 
253                                 if (AliDebugLevel()) p->Print("");
254                                 
255                                 Int_t peaks = p->Peaks();
256                                                                 
257                                 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
258                                 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
259                                         
260                                 for (Int_t j = 0; j < sizeX * sizeY; j++)
261                                 {
262                                         if (peaks & (1 << j))
263                                         {
264                                                 pos = posMap[px + j % sizeX][py + j / sizeX];
265                                                         
266                                                 if (pos == -1) {
267                                                         // Add a new digit
268                                                         posMap[px + j % sizeX][py + j / sizeX] = digits->GetEntriesFast();
269
270                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
271                                                                 
272                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
273                                                 } else {
274                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
275                                                 }
276                                                         
277                                                 dig->SetL0Time(p->Time());
278                                         }
279                                 }
280                                         
281                                 pos = posMap[px][py];
282                                         
283                                 if (pos == -1) {
284                                         // Add a new digit
285                                         posMap[px][py] = digits->GetEntriesFast();
286
287                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
288                                                 
289                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
290                                         
291                                 }
292                                 else
293                                 {
294                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
295                                 }
296                                         
297                                 dig->SetTriggerBit(kL0, 0);
298                         }
299                 }
300         }
301         
302         // Prepare STU for L1 calculation
303         for (int i = 0; i < (fSTU->RegionSize())->X(); i++) {
304                 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) {
305                         
306                         pos = posMap[i][j];
307                 
308                         if (pos >= 0) {
309                                 
310                                 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
311                 
312                                 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
313                         }
314                 }
315         }
316         
317         AliDebug(999,"==================== STU  ====================");
318         if (AliDebugLevel() >= 999) fSTU->Scan();
319         AliDebug(999,"==============================================");
320         
321         fSTU->SetRegion(region);
322         
323         if (data->GetMode()) 
324         {
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                 }
331         }
332         else
333         {
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                 }
344         }
345
346         for (int ithr = 0; ithr < 2; ithr++) {
347                 //
348                 fSTU->Reset();
349                 
350                 fSTU->L1(kL1GammaHigh + ithr);
351                 
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);
361                         
362                         if (AliDebugLevel()) p->Print("");
363                         
364                         if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
365                         {
366                                 if (posMap[px][py] == -1)
367                                 {
368                                         posMap[px][py] = digits->GetEntriesFast();
369                                         
370                                         // Add a new digit
371                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
372                                         
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("");
381                                 
382                                 dig->SetTriggerBit(kL1GammaHigh + ithr, 0);
383                         }
384                 }
385                 
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);
397                         
398                         if (AliDebugLevel()) p->Print("");
399                         
400                         if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
401                         {
402                                 if (posMap[px][py] == -1)
403                                 {
404                                         posMap[px][py] = digits->GetEntriesFast();
405                                         
406                                         // Add a new digit
407                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
408                                         
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("");
417                                 
418                                 dig->SetTriggerBit(kL1JetHigh + ithr, 0);
419                         }
420                 }
421         }
422         
423         // Now reset the electronics for a fresh start with next event
424         Reset();
425 }
426
427 //__________________
428 void AliEMCALTriggerElectronics::Reset()
429 {
430         // Reset
431         
432         TIter nextTRU(fTRU);
433         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset();
434         
435         fSTU->Reset();
436 }