]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALTriggerElectronics.cxx
8e24bc1ef64f6e0339c684ba209bb1df21a08322
[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 = 30;
46 }
47
48 ClassImp(AliEMCALTriggerElectronics)
49
50 //__________________
51 AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(const AliEMCALTriggerDCSConfig *dcsConf) : TObject(),
52 fTRU(new TClonesArray("AliEMCALTriggerTRU",32)),
53 fSTU(0x0)
54 {
55         // Ctor
56         
57         TVector2 rSize;
58         
59         rSize.Set( 24.,  4. );
60
61         // 32 TRUs
62         for (Int_t i=0;i<kNTRU;i++) 
63         {
64                 AliEMCALTriggerTRUDCSConfig* truConf = dcsConf->GetTRUDCSConfig(i);
65                 new ((*fTRU)[i]) AliEMCALTriggerTRU(truConf, rSize, i % 2);
66         }
67         
68         rSize.Set( 48., 64. );
69         
70         // 1 STU
71         AliEMCALTriggerSTUDCSConfig* stuConf = dcsConf->GetSTUDCSConfig();
72         fSTU = new AliEMCALTriggerSTU(stuConf, rSize);
73         
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                                                                                     );
80 }
81
82 //________________
83 AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics()
84 {
85         // Dtor
86         
87         fTRU->Delete();
88         delete fSTU;
89 }
90
91 //__________________
92 void AliEMCALTriggerElectronics::Digits2Trigger(TClonesArray* digits, const Int_t V0M[], AliEMCALTriggerData* data)
93 {
94         // Digits to trigger
95
96         AliEMCALGeometry* geom = 0x0;
97         
98         AliRunLoader *rl = AliRunLoader::Instance();
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!");
107         
108         Int_t pos, px, py, id; 
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++)
118         {
119                 AliEMCALTriggerRawDigit* digit = (AliEMCALTriggerRawDigit*)digits->At(i);
120                 
121                 id = digit->GetId();
122                 
123                 Int_t iTRU, iADC;
124                 
125                 Bool_t isOK1 = geom->GetTRUFromAbsFastORIndex(id, iTRU, iADC);
126                 
127                 if ((isOK1 && iTRU >= kNTRU) || !isOK1) continue;
128
129                 for (Int_t j = 0; j < digit->GetNSamples(); j++)
130                 {
131                         Int_t time, amp;
132                         Bool_t isOK2 = digit->GetTimeSample(j, time, amp);
133                         
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                         }
142                 }
143                 
144                 if (geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i;
145         }
146
147         Int_t iL0 = 0;
148
149         Int_t timeL0[kNTRU] = {0}, timeL0min = 999;
150         
151         for (Int_t i=0; i<kNTRU; i++) 
152         {
153                 AliDebug(999, Form("===========< TRU %2d >============", i));
154                 
155                 AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
156                 
157                 if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO
158                 {
159                         iL0++;
160                         
161                         timeL0[i] = iTRU->GetL0Time();
162                         
163                         if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i));
164                         
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
173         AliDebug(999, Form("=== %2d TRU (out of %2d) has issued a L0 / Min L0 time: %d", iL0, kNTRU, timeL0min));
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];
185                         for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0;
186                                         
187                         iTRU->GetL0Region(timeL0min, reg);
188                         
189                         for (int j = 0; j < iTRU->RegionSize()->X(); j++)
190                         {
191                                 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
192                                 {
193                                         if (reg[j][k]
194                                                 && 
195                                                 geom->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
196                                                 &&
197                                                 geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
198                                         {
199                                                 pos = posMap[px][py];
200                                                                         
201                                                 if (pos == -1)
202                                                 {
203                                                         // Add a new digit
204                                                         posMap[px][py] = digits->GetEntriesFast();
205
206                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
207                                                                                 
208                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
209                                                 }
210                                                 else
211                                                 {
212                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
213                                                 }
214                                                 
215                                                 // 14b to 12b STU time sums
216                                                 reg[j][k] >>= 2; 
217                                                 
218                                                 dig->SetL1TimeSum(reg[j][k]);
219                                         }
220                                 }
221                         }
222                 }
223         }
224
225         if (iL0 && !data->GetMode())
226         {
227                 for (Int_t i = 0; i < kNTRU; i++)
228                 {
229                         AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
230                         
231                         AliDebug(999, Form("=== TRU# %2d found %d patches", i, (iTRU->Patches()).GetEntriesFast()));
232                         
233                         TIter next(&iTRU->Patches());
234                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)next())
235                         {
236                                 p->Position(px, py);
237                         
238                                 // Local 2 Global
239                                 if (geom->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) 
240                                         && 
241                                         geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
242                                 
243                                 if (AliDebugLevel()) p->Print("");
244                                 
245                                 Int_t peaks = p->Peaks();
246                                                                 
247                                 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
248                                 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
249                                         
250                                 for (Int_t j = 0; j < sizeX * sizeY; j++)
251                                 {
252                                         if (peaks & (1 << j))
253                                         {
254                                                 pos = posMap[px + j % sizeX][py + j / sizeX];
255                                                         
256                                                 if (pos == -1) {
257                                                         // Add a new digit
258                                                         posMap[px + j % sizeX][py + j / sizeX] = digits->GetEntriesFast();
259
260                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
261                                                                 
262                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);                                                       
263                                                 } else {
264                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
265                                                 }
266                                                         
267                                                 dig->SetL0Time(p->Time());
268                                         }
269                                 }
270                                         
271                                 pos = posMap[px][py];
272                                         
273                                 if (pos == -1) {
274                                         // Add a new digit
275                                         posMap[px][py] = digits->GetEntriesFast();
276
277                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
278                                                 
279                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
280                                         
281                                 }
282                                 else
283                                 {
284                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
285                                 }
286                                         
287                                 dig->SetTriggerBit(kL0, 0);
288                         }
289                 }
290         }
291         
292         // Prepare STU for L1 calculation
293         for (int i = 0; i < (fSTU->RegionSize())->X(); i++) {
294                 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++) {
295                         
296                         pos = posMap[i][j];
297                 
298                         if (pos >= 0) {
299                                 
300                                 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
301                 
302                                 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
303                         }
304                 }
305         }
306         
307         AliDebug(999,"==================== STU  ====================");
308         if (AliDebugLevel() >= 999) fSTU->Scan();
309         AliDebug(999,"==============================================");
310         
311         fSTU->SetRegion(region);
312         
313         if (data->GetMode()) 
314         {
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                 }
321         }
322         else
323         {
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                 }
334         }
335
336         for (int ithr = 0; ithr < 2; ithr++) {
337                 //
338                 fSTU->Reset();
339                 
340                 fSTU->L1(kL1GammaHigh + ithr);
341                 
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);
351                         
352                         if (AliDebugLevel()) p->Print("");
353                         
354                         if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
355                         {
356                                 if (posMap[px][py] == -1)
357                                 {
358                                         posMap[px][py] = digits->GetEntriesFast();
359                                         
360                                         // Add a new digit
361                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
362                                         
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("");
371                                 
372                                 dig->SetTriggerBit(kL1GammaHigh + ithr, 0);
373                         }
374                 }
375                 
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);
387                         
388                         if (AliDebugLevel()) p->Print("");
389                         
390                         if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
391                         {
392                                 if (posMap[px][py] == -1)
393                                 {
394                                         posMap[px][py] = digits->GetEntriesFast();
395                                         
396                                         // Add a new digit
397                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
398                                         
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("");
407                                 
408                                 dig->SetTriggerBit(kL1JetHigh + ithr, 0);
409                         }
410                 }
411         }
412         
413         // Now reset the electronics for a fresh start with next event
414         Reset();
415 }
416
417 //__________________
418 void AliEMCALTriggerElectronics::Reset()
419 {
420         // Reset
421         
422         TIter nextTRU(fTRU);
423         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)nextTRU() ) TRU->Reset();
424         
425         fSTU->Reset();
426 }