During simulation: fill STU region w/ non null time sums
[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) (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time, amp);
135                 }
136                 
137                 if (geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) posMap[px][py] = i;
138         }
139
140         Int_t iL0 = 0;
141
142         Int_t timeL0[kNTRU] = {0}, timeL0min = 999;
143         
144         for (Int_t i=0; i<kNTRU; i++) 
145         {
146                 AliDebug(999, Form("===========< TRU %2d >============\n", i));
147                 
148                 AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
149                 
150                 if (iTRU->L0()) // L0 recomputation: *ALWAYS* done from FALTRO
151                 {
152                         iL0++;
153                         
154                         timeL0[i] = iTRU->GetL0Time();
155                         
156                         if (!timeL0[i]) AliWarning(Form("TRU# %d has 0 trigger time",i));
157                         
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];
178                         for (int j = 0; j < 24; j++) for (int k = 0; k < 4; k++) reg[j][k] = 0;
179                                         
180                         iTRU->GetL0Region(timeL0min, reg);
181                         
182                         for (int j = 0; j < iTRU->RegionSize()->X(); j++)
183                         {
184                                 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
185                                 {
186                                         if (reg[j][k]
187                                                         && 
188                                                         geom->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
189                                                         &&
190                                                         geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
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         {
215                         // transform local to global 
216                 
217                 for (Int_t i = 0; i < kNTRU; i++)
218                 {
219                         AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
220                         
221                         TIter Next(&iTRU->Patches());
222                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)Next())
223                         {
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);
229                                 
230                                 Int_t peaks = p->Peaks();
231                                 
232                                 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
233                                 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
234                                         
235                                 for (Int_t j = 0; j < sizeX * sizeY; j++)
236                                 {
237                                         if (peaks & (1 << j))
238                                         {
239                                                 pos = posMap[px + j % sizeX][py + j / sizeX];
240                                                         
241                                                 if (pos == -1)
242                                                 {
243                                                                 // Add a new digit
244                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
245                                                                 
246                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
247                                                 }
248                                                 else
249                                                 {
250                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
251                                                 }
252                                                         
253                                                 dig->SetL0Time(timeL0min);
254                                         }
255                                 }
256                                         
257                                 pos = posMap[px][py];
258                                         
259                                 if (pos == -1)
260                                 {
261                                                 // Add a new digit
262                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
263                                                 
264                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
265                                 }
266                                 else
267                                 {
268                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
269                                 }
270                                         
271                                 dig->SetTriggerBit(kL0, 0);
272                         }
273                 }
274         }
275         
276         //
277         // Prepare STU for L1 calculation
278         
279         for (int i = 0; i < (fSTU->RegionSize())->X(); i++)
280         {
281                 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++)
282                 {
283                         pos = posMap[i][j];
284                 
285                         if (pos >= 0) 
286                         {
287                                 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
288                 
289                                 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
290                         }
291                 }
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         }
308
309         fSTU->L1(kL1Gamma);
310                 
311         TIterator* nP = 0x0;
312                 
313         nP = (fSTU->Patches()).MakeIterator();
314         
315         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
316         {                       
317                 p->Position(px, py);
318                         
319                 if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
320                 {
321                         if (posMap[px][py] == -1)
322                         {
323                                         // Add a new digit
324                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
325                                         
326                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
327                         } 
328                         else
329                         {
330                                 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);                                                             
331                         }
332                                 
333                         dig->SetTriggerBit(kL1Gamma,0);
334                 }
335         }
336
337         fSTU->Reset();
338
339         fSTU->L1(kL1Jet);
340                 
341         nP = (fSTU->Patches()).MakeIterator();
342                         
343         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
344         {                       
345                 p->Position(px, py);
346
347                 px *= (Int_t)((fSTU->SubRegionSize())->X());
348
349                 py *= (Int_t)((fSTU->SubRegionSize())->Y());
350                         
351                 if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
352                 {
353                         if (posMap[px][py] == -1)
354                         {
355                                         // Add a new digit
356                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
357                                         
358                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
359                         } 
360                         else
361                         {
362                                 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);
363                         }
364                                 
365                         dig->SetTriggerBit(kL1Jet, 0);
366                 }
367         }
368
369         if (AliDebugLevel() >= 999) data->Scan();
370         
371         // Now reset the electronics for a fresh start with next event
372         Reset();
373 }
374
375 //__________________
376 void AliEMCALTriggerElectronics::Reset()
377 {
378         // Reset
379         
380         TIter NextTRU(fTRU);
381         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)NextTRU() ) TRU->Reset();
382         
383         fSTU->Reset();
384 }