51fabdc214205ce14b06784c915a9aa99789fe39
[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                         iTRU->GetL0Region(timeL0min, reg);
179                                         
180                         for (int j = 0; j < iTRU->RegionSize()->X(); j++)
181                         {
182                                 for (int k = 0; k < iTRU->RegionSize()->Y(); k++)
183                                 {
184                                         if (geom->GetAbsFastORIndexFromPositionInTRU(i, j, k, id)
185                                                                          &&
186                                                                          geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
187                                         {
188                                                 pos = posMap[px][py];
189                                                                         
190                                                 if (pos == -1)
191                                                 {
192                                                         // Add a new digit
193                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
194                                                                                 
195                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
196                                                 }
197                                                 else
198                                                 {
199                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
200                                                 }
201                                                 
202                                                 dig->SetL1TimeSum(reg[j][k]);
203                                         }
204                                 }
205                         }
206                 }
207         }
208
209         if (iL0 && !data->GetMode())
210         {
211                         // transform local to global 
212                 
213                 for (Int_t i = 0; i < kNTRU; i++)
214                 {
215                         AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
216                         
217                         TIter Next(&iTRU->Patches());
218                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)Next())
219                         {
220                                 p->Position(px, py);
221                         
222                         // Local 2 Global       
223                                 if (geom->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) && 
224                                                                 geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
225                                 
226                                 Int_t peaks = p->Peaks();
227                         
228                                 Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
229                                 Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
230                                         
231                                 for (Int_t j = 0; j < sizeX * sizeY; j++)
232                                 {
233                                         if (peaks & (1 << j))
234                                         {
235                                                 pos = posMap[px + j % sizeX][py + j / sizeX];
236                                                         
237                                                 if (pos == -1)
238                                                 {
239                                                                 // Add a new digit
240                                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
241                                                                 
242                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
243                                                 }
244                                                 else
245                                                 {
246                                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
247                                                 }
248                                                         
249                                                 dig->SetL0Time(timeL0min);
250                                         }
251                                 }
252                                         
253                                 pos = posMap[px][py];
254                                         
255                                 if (pos == -1)
256                                 {
257                                                 // Add a new digit
258                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
259                                                 
260                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
261                                 }
262                                 else
263                                 {
264                                         dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
265                                 }
266                                         
267                                 dig->SetTriggerBit(kL0, 0);
268                         }
269                 }
270         }
271         
272         //
273         // Prepare STU for L1 calculation
274         
275         for (int i = 0; i < (fSTU->RegionSize())->X(); i++)
276         {
277                 for (int j = 0; j < (fSTU->RegionSize())->Y(); j++)
278                 {
279                         pos = posMap[i][j];
280                 
281                         if (pos >= 0) 
282                         {
283                                 AliEMCALTriggerRawDigit *digit = (AliEMCALTriggerRawDigit*)digits->At(pos);
284                 
285                                 if (digit->GetL1TimeSum() > -1) region[i][j] = digit->GetL1TimeSum();
286                         }
287                 }
288         }
289         
290         fSTU->SetRegion(region);
291         
292         if (data->GetMode()) 
293         {
294                 fSTU->SetThreshold(kL1Gamma, data->GetL1GammaThreshold());
295                 fSTU->SetThreshold(kL1Jet,   data->GetL1JetThreshold()  );
296         }
297         else
298         {
299                 fSTU->ComputeThFromV0(kL1Gamma, V0M); 
300                 data->SetL1GammaThreshold( fSTU->GetThreshold(kL1Gamma));
301                 fSTU->ComputeThFromV0(kL1Jet,   V0M);
302                 data->SetL1JetThreshold(   fSTU->GetThreshold(kL1Jet)  );
303         }
304
305         fSTU->L1(kL1Gamma);
306                 
307         TIterator* nP = 0x0;
308                 
309         nP = (fSTU->Patches()).MakeIterator();
310         
311         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
312         {                       
313                 p->Position(px, py);
314                         
315                 if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
316                 {
317                         if (posMap[px][py] == -1)
318                         {
319                                         // Add a new digit
320                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
321                                         
322                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
323                         } 
324                         else
325                         {
326                                 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);                                                             
327                         }
328                                 
329                         dig->SetTriggerBit(kL1Gamma,0);
330                 }
331         }
332
333         fSTU->Reset();
334
335         fSTU->L1(kL1Jet);
336                 
337         nP = (fSTU->Patches()).MakeIterator();
338                         
339         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
340         {                       
341                 p->Position(px, py);
342
343                 px *= (Int_t)((fSTU->SubRegionSize())->X());
344
345                 py *= (Int_t)((fSTU->SubRegionSize())->Y());
346                         
347                 if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
348                 {
349                         if (posMap[px][py] == -1)
350                         {
351                                         // Add a new digit
352                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
353                                         
354                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
355                         } 
356                         else
357                         {
358                                 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);
359                         }
360                                 
361                         dig->SetTriggerBit(kL1Jet, 0);
362                 }
363         }
364
365         if (AliDebugLevel() >= 999) data->Scan();
366         
367         // Now reset the electronics for a fresh start with next event
368         Reset();
369 }
370
371 //__________________
372 void AliEMCALTriggerElectronics::Reset()
373 {
374         // Reset
375         
376         TIter NextTRU(fTRU);
377         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)NextTRU() ) TRU->Reset();
378         
379         fSTU->Reset();
380 }