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