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