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