Fix OCDB induced problem in trigger calculation
[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                                 if (data->GetMode())
142                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time, 4 * amp);
143                                 else
144                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time,     amp);
145                         }
146                 }
147                 
148                 if (fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i;
149         }
150
151         Int_t iL0 = 0;
152
153         Int_t timeL0[kNTRU] = {0}, timeL0min = 999;
154         
155         for (Int_t i = 0; i < kNTRU; i++) 
156         {
157                 AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
158                 if (!iTRU) continue;
159                 
160                 AliDebug(999, Form("===========< TRU %2d >============", i));
161                 
162                 if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO
163                 {
164                         iL0++;
165                         
166                         timeL0[i] = iTRU->GetL0Time();
167                         
168                         if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i));
169                         
170                         if (timeL0[i] < timeL0min) timeL0min = timeL0[i];
171                         
172                         data->SetL0Trigger(0, i, 1); // TRU# i has issued a L0
173                 }
174                 else
175                         data->SetL0Trigger(0, i, 0);
176         }
177
178         AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d", iL0, fTRU->GetEntriesFast(), timeL0min));
179         
180         AliEMCALTriggerRawDigit* dig = 0x0;
181         
182         if (iL0 && (!data->GetMode() || !fSTU->GetDCSConfig()->GetRawData())) 
183         {
184                 // Update digits after L0 calculation
185                 for (Int_t i = 0; i < kNTRU; i++)
186                 {
187                         AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
188                         if (!iTRU) continue;
189                         
190                         Int_t reg[24][4];
191                         for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0;
192                                         
193                         iTRU->GetL0Region(timeL0min, reg);
194                         
195                         for (int j = 0; j < iTRU->RegionSize()->X(); j++)
196                         {
197                                 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
198                                 {
199                                         if (reg[j][k]
200                                                 && 
201                                                 fGeometry->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
202                                                 &&
203                                                 fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
204                                         {
205                                                 pos = posMap[px][py];
206                                                                         
207                                                 if (pos == -1)
208                                                 {
209                                                         // Add a new digit
210                                                         posMap[px][py] = digits->GetEntriesFast();
211
212                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
213                                                                                 
214                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
215                                                 }
216                                                 else
217                                                 {
218                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
219                                                 }
220                                                 
221                                                 // 14b to 12b STU time sums
222                                                 reg[j][k] >>= 2; 
223                                                 
224                                                 dig->SetL1TimeSum(reg[j][k]);
225                                         }
226                                 }
227                         }
228                 }
229         }
230
231         if (iL0 && !data->GetMode())
232         {
233                 for (Int_t i = 0; i < kNTRU; i++)
234                 {
235                         AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
236                         if (!iTRU) continue;
237                         
238                         AliDebug(999, Form("=== TRU# %2d found %d patches", i, (iTRU->Patches()).GetEntriesFast()));
239                         
240                         TIter next(&iTRU->Patches());
241                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next())
242                         {
243                                 p->Position(px, py);
244                         
245                                 // Local 2 Global
246                                 if (fGeometry->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) 
247                                         && 
248                                         fGeometry->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
249                                 
250                                 if (AliDebugLevel()) p->Print("");
251                                 
252                                 Int_t peaks = p->Peaks();
253                                                                 
254                                 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
255                                 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
256                                         
257                                 for (Int_t j = 0; j < sizeX * sizeY; j++)
258                                 {
259                                         if (peaks & (1 << j))
260                                         {
261                                                 pos = posMap[px + j % sizeX][py + j / sizeX];
262                                                         
263                                                 if (pos == -1) {
264                                                         // Add a new digit
265                                                         posMap[px + j % sizeX][py + j / sizeX] = digits->GetEntriesFast();
266
267                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
268                                                                 
269                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
270                                                 } else {
271                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
272                                                 }
273                                                         
274                                                 dig->SetL0Time(p->Time());
275                                         }
276                                 }
277                                         
278                                 pos = posMap[px][py];
279                                         
280                                 if (pos == -1) {
281                                         // Add a new digit
282                                         posMap[px][py] = digits->GetEntriesFast();
283
284                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
285                                                 
286                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
287                                         
288                                 }
289                                 else
290                                 {
291                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
292                                 }
293                                         
294                                 dig->SetTriggerBit(kL0, 0);
295                         }
296                 }
297         }
298         
299         // Prepare STU for L1 calculation
300         for (int i = 0; i < (fSTU->RegionSize())->X(); i++) {
301                 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) {
302                         
303                         pos = posMap[i][j];
304                 
305                         if (pos >= 0) {
306                                 
307                                 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
308                 
309                                 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
310                         }
311                 }
312         }
313         
314         AliDebug(999,"==================== STU  ====================");
315         if (AliDebugLevel() >= 999) fSTU->Scan();
316         AliDebug(999,"==============================================");
317         
318         fSTU->SetRegion(region);
319         
320         if (data->GetMode()) 
321         {
322                 for (int ithr = 0; ithr < 2; ithr++) {
323                         AliDebug(999, Form(" THR %d / EGA %d / EJE %d", ithr, data->GetL1GammaThreshold(ithr), data->GetL1JetThreshold(ithr)));
324                                                            
325                         fSTU->SetThreshold(kL1GammaHigh + ithr, data->GetL1GammaThreshold(ithr));
326                         fSTU->SetThreshold(kL1JetHigh + ithr, data->GetL1JetThreshold(  ithr));
327                 }
328         }
329         else
330         {
331                 for (int ithr = 0; ithr < 2; ithr++) {
332                         //
333                         fSTU->ComputeThFromV0(kL1GammaHigh + ithr, V0M); 
334                         data->SetL1GammaThreshold(ithr, fSTU->GetThreshold(kL1GammaHigh + ithr));
335                         
336                         fSTU->ComputeThFromV0(kL1JetHigh + ithr,   V0M);
337                         data->SetL1JetThreshold(ithr, fSTU->GetThreshold(kL1JetHigh + ithr)  );
338                         
339                         AliDebug(999, Form("STU THR %d EGA %d EJE %d", ithr, fSTU->GetThreshold(kL1GammaHigh + ithr), fSTU->GetThreshold(kL1JetHigh + ithr)));
340                 }
341         }
342
343         for (int ithr = 0; ithr < 2; ithr++) {
344                 //
345                 fSTU->Reset();
346                 
347                 fSTU->L1(kL1GammaHigh + ithr);
348                 
349                 TIterator* nP = 0x0;
350                 
351                 nP = (fSTU->Patches()).MakeIterator();
352                 
353                 AliDebug(999, Form("=== STU found %d gamma patches", (fSTU->Patches()).GetEntriesFast()));
354                 
355                 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
356                 {                       
357                         p->Position(px, py);
358                         
359                         if (AliDebugLevel()) p->Print("");
360                         
361                         if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
362                         {
363                                 if (posMap[px][py] == -1)
364                                 {
365                                         posMap[px][py] = digits->GetEntriesFast();
366                                         
367                                         // Add a new digit
368                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
369                                         
370                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
371                                 } 
372                                 else
373                                 {
374                                         dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);                                                             
375                                 }
376                                 
377                                 if (AliDebugLevel()) dig->Print("");
378                                 
379                                 dig->SetTriggerBit(kL1GammaHigh + ithr, 0);
380                         }
381                 }
382                 
383                 fSTU->Reset();
384                 
385                 fSTU->L1(kL1JetHigh + ithr);
386                 
387                 nP = (fSTU->Patches()).MakeIterator();
388                 
389                 AliDebug(999, Form("=== STU found %d jet patches", (fSTU->Patches()).GetEntriesFast()));
390                 
391                 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
392                 {                       
393                         p->Position(px, py);
394                         
395                         if (AliDebugLevel()) p->Print("");
396                         
397                         if (fGeometry->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
398                         {
399                                 if (posMap[px][py] == -1)
400                                 {
401                                         posMap[px][py] = digits->GetEntriesFast();
402                                         
403                                         // Add a new digit
404                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
405                                         
406                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
407                                 } 
408                                 else
409                                 {
410                                         dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);
411                                 }
412                                 
413                                 if (AliDebugLevel()) dig->Print("");
414                                 
415                                 dig->SetTriggerBit(kL1JetHigh + ithr, 0);
416                         }
417                 }
418         }
419         
420         // Now reset the electronics for a fresh start with next event
421         Reset();
422 }
423
424 //__________________
425 void AliEMCALTriggerElectronics::Reset()
426 {
427         // Reset
428         
429         TIter nextTRU(fTRU);
430         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset();
431         
432         fSTU->Reset();
433 }