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