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