51bc3722d326c1e342f90c027cd6a42b8ad9aeaf
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerElectronics.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 /* $Id$ */
17
18 //*-- Author: Rachid Guernane (LPCCFd)
19 //*   Manager class for muon trigger electronics
20 //*   Client of trigger board classes
21 //*
22 //*
23
24 #include "AliMUONTriggerElectronics.h"
25 #include "AliMUONTriggerCrate.h"
26 #include "AliMUONTriggerCrateStore.h"
27 #include "AliMUONConstants.h"
28 #include "AliMUONLocalTriggerBoard.h"
29 #include "AliMUONRegionalTriggerBoard.h"
30 #include "AliMUONGlobalTriggerBoard.h"
31 #include "AliMUONLocalTrigger.h"
32 #include "AliMUONRegionalTrigger.h"
33 #include "AliMUONGlobalTrigger.h"
34 #include "AliMUON.h" 
35 #include "AliMUONData.h" 
36 #include "AliMUONDigit.h"
37 #include "AliMUONSegmentation.h"
38 #include "AliMUONCalibrationData.h"
39 #include "AliMUONVCalibParam.h"
40
41 #include "AliMpVSegmentation.h"
42
43 #include "AliLog.h"
44 #include "AliLoader.h"
45 #include "AliRun.h"
46
47 //#include "Riostream.h"
48 #include "TBits.h"
49 #include "TSystem.h"
50
51 ClassImp(AliMUONTriggerElectronics)
52
53 //___________________________________________
54 AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONData *Data, AliMUONCalibrationData* calibData) 
55 : TTask("AliMUONTriggerElectronics",
56         "From trigger digits to Local and Global Trigger objects"),
57   fCrates(new AliMUONTriggerCrateStore),
58   fGlobalTriggerBoard(new AliMUONGlobalTriggerBoard),
59   fMUONData(Data)
60 {
61 //* CONSTRUCTOR
62 //*
63   if (!fMUONData)
64   {  
65     AliFatal("NO MUON TRIGGER DATA");
66   }
67     
68   SetDataSource();
69   Factory(calibData);
70   LoadMasks(calibData);
71 }
72
73 //______________________________________________________________________________
74 AliMUONTriggerElectronics::AliMUONTriggerElectronics(const AliMUONTriggerElectronics& right) 
75   : TTask(right) 
76 {  
77 /// Protected copy constructor (not implemented)
78
79   AliFatal("Copy constructor not provided.");
80 }
81
82 //___________________________________________
83 AliMUONTriggerElectronics::~AliMUONTriggerElectronics()
84 {
85 //* DESTRUCTOR
86 //*
87   delete fGlobalTriggerBoard;
88   delete fCrates;
89 }
90
91 //______________________________________________________________________________
92 AliMUONTriggerElectronics& 
93 AliMUONTriggerElectronics::operator=(const AliMUONTriggerElectronics& right)
94 {
95 /// Protected assignement operator (not implemented)
96
97   // check assignement to self
98   if (this == &right) return *this;
99
100   AliFatal("Assignement operator not provided.");
101     
102   return *this;  
103 }    
104
105 //___________________________________________
106 void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData)
107 {  
108  //* BUILD ALL ELECTRONICS
109  //*
110  
111   fCrates->ReadFromFile(gSystem->ExpandPathName(fSourceFileName.Data()));
112   
113   if ( !calibData ) return;
114   
115   AliMUONTriggerLut* lut = calibData->TriggerLut();
116   
117   if (!lut) return;
118   
119   AliMUONLocalTriggerBoard* localBoard;
120   
121   fCrates->FirstLocalBoard();
122   
123   while ( (localBoard=fCrates->NextLocalBoard()) )
124   {
125     localBoard->SetLUT(lut);
126   }
127 }
128
129 //___________________________________________
130 void AliMUONTriggerElectronics::FeedM()
131 {
132 //* FILL INPUTS
133 //*
134         for (Int_t ichamber=10; ichamber<14; ichamber++) 
135         {
136       TClonesArray *muonDigits = fMUONData->Digits(ichamber);
137       Int_t ndigits = muonDigits->GetEntriesFast();
138
139       for (Int_t digit=0; digit<ndigits; digit++)
140                 {
141                         AliMUONDigit *mdig = static_cast<AliMUONDigit*>(muonDigits->UncheckedAt(digit));
142
143 //       CHECKME ! The TrackCharge is not ok with new digitizerV3 !
144 //                      for (Int_t ichg=0; ichg<10; ichg++) schg += mdig->TrackCharge(ichg);
145 //       assert(schg==mdig->Signal());
146                         Int_t schg = mdig->Signal();
147          
148 //       APPLY CONDITION ON SOFT BACKGROUND     
149                         Int_t tchg = schg - (Int_t(schg/10))*10;        
150
151                         if (schg<=10 || tchg>0) 
152                         {
153 //                              mdig->Print();
154
155                                 Int_t digitindex = digit;
156                                 Int_t detElemId  = mdig->DetElemId();
157                                 Int_t cathode    = mdig->Cathode();
158
159                                 const AliMpVSegmentation *seg = ((AliMUON*)gAlice->GetDetector("MUON"))->GetSegmentation()->GetMpSegmentation(detElemId,cathode);
160
161                                 Int_t ix = mdig->PadX(), iy = mdig->PadY();
162                                 
163                                 AliDebug(3,Form("cathode %d ix %d iy %d ",cathode,ix,iy));
164
165                                 AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
166                                 
167                                 for (Int_t i=0; i<pad.GetNofLocations(); i++) 
168                                 {
169                                         AliMpIntPair location = pad.GetLocation(i);
170                                         
171                                         Int_t nboard = location.GetFirst();
172
173                                         Int_t ibitxy = location.GetSecond();
174
175                                         AliMUONLocalTriggerBoard *b = fCrates->LocalBoard(nboard);
176
177                                         if (b) 
178                                         {
179                                                 if (cathode && b->GetSwitch(6)) ibitxy += 8;
180                                                 
181                                                 b->SetbitM(ibitxy,cathode,ichamber-10);
182                                                 
183                                                 DigitFiredCircuit(b->GetI(), cathode, ichamber, digitindex);
184                                         }
185           else
186           {
187             AliError(Form("Could not get local board number %d",b->GetNumber()));
188           }
189                                 }
190                         }                       
191                 }
192         }
193
194 // Particular case of the columns with 22 local boards (2R(L) 3R(L))   
195         AliMUONTriggerCrate *crate = 0x0; TObjArray *bs = 0x0;
196
197         char *scratess[4] = {  "2R",   "2L",   "3L",   "3R"}; 
198         char *scratesd[4] = {"2-3R", "2-3L", "2-3L", "2-3R"}; 
199         Int_t    slotf[4] = {     2,      2,     10,     10}; 
200         Int_t    slotd[4] = {     1,      1,      9,      9}; 
201
202         for (Int_t i=0; i<4; i++)
203         {
204       crate = fCrates->Crate(scratess[i]); 
205       bs = crate->Boards();
206       AliMUONLocalTriggerBoard *desybb = (AliMUONLocalTriggerBoard*)bs->At(14);
207       AliMUONLocalTriggerBoard *fromcb = (AliMUONLocalTriggerBoard*)bs->At(15);
208       AliMUONLocalTriggerBoard *desxbb = (AliMUONLocalTriggerBoard*)bs->At(16);
209
210       crate = fCrates->Crate(scratesd[i]); 
211       bs = crate->Boards();
212       AliMUONLocalTriggerBoard *frombb = (AliMUONLocalTriggerBoard*)bs->At(slotf[i]);
213       AliMUONLocalTriggerBoard *desycb = (AliMUONLocalTriggerBoard*)bs->At(slotd[i]);
214
215       UShort_t cX[2];
216
217 //    COPY X3-4 FROM BOARD  2 OF CRATE 2-3 TO BOARD 16 OF CRATE 2
218 //    COPY X3-4 FROM BOARD 10 OF CRATE 2-3 TO BOARD 16 OF CRATE 3
219       frombb->GetX34(cX); desxbb->SetX34(cX);
220
221 //    COPY X3-4 FROM BOARD 15 OF CRATE 2 TO BOARD 1 OF CRATE 2-3
222 //    COPY X3-4 FROM BOARD 15 OF CRATE 3 TO BOARD 9 OF CRATE 2-3
223       fromcb->GetX34(cX); desycb->SetX34(cX);
224
225       UShort_t cY[4];
226
227       desybb->GetY(cY); frombb->SetY(cY);
228
229       frombb->GetY(cY); desxbb->SetY(cY);
230       fromcb->GetY(cY); desycb->SetY(cY);
231         }
232
233 // FILL UP/DOWN OF CURRENT BOARD (DONE VIA J3 BUS IN REAL LIFE)
234  AliMUONTriggerCrate* cr;
235  
236  fCrates->FirstCrate();
237  
238  while ( ( cr = fCrates->NextCrate() ) )
239         {            
240                 TObjArray *boards = cr->Boards();
241                 
242                 for (Int_t j=1; j<boards->GetEntries()-1; j++)
243                 {
244                         TObject *o = boards->At(j);
245                         
246                         if (!o) break;
247                         
248                         AliMUONLocalTriggerBoard *currboard = (AliMUONLocalTriggerBoard*)o;
249                         
250                         AliMUONLocalTriggerBoard *neighbour = (AliMUONLocalTriggerBoard*)boards->At(j+1);
251                         
252                         UShort_t cXY[2][4];
253                         
254                         if (j==1) {neighbour->GetXY(cXY); currboard->SetXYU(cXY);}
255                         
256 //       LAST BOARD IN THE CRATE HAS NO UP EXCEPT FOR CRATES 2 & 3
257                         if (j<boards->GetEntries()-2)  
258                         {
259                                 AliMUONLocalTriggerBoard *nextboard = (AliMUONLocalTriggerBoard*)boards->At(j+2);
260                                 
261                                 currboard->GetXY(cXY); neighbour->SetXYD(cXY);
262                                 nextboard->GetXY(cXY); neighbour->SetXYU(cXY);
263                                 
264                                 if (j==boards->GetEntries()-3) {neighbour->GetXY(cXY); nextboard->SetXYD(cXY);}
265                         }
266                 }
267         }
268 }
269
270 //___________________________________________
271 void AliMUONTriggerElectronics::Feed(UShort_t pattern[2][4])
272 {
273   //* FILL INPUTS
274   //*
275   AliMUONTriggerCrate* cr;
276    
277    fCrates->FirstCrate();
278    
279    while ( ( cr = fCrates->NextCrate() ) )
280    {                 
281      TObjArray *boards = cr->Boards();
282      
283      for (Int_t j=1; j<boards->GetEntries(); j++)
284      {
285        TObject *o = boards->At(j);
286        
287        if (!o) break;
288        
289        AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
290        
291        board->SetXY(pattern);
292      }
293    }
294 }
295
296 //___________________________________________
297 void AliMUONTriggerElectronics::DumpOS()
298 {
299 //* DUMP IN THE OLD WAY
300 //*
301    for (Int_t i=0;i<234;i++)
302    {
303       AliMUONLocalTriggerBoard *board = fCrates->LocalBoard(i);
304
305                         if (board) board->Scan("ALL");
306    }
307 }
308
309 //___________________________________________
310 void AliMUONTriggerElectronics::Scan(Option_t *option)
311 {
312   //* SCAN
313   //*
314
315   AliMUONTriggerCrate* cr;
316   
317   fCrates->FirstCrate();
318   
319   while ( ( cr = fCrates->NextCrate() ) )
320         {                
321     TObjArray *boards = cr->Boards();
322     
323     for (Int_t j=0; j<boards->GetEntries(); j++)
324     {
325       TObject *o = boards->At(j);
326       
327       TString op = option;
328       
329       Bool_t cdtion = kFALSE;
330       
331       if (op.Contains("LOCAL"))    cdtion = o->IsA() == AliMUONLocalTriggerBoard::Class();
332       if (op.Contains("REGIONAL")) cdtion = o->IsA() == AliMUONRegionalTriggerBoard::Class();
333       if (op.Contains("GLOBAL"))   cdtion = o->IsA() == AliMUONGlobalTriggerBoard::Class();
334       
335       if (!o || !cdtion) continue;
336       
337       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
338       
339       board->Scan();
340     }
341   }
342 }
343
344 //___________________________________________
345 void AliMUONTriggerElectronics::Reset()
346 {
347   //* RESET
348   //*
349   
350    AliMUONTriggerCrate* cr;
351    
352    fCrates->FirstCrate();
353    
354    while ( ( cr = fCrates->NextCrate() ) )
355    {            
356       TObjArray *boards = cr->Boards();
357             
358       for (Int_t j=0; j<boards->GetEntries(); j++)
359       {     
360          AliMUONTriggerBoard *b = (AliMUONTriggerBoard*)boards->At(j);
361
362          if (b) b->Reset();
363       }
364    }
365 }
366
367 //_______________________________________________________________________
368 void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData)
369 {
370   // LOAD MASKS FROM CDB
371   
372
373   // SET MASKS
374   
375   AliMUONTriggerCrate* cr;
376   
377   fCrates->FirstCrate();
378   
379   Int_t irb(0);
380   
381   while ( ( cr = fCrates->NextCrate() ) )
382         {            
383     TObjArray *boards = cr->Boards();
384     
385     AliMUONRegionalTriggerBoard *regb =
386       (AliMUONRegionalTriggerBoard*)boards->At(0);
387
388     AliMUONVCalibParam* regionalBoardMasks = calibData->RegionalTriggerBoardMasks(irb);
389     
390     for ( Int_t i = 0; i < regionalBoardMasks->Size(); ++i )
391     {
392       UShort_t rmask = static_cast<UShort_t>(regionalBoardMasks->ValueAsInt(i) & 0x3F);
393       regb->Mask(i,rmask);
394     }
395     
396     for (Int_t j=1; j<boards->GetEntries(); j++)
397     {
398       AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
399       
400       Int_t cardNumber = b->GetNumber();
401       
402       if (cardNumber) // interface board are not interested
403       {
404         AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
405         for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
406         {
407           UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
408           b->Mask(i,lmask);
409         }
410       }
411     }
412     ++irb;
413   }
414   
415   AliMUONVCalibParam* globalBoardMasks = calibData->GlobalTriggerBoardMasks();
416   for ( Int_t i = 0; i < globalBoardMasks->Size(); ++i )
417   {
418     UShort_t gmask = static_cast<UShort_t>(globalBoardMasks->ValueAsInt(i) & 0xFFF);
419     fGlobalTriggerBoard->Mask(i,gmask);
420   }
421 }
422
423
424 //___________________________________________
425 void AliMUONTriggerElectronics::LocalResponse()
426 {
427   // INTERFACE BOARDS
428         struct crates_t 
429   {
430     TString name;
431     Int_t slots[5];
432     Int_t ns;
433   } crate[6];
434
435         crate[0].name = "2R";   crate[0].ns = 1; crate[0].slots[0] = 16;
436         crate[1].name = "2L";   crate[1].ns = 1; crate[1].slots[0] = 16;
437         crate[2].name = "3L";   crate[2].ns = 1; crate[2].slots[0] = 16;
438         crate[3].name = "3R";   crate[3].ns = 1; crate[3].slots[0] = 16;
439         crate[4].name = "2-3R"; crate[4].ns = 2; crate[4].slots[0] = 1;  crate[4].slots[1] = 9;
440         crate[5].name = "2-3L"; crate[5].ns = 2; crate[5].slots[0] = 1;  crate[5].slots[1] = 9; 
441         
442   AliMUONTriggerCrate* cr;
443   
444   fCrates->FirstCrate();
445   
446   while ( ( cr = fCrates->NextCrate() ) )
447         {            
448     Int_t iib = -1;
449     
450     for (Int_t icr=0; icr<6; icr++) 
451     {
452                         const char *n = (crate[icr].name).Data();
453                         
454       AliMUONTriggerCrate *dcr = fCrates->Crate(n);
455       
456       //       THIS CRATE CONTAINS AN INTERFACE BOARD
457       if ( dcr && !strcmp(cr->GetName(),dcr->GetName()) ) iib = icr;
458     }
459     
460     TObjArray *boards = cr->Boards();
461     
462     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
463     
464     UShort_t thisl[16]; for (Int_t j=0; j<16; j++) thisl[j] = 0;
465         
466     for (Int_t j=1; j<boards->GetEntries(); j++)
467     {     
468       TObject *o = boards->At(j);
469       
470       if (!o) break;
471       
472       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
473       
474       if (board) 
475       {
476         board->Response();
477                                 
478         UShort_t tmp = board->GetResponse();            
479         
480         //          CRATE CONTAINING INTERFACE BOARD
481         if ( iib>-1 ) 
482         {
483           for (Int_t iid = 0; iid<crate[iib].ns; iid++) 
484                                         {
485             if ( j == crate[iib].slots[iid] )
486                                                 {
487               if ( tmp != 0 ) 
488                 AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
489                                 board->GetName(),j,cr->GetName()));
490                                                 }
491                                         }                                       
492         }
493         
494         thisl[j-1] = tmp;
495       }
496     }
497     
498     regb->SetLocalResponse(thisl);
499   }
500 }
501
502 //___________________________________________
503 void AliMUONTriggerElectronics::RegionalResponse()
504 {
505   /// Compute the response for all regional cards.
506   AliMUONTriggerCrate* cr;
507   
508   fCrates->FirstCrate();
509   
510   while ( ( cr = fCrates->NextCrate() ) )
511         {            
512       TObjArray *boards = cr->Boards();
513
514       AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
515       
516       if (regb) 
517       {
518          regb->Response();
519       }  
520    }
521 }
522
523 //___________________________________________
524 void AliMUONTriggerElectronics::GlobalResponse()
525 {
526   /// Compute the global response
527
528   UShort_t regional[16];
529   
530   AliMUONTriggerCrate* cr;
531   
532   fCrates->FirstCrate();
533   Int_t irb(0);
534   
535   if ( !fCrates->NumberOfCrates() >= 16 ) 
536   {
537     AliFatal(Form("Something is wrong : too many crates %d",
538                   fCrates->NumberOfCrates()));
539   }
540   
541   while ( ( cr = fCrates->NextCrate() ) )
542         {            
543     AliMUONTriggerBoard* rb = 
544       static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
545     regional[irb] = rb->GetResponse();
546     ++irb;
547   }
548   
549   fGlobalTriggerBoard->SetRegionalResponse(regional);
550   fGlobalTriggerBoard->Response();
551 }
552
553 //___________________________________________
554 void AliMUONTriggerElectronics::BoardName(Int_t ix, Int_t iy, char *name)
555 {
556 //* BOARD NAME FROM PAD INFO (OLD MAPPING)
557 //*
558    TString s = (ix>0) ? "R" : "L"; 
559
560    Int_t board = iy / 16, bid[4] = {12,34,56,78}; 
561
562    ix = abs(ix);
563
564    Int_t line = ix / 10, column = ix - 10 * line;
565
566 // old scheme: line==1 is line==9
567    line -= 9; line = TMath::Abs(line); line++;
568
569    sprintf(name,"%sC%dL%dB%d", s.Data(), column, line, bid[board]);
570    
571    AliDebug(3, Form("Strip ( %d , %d ) connected to board %s ", ix, iy, name));
572 }
573
574 //___________________________________________
575 void AliMUONTriggerElectronics::BuildName(Int_t icirc, char name[20])
576 {
577 //* GET BOARD NAME FROM OLD NUMBERING
578 //*
579    const Int_t kCircuitId[234] = 
580       {
581           111,  121,  131,  141,  151,  161,  171,
582           211,  212,  221,  222,  231,  232,  241,  242,  251,  252,  261,  262,  271,
583           311,  312,  321,  322,  331,  332,  341,  342,  351,  352,  361,  362,  371,
584           411,  412,  413,  421,  422,  423,  424,  431,  432,  433,  434,  441,  442,  451,  452,  461,  462,  471,
585           521,  522,  523,  524,  531,  532,  533,  534,  541,  542,  551,  552,  561,  562,  571, 
586           611,  612,  613,  621,  622,  623,  624,  631,  632,  633,  634,  641,  642,  651,  652,  661,  662,  671,
587           711,  712,  721,  722,  731,  732,  741,  742,  751,  752,  761,  762,  771,
588           811,  812,  821,  822,  831,  832,  841,  842,  851,  852,  861,  862,  871,
589           911,  921,  931,  941,  951,  961,  971,
590          -111, -121, -131, -141, -151, -161, -171,
591          -211, -212, -221, -222, -231, -232, -241, -242, -251, -252, -261, -262, -271,
592          -311, -312, -321, -322, -331, -332, -341, -342, -351, -352, -361, -362, -371,
593          -411, -412, -413, -421, -422, -423, -424, -431, -432, -433, -434, -441, -442, -451, -452, -461, -462, -471,
594          -521, -522, -523, -524, -531, -532, -533, -534, -541, -542, -551, -552, -561, -562, -571, 
595          -611, -612, -613, -621, -622, -623, -624, -631, -632, -633, -634, -641, -642, -651, -652, -661, -662, -671,
596          -711, -712, -721, -722, -731, -732, -741, -742, -751, -752, -761, -762, -771,
597          -811, -812, -821, -822, -831, -832, -841, -842, -851, -852, -861, -862, -871,
598          -911, -921, -931, -941, -951, -961, -971 
599       };
600
601    Int_t b[4] = {12, 34, 56, 78};
602
603    Int_t code = TMath::Abs(kCircuitId[icirc]);
604
605    Int_t lL = code / 100;
606
607    Int_t cC = ( code - 100 * lL ) / 10;
608    
609    Int_t bB = code - 100 * lL - 10 * cC;
610    
611    const char *side = (kCircuitId[icirc]>0) ? "R" : "L";
612
613 // lL=1 AT TOP
614    lL -= 9; lL = abs(lL); lL++;
615
616    sprintf(name,"%sC%dL%dB%d",side,cC,lL,b[bB-1]);
617 }
618
619 //_______________________________________________________________________
620 void 
621 AliMUONTriggerElectronics::Exec(Option_t*)
622 {
623 //*
624 //*
625   Digits2Trigger();
626 }
627
628 //_______________________________________________________________________
629 void AliMUONTriggerElectronics::Trigger()
630 {
631 //*
632 //*
633    FeedM();
634    LocalResponse();
635    RegionalResponse();      
636    GlobalResponse();
637 }
638
639 //_______________________________________________________________________
640 void AliMUONTriggerElectronics::Digits2Trigger()
641 {
642   /// Main method to go from digits to trigger decision
643
644   AliMUONRegionalTrigger *pRegTrig = new AliMUONRegionalTrigger();
645
646   ClearDigitNumbers();
647   
648   fMUONData->ResetTrigger(); 
649   
650   // RUN THE FULL BEE CHAIN
651   Trigger();
652   //    DumpOS();
653         
654   AliMUONTriggerCrate* cr;
655   
656   fCrates->FirstCrate();
657   
658   while ( ( cr = fCrates->NextCrate() ) )
659   {            
660     TObjArray *boards = cr->Boards();
661
662     UInt_t regInpLpt = 0;
663     UInt_t regInpHpt = 0;
664     UShort_t localMask = 0x0;
665
666     AliMUONRegionalTriggerBoard *regBoard = (AliMUONRegionalTriggerBoard*)boards->At(0);
667
668     for (Int_t j = 1; j < boards->GetEntries(); j++)
669     {     
670       TObject *o = boards->At(j);
671       
672       if (!o) break;
673       
674       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
675       
676       if (board) 
677       {
678         //          L0 TRIGGER
679         if (board->Triggered())
680         {
681           Int_t localtr[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
682           
683           Int_t icirc = board->GetNumber();
684           
685           localtr[0] = icirc;
686           localtr[1] = board->GetStripX11();
687           localtr[2] = board->GetDev();
688           localtr[3] = board->GetStripY11();
689           
690           //             SAVE LUT OUTPUT 
691           UShort_t response = board->GetResponse();
692           localtr[4] = (response & 12) >> 2;
693           localtr[5] = (response & 48) >> 4;
694           localtr[6] = (response &  3);
695
696           // calculates regional inputs from local for the moment
697           UInt_t hPt = (response >> 4) & 0x3;
698           UInt_t lPt = (response >> 2) & 0x3;
699             
700           regInpHpt |= hPt << (30 - (j-1)*2);
701           regInpLpt |= lPt << (30 - (j-1)*2);
702           localMask |= (0x1 << (j-1)); // local mask
703
704
705           TBits rrr;
706           rrr.Set(6,&response);
707           
708           //             SAVE BIT PATTERN
709           localtr[7]  = board->GetXY(0,0);
710           localtr[8]  = board->GetXY(0,1);
711           localtr[9]  = board->GetXY(0,2);
712           localtr[10] = board->GetXY(0,3);
713           
714           localtr[11] = board->GetXY(1,0);
715           localtr[12] = board->GetXY(1,1);
716           localtr[13] = board->GetXY(1,2);
717           localtr[14] = board->GetXY(1,3);
718           
719           //             ADD A NEW LOCAL TRIGGER
720           AliMUONLocalTrigger *pLocTrig = new AliMUONLocalTrigger(localtr, fDigitNumbers[icirc]);
721           
722           fMUONData->AddLocalTrigger(*pLocTrig);  
723           delete pLocTrig;
724         }
725       }
726     }
727     pRegTrig->SetLocalOutput(regInpLpt, 0);
728     pRegTrig->SetLocalOutput(regInpHpt, 1);
729     pRegTrig->SetLocalMask(localMask);
730     pRegTrig->SetOutput((regBoard->GetResponse() >> 4) & 0xF); // to be uniformized (oct06 ?)
731
732     fMUONData->AddRegionalTrigger(*pRegTrig);  
733
734   }
735   delete pRegTrig;
736   
737   // GLOBAL TRIGGER INFORMATION: [0] -> LOW PT 
738   //                             [1] -> HIGH PT
739   //                             [2] -> ALL PT 
740   Int_t globalSinglePlus[3], globalSingleMinus[3], globalSingleUndef[3]; 
741   Int_t globalPairUnlike[3], globalPairLike[3];   
742   
743   UShort_t global = fGlobalTriggerBoard->GetResponse();
744   
745   globalPairUnlike[0] = (global &  16) >> 4;
746   globalPairUnlike[1] = (global & 256) >> 8;
747   globalPairUnlike[2] = (global &   1);
748   
749   globalPairLike[0] = (global &  32) >> 5;
750   globalPairLike[1] = (global & 512) >> 9;
751   globalPairLike[2] = (global &   2) >> 1;
752   
753   globalSinglePlus[0] = ((global &  192) >>  6) == 2;
754   globalSinglePlus[1] = ((global & 3072) >> 10) == 2;
755   globalSinglePlus[2] = ((global &   12) >>  2) == 2;
756   
757   globalSingleMinus[0] = ((global &  192) >>  6) == 1;
758   globalSingleMinus[1] = ((global & 3072) >> 10) == 1;
759   globalSingleMinus[2] = ((global &   12) >>  2) == 1;
760   
761   globalSingleUndef[0] = ((global &  192) >>  6) == 3;
762   globalSingleUndef[1] = ((global & 3072) >> 10) == 3;
763   globalSingleUndef[2] = ((global &   12) >>  2) == 3;
764   
765   AliMUONGlobalTrigger *pGloTrig = new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
766                                                             globalSingleUndef, globalPairUnlike, 
767                                                             globalPairLike);
768   
769   // ADD A LOCAL TRIGGER IN THE LIST 
770   fMUONData->AddGlobalTrigger(*pGloTrig);
771   delete pGloTrig;
772
773   // NOW RESET ELECTRONICS
774   Reset();
775 }
776
777 //_______________________________________________________________________
778 void AliMUONTriggerElectronics::ClearDigitNumbers()
779 {
780 // RESET fDigitNumbers
781         for (Int_t i=0; i<AliMUONConstants::NTriggerCircuit(); i++) fDigitNumbers[i].Set(0);
782 }
783
784 //_______________________________________________________________________
785 void AliMUONTriggerElectronics::DigitFiredCircuit(Int_t circuit, Int_t cathode,
786                                                   Int_t chamber, Int_t digit)
787 {
788 // REGISTERS THAT THE SPECIFIED DIGIT FIRED THE SPECIFIED CIRCUIT
789 // THIS DIGIT GETS ADDED TO AN ARRAY WHICH WILL BE COPIED TO
790 // AliMUONLocalTrigger WHEN SUCH AN OBJECT IS CREATED FOR EACH CIRCUIT
791         Int_t digitnumber = AliMUONLocalTrigger::EncodeDigitNumber(chamber, cathode, digit);
792         Int_t last = fDigitNumbers[circuit].GetSize();
793         fDigitNumbers[circuit].Set(last + 1);
794         fDigitNumbers[circuit][last] = digitnumber;
795 }
796