Solve RuleChecker violations
[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
40 #include <TVector2.h>
41
42 namespace
43 {
44         const Int_t kNTRU = 30;
45 }
46
47 ClassImp(AliEMCALTriggerElectronics)
48
49 //__________________
50 AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(const AliEMCALTriggerDCSConfig *dcsConf) : TObject(),
51 fTRU(new TClonesArray("AliEMCALTriggerTRU",32)),
52 fSTU(0x0)
53 {
54         // Ctor
55         
56         TVector2 rSize;
57         
58         rSize.Set( 24.,  4. );
59
60         // 32 TRUs
61         for (Int_t i=0;i<kNTRU;i++) 
62         {
63                 AliEMCALTriggerTRUDCSConfig* truConf = dcsConf->GetTRUDCSConfig(i);
64                 new ((*fTRU)[i]) AliEMCALTriggerTRU(truConf, rSize, i % 2);
65         }
66         
67         rSize.Set( 48., 64. );
68         
69         // 1 STU
70         AliEMCALTriggerSTUDCSConfig* stuConf = dcsConf->GetSTUDCSConfig();
71         fSTU = new AliEMCALTriggerSTU(stuConf, rSize);
72         
73         TString str = "map";
74         for (Int_t i=0;i<kNTRU;i++) fSTU->Build(str,
75                                                                                         i,
76                                                                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->Map(),
77                                                                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->RegionSize() 
78                                                                                     );
79 }
80
81 //________________
82 AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics()
83 {
84         // Dtor
85         
86         fTRU->Delete();
87         delete fSTU;
88 }
89
90 //__________________
91 void AliEMCALTriggerElectronics::Digits2Trigger(TClonesArray* digits, const Int_t V0M[], AliEMCALTriggerData* data)
92 {
93         // Digits to trigger
94         
95         AliEMCALGeometry* geom = 0x0;
96         
97         AliRunLoader *rl = AliRunLoader::Instance();
98         if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")){
99           AliEMCAL* emcal = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"));
100           if(emcal)geom = emcal->GetGeometry();
101         }
102         
103         if(!geom) geom =  AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName());
104         
105         if(!geom) AliError("Cannot access geometry!");
106         
107         //      digits->Sort();
108         
109         Int_t region[48][64], posMap[48][64];
110         for (Int_t i = 0; i < 48; i++) for (Int_t j = 0; j < 64; j++) 
111         {
112                 region[i][j] =  0;
113                 posMap[i][j] = -1;
114         }
115         
116         for (Int_t i = 0; i < digits->GetEntriesFast(); i++)
117         {
118                 AliEMCALTriggerRawDigit* digit = (AliEMCALTriggerRawDigit*)digits->At(i);
119                 
120                 Int_t id = digit->GetId();
121                 
122                 Int_t iTRU, iADC;
123                 
124                 Bool_t isOK1 = geom->GetTRUFromAbsFastORIndex(id, iTRU, iADC);
125                 
126                 if ((isOK1 && iTRU >= kNTRU) || !isOK1) continue;
127
128                 for (Int_t j = 0; j < digit->GetNSamples(); j++)
129                 {
130                         Int_t time, amp;
131                         Bool_t isOK2 = digit->GetTimeSample(j, time, amp);
132                         
133                         if (isOK1 && isOK2 && amp) (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time, amp);
134                 }
135                 
136                 Int_t px, py;
137                 if (geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py))
138                 {
139                         posMap[px][py] = i;
140                         
141                         if (fSTU->GetRawData() && digit->GetL1TimeSum() >= 0) 
142                         {
143                                 region[px][py] = digit->GetL1TimeSum();
144                         }
145                 }
146         }
147
148         Int_t iL0 = 0;
149
150         for (Int_t i=0; i<kNTRU; i++) 
151         {
152                 AliDebug(999, Form("===========< TRU %2d >============\n", i));
153                 
154                 AliEMCALTriggerTRU* iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
155
156                 // L0 is always computed from F-ALTRO
157                 if (iTRU->L0()) 
158                 {
159                         iL0 += iTRU->L0();
160                         
161                         Int_t sizeX = (Int_t) ((iTRU->PatchSize())->X() * (iTRU->SubRegionSize())->X());
162                         
163                         Int_t sizeY = (Int_t) ((iTRU->PatchSize())->Y() * (iTRU->SubRegionSize())->Y());
164                         
165                         // transform local to global 
166                         TIter Next(&iTRU->Patches());
167                         while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)Next())
168                         {
169                                 Int_t px, py, id; p->Position(px, py);
170                                 
171                                 if (geom->GetAbsFastORIndexFromPositionInTRU(i, px, py, id) 
172                                         && 
173                                         geom->GetPositionInEMCALFromAbsFastORIndex(id, px, py)) p->SetPosition(px, py);
174                                 
175                                 if (!data->GetMode()) // Simulation
176                                 {
177                                         Int_t peaks = p->Peaks();
178                                         
179                                         Int_t pos;
180                                         AliEMCALTriggerRawDigit* dig = 0x0;
181                                         
182                                         for (Int_t j = 0; j < sizeX * sizeY; j++)
183                                         {
184                                                 if (peaks & (1 << j))
185                                                 {
186                                                         pos = posMap[px + j % sizeX][py + j / sizeX];
187                                                         
188                                                         if (pos == -1)
189                                                         {
190                                                                 // Add a new digit
191                                                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
192                                                                 
193                                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
194                                                         }
195                                                         else
196                                                         {
197                                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
198                                                         }
199                                                         
200                                                         dig->SetL0Time(p->Time());
201                                                 }
202                                         }
203                                         
204                                         pos = posMap[px][py];
205                                         
206                                         if (pos == -1)
207                                         {
208                                                 // Add a new digit
209                                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
210                                                 
211                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
212                                         }
213                                         else
214                                         {
215                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(pos);
216                                         }
217                                         
218                                         dig->SetTriggerBit(kL0,0);
219                                 }
220                         }
221                         
222                         data->SetL0Trigger(0, i, 1);
223                 }
224                 else
225                         data->SetL0Trigger(0, i, 0);
226         }
227
228         // A L0 has been issued, run L1
229         // Depending on raw data enabled or not in STU data: L1 computation 
230         // should be done from F-ALTRO or directly on TRU time sums in STU raw data
231         if (iL0) 
232         {
233                 // Use L1 threshold from raw data when reconstructing raw data
234                 if (data->GetMode())
235                 {
236                         fSTU->SetThreshold(kL1Gamma, data->GetL1GammaThreshold());
237                         fSTU->SetThreshold(kL1Jet,   data->GetL1JetThreshold()  );                      
238                 }
239                 else
240                 {
241                         fSTU->ComputeThFromV0(V0M); // C/A
242                         data->SetL1GammaThreshold(fSTU->GetThreshold(kL1Gamma));
243                         data->SetL1JetThreshold(  fSTU->GetThreshold(kL1Jet)  );
244                 }
245                 
246                 if (fSTU->GetRawData())
247                 {
248                         // Compute L1 from STU raw data
249                         fSTU->SetRegion(region);
250                 }
251                 else
252                 {
253                         // Build STU raw data from F-ALTRO
254                         TString str = "region";
255                         for (Int_t i = 0; i < kNTRU; i++) fSTU->Build(str,
256                                                                                                                   i, 
257                                                                                                                   (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->Region(), 
258                                                                                                                   (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->RegionSize());
259                 }
260
261                 fSTU->L1(kL1Gamma);
262                 
263                 Int_t id, px, py;
264                 AliEMCALTriggerRawDigit* dig = 0x0;
265                 
266                 TIterator* nP = 0x0;
267                 
268                 nP = (fSTU->Patches()).MakeIterator();
269                 
270                 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
271                 {                       
272                         p->Position(px, py);
273                         
274                         if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
275                         {
276                                 if (posMap[px][py] == -1)
277                                 {
278                                         // Add a new digit
279                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
280                                         
281                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
282                                 } 
283                                 else
284                                 {
285                                         dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);                                                             
286                                 }
287                                 
288                                 dig->SetTriggerBit(kL1Gamma,0);
289                         }
290                 }
291
292                 fSTU->Reset();
293
294                 fSTU->L1(kL1Jet);
295                 
296                 nP = (fSTU->Patches()).MakeIterator();
297                 
298                 while (AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)nP->Next()) 
299                 {                       
300                         p->Position(px, py);
301
302                         px *= (Int_t)((fSTU->SubRegionSize())->X());
303
304                         py *= (Int_t)((fSTU->SubRegionSize())->Y());
305                         
306                         if (geom->GetAbsFastORIndexFromPositionInEMCAL(px, py, id))
307                         {
308                                 if (posMap[px][py] == -1)
309                                 {
310                                         // Add a new digit
311                                         new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
312                                         
313                                         dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
314                                 } 
315                                 else
316                                 {
317                                         dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[px][py]);                                                             
318                                 }
319                                 
320                                 dig->SetTriggerBit(kL1Jet,0);
321                         }
322                 }
323                 
324                 Int_t** reg = fSTU->Region();
325                 
326                 if (!fSTU->GetRawData())
327                 {
328                         // Update digits w/ L1 time sum
329                         // Done in raw digit maker when raw data enabled
330                         for (Int_t i = 0; i < 48; i++)
331                         {
332                                 for (Int_t j = 0; j < 64; j++)
333                                 {
334                                         if (reg[i][j])
335                                         {
336                                                 if (geom->GetAbsFastORIndexFromPositionInEMCAL(i, j, id))
337                                                 {
338                                                         if (posMap[i][j] == -1)
339                                                         {
340                                                                 // Add a new digit with L1 time sum
341                                                                 new((*digits)[digits->GetEntriesFast()]) AliEMCALTriggerRawDigit(id, 0x0, 0);
342                                                                 
343                                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(digits->GetEntriesFast() - 1);
344                                                         } 
345                                                         else
346                                                         {
347                                                                 dig = (AliEMCALTriggerRawDigit*)digits->At(posMap[i][j]);                                                               
348                                                         }
349                                                         
350                                                         dig->SetL1TimeSum(reg[i][j]);
351                                                 }
352                                         }
353                                 }
354                         }
355                 }
356         }
357
358         if (AliDebugLevel() >= 999) data->Scan();
359         
360         // Now reset the electronics for a fresh start with next event
361         Reset();
362 }
363
364 //__________________
365 void AliEMCALTriggerElectronics::Reset()
366 {
367         // Reset
368         
369         TIter NextTRU(fTRU);
370         while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)NextTRU() ) TRU->Reset();
371         
372         fSTU->Reset();
373 }