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