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