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