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