bug fixed and cleaning (Christian, Philippe)
[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 "AliMUONTriggerCrateStore.h"
27 #include "AliMUONConstants.h"
28 #include "AliMUONLocalTriggerBoard.h"
29 #include "AliMUONRegionalTriggerBoard.h"
30 #include "AliMUONGlobalTriggerBoard.h"
31 #include "AliMUONLocalTrigger.h"
32 #include "AliMUONRegionalTrigger.h"
33 #include "AliMUONGlobalTrigger.h"
34 #include "AliMUON.h" 
35 #include "AliMUONData.h" 
36 #include "AliMUONDigit.h"
37 #include "AliMUONSegmentation.h"
38 #include "AliMUONCalibrationData.h"
39 #include "AliMUONVCalibParam.h"
40
41 #include "AliMpVSegmentation.h"
42
43 #include "AliLog.h"
44 #include "AliLoader.h"
45 #include "AliRun.h"
46
47 //#include "Riostream.h"
48 #include "TBits.h"
49 #include "TSystem.h"
50
51 /// \cond CLASSIMP
52 ClassImp(AliMUONTriggerElectronics)
53 /// \endcond
54
55 //___________________________________________
56 AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONData *Data, AliMUONCalibrationData* calibData) 
57 : TTask("AliMUONTriggerElectronics",
58         "From trigger digits to Local and Global Trigger objects"),
59   fSourceFileName(),
60   fCrates(new AliMUONTriggerCrateStore),
61   fGlobalTriggerBoard(new AliMUONGlobalTriggerBoard),
62   fMUONData(Data),
63   fLocalTrigger(new AliMUONLocalTrigger()),
64   fGlobalTrigger(new AliMUONGlobalTrigger())
65
66 {
67 /// CONSTRUCTOR
68 ///
69   if (!fMUONData)
70   {  
71     AliFatal("NO MUON TRIGGER DATA");
72   }
73     
74   SetDataSource();
75   Factory(calibData);
76   LoadMasks(calibData);
77 }
78
79 //___________________________________________
80 AliMUONTriggerElectronics::~AliMUONTriggerElectronics()
81 {
82 /// DESTRUCTOR
83 ///
84   delete fGlobalTriggerBoard;
85   delete fCrates;
86   delete fLocalTrigger;
87   delete fGlobalTrigger;
88
89 }
90
91 //___________________________________________
92 void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData)
93 {  
94  /// BUILD ALL ELECTRONICS
95  ///
96
97 // get coinc44 from AliMUON (added 12/09/06)
98   AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
99   Int_t coinc44 = pMUON->GetTriggerCoinc44();
100   if (coinc44 != 0 && coinc44 != 1) {
101       AliFatal("Coinc 44 should be equal to 0 or 1");
102       return;
103   }
104
105   fCrates->ReadFromFile(gSystem->ExpandPathName(fSourceFileName.Data()));
106   
107   if ( !calibData ) return;
108   
109   AliMUONTriggerLut* lut = calibData->TriggerLut();
110   
111   if (!lut) return;
112   
113   AliMUONLocalTriggerBoard* localBoard;
114   
115   fCrates->FirstLocalBoard();
116   
117   while ( (localBoard=fCrates->NextLocalBoard()) )
118   {
119     localBoard->SetLUT(lut);
120     localBoard->SetCoinc44(coinc44);
121   }
122 }
123
124 //___________________________________________
125 void AliMUONTriggerElectronics::FeedM()
126 {
127 /// FILL INPUTS
128 ///
129     for (Int_t ichamber=10; ichamber<14; ichamber++) 
130     {
131       TClonesArray *muonDigits = fMUONData->Digits(ichamber);
132       Int_t ndigits = muonDigits->GetEntriesFast();
133
134       for (Int_t digit=0; digit<ndigits; digit++)
135       {
136           AliMUONDigit *mdig = static_cast<AliMUONDigit*>(muonDigits->UncheckedAt(digit));
137
138           //       CHECKME ! The TrackCharge is not ok with new digitizerV3 !
139           //                    for (Int_t ichg=0; ichg<10; ichg++) schg += mdig->TrackCharge(ichg);
140           //       assert(schg==mdig->Signal());
141           Int_t schg = (Int_t)(mdig->Signal() + 0.5);
142          
143           //       APPLY CONDITION ON SOFT BACKGROUND   
144           Int_t tchg = schg - (Int_t(schg/10))*10;      
145
146           if (schg<=10 || tchg>0) 
147           {
148               //                                mdig->Print();
149
150               Int_t digitindex = digit;
151               Int_t detElemId  = mdig->DetElemId();
152               Int_t cathode    = mdig->Cathode();
153
154               const AliMpVSegmentation *seg = 
155                 ((AliMUON*)gAlice->GetDetector("MUON"))->GetSegmentation()->GetMpSegmentation(detElemId,cathode);
156
157               Int_t ix = mdig->PadX(), iy = mdig->PadY();
158                                 
159               AliDebug(3,Form("cathode %d ix %d iy %d ",cathode,ix,iy));
160
161               AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
162                                 
163               for (Int_t i=0; i<pad.GetNofLocations(); i++) 
164               {
165                   AliMpIntPair location = pad.GetLocation(i);
166                                         
167                   Int_t nboard = location.GetFirst();
168
169                   Int_t ibitxy = location.GetSecond();
170
171                   AliMUONLocalTriggerBoard *b = fCrates->LocalBoard(nboard);
172
173                   if (b) 
174                   {
175                       if (cathode && b->GetSwitch(6)) ibitxy += 8;
176                                                 
177                       b->SetbitM(ibitxy,cathode,ichamber-10);
178                                                 
179                       DigitFiredCircuit(b->GetI(), cathode, ichamber, digitindex);
180                   }
181                   else
182                   {
183                       AliError(Form("Could not get local board number %d",b->GetNumber()));
184                  }
185               }
186           }             
187       }
188     }
189
190   // Particular case of the columns with 22 local boards (2R(L) 3R(L))   
191   AliMUONTriggerCrate *crate = 0x0; TObjArray *bs = 0x0;
192
193   char *scratess[4] = {  "2R",   "2L",   "3L",   "3R"}; 
194   char *scratesd[4] = {"2-3R", "2-3L", "2-3L", "2-3R"}; 
195   Int_t    slotf[4] = {     2,      2,     10,     10}; 
196   Int_t    slotd[4] = {     1,      1,      9,      9}; 
197
198   for (Int_t i = 0; i < 4; i++)
199   {
200       crate = fCrates->Crate(scratess[i]); 
201       bs = crate->Boards();
202       AliMUONLocalTriggerBoard *desybb = (AliMUONLocalTriggerBoard*)bs->At(14);
203       AliMUONLocalTriggerBoard *fromcb = (AliMUONLocalTriggerBoard*)bs->At(15);
204       AliMUONLocalTriggerBoard *desxbb = (AliMUONLocalTriggerBoard*)bs->At(16);
205
206       crate = fCrates->Crate(scratesd[i]); 
207       bs = crate->Boards();
208       AliMUONLocalTriggerBoard *frombb = (AliMUONLocalTriggerBoard*)bs->At(slotf[i]);
209       AliMUONLocalTriggerBoard *desycb = (AliMUONLocalTriggerBoard*)bs->At(slotd[i]);
210
211       UShort_t cX[2];
212
213       //    COPY X3-4 FROM BOARD  2 OF CRATE 2-3 TO BOARD 16 OF CRATE 2
214       //    COPY X3-4 FROM BOARD 10 OF CRATE 2-3 TO BOARD 16 OF CRATE 3
215       frombb->GetX34(cX); desxbb->SetX34(cX);
216
217       //    COPY X3-4 FROM BOARD 15 OF CRATE 2 TO BOARD 1 OF CRATE 2-3
218       //    COPY X3-4 FROM BOARD 15 OF CRATE 3 TO BOARD 9 OF CRATE 2-3
219       fromcb->GetX34(cX); desycb->SetX34(cX);
220
221       UShort_t cY[4];
222
223       desybb->GetY(cY); frombb->SetY(cY);
224
225       frombb->GetY(cY); desxbb->SetY(cY);
226       fromcb->GetY(cY); desycb->SetY(cY);
227   }
228
229   // FILL UP/DOWN OF CURRENT BOARD (DONE VIA J3 BUS IN REAL LIFE)
230   AliMUONTriggerCrate* cr;
231  
232   fCrates->FirstCrate();
233  
234   while ( ( cr = fCrates->NextCrate() ) )
235   {            
236       TObjArray *boards = cr->Boards();
237                 
238       for (Int_t j = 1; j < boards->GetEntries()-1; j++)
239       {
240           TObject *o = boards->At(j);
241                         
242           if (!o) break;
243                         
244           AliMUONLocalTriggerBoard *currboard = (AliMUONLocalTriggerBoard*)o;
245                         
246           AliMUONLocalTriggerBoard *neighbour = (AliMUONLocalTriggerBoard*)boards->At(j+1);
247                         
248           UShort_t cXY[2][4];
249                         
250           if (j==1) {neighbour->GetXY(cXY); currboard->SetXYU(cXY);}
251                         
252           //       LAST BOARD IN THE CRATE HAS NO UP EXCEPT FOR CRATES 2 & 3
253           if (j < boards->GetEntries()-2)  
254           {
255               AliMUONLocalTriggerBoard *nextboard = (AliMUONLocalTriggerBoard*)boards->At(j+2);
256                                 
257               currboard->GetXY(cXY); neighbour->SetXYD(cXY);
258               nextboard->GetXY(cXY); neighbour->SetXYU(cXY);
259                                 
260               if (j==boards->GetEntries()-3) {neighbour->GetXY(cXY); nextboard->SetXYD(cXY);}
261           }
262       }
263   }
264 }
265
266 //___________________________________________
267 void AliMUONTriggerElectronics::Feed(UShort_t pattern[2][4])
268 {
269   /// FILL INPUTS
270   ///
271   AliMUONTriggerCrate* cr;
272    
273    fCrates->FirstCrate();
274    
275    while ( ( cr = fCrates->NextCrate() ) )
276    {                 
277      TObjArray *boards = cr->Boards();
278      
279      for (Int_t j = 1; j < boards->GetEntries(); j++)
280      {
281        TObject *o = boards->At(j);
282        
283        if (!o) break;
284        
285        AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
286        
287        board->SetXY(pattern);
288      }
289    }
290 }
291
292 //___________________________________________
293 void AliMUONTriggerElectronics::DumpOS()
294 {
295 /// DUMP IN THE OLD WAY
296 ///
297    for (Int_t i= 0; i < 234;i++)
298    {
299       AliMUONLocalTriggerBoard *board = fCrates->LocalBoard(i);
300
301       if (board) board->Scan("ALL");
302    }
303 }
304
305 //___________________________________________
306 void AliMUONTriggerElectronics::Scan(Option_t *option)
307 {
308   /// SCAN
309   ///
310
311   AliMUONTriggerCrate* cr;
312   
313   fCrates->FirstCrate();
314   
315   while ( ( cr = fCrates->NextCrate() ) )
316   {                
317     TObjArray *boards = cr->Boards();
318     
319     for (Int_t j = 0; j < boards->GetEntries(); j++)
320     {
321       TObject *o = boards->At(j);
322       
323       TString op = option;
324       
325       Bool_t cdtion = kFALSE;
326       
327       if (op.Contains("LOCAL"))    cdtion = o->IsA() == AliMUONLocalTriggerBoard::Class();
328       if (op.Contains("REGIONAL")) cdtion = o->IsA() == AliMUONRegionalTriggerBoard::Class();
329       if (op.Contains("GLOBAL"))   cdtion = o->IsA() == AliMUONGlobalTriggerBoard::Class();
330       
331       if (!o || !cdtion) continue;
332       
333       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
334       
335       board->Scan();
336     }
337   }
338 }
339
340 //___________________________________________
341 void AliMUONTriggerElectronics::Reset()
342 {
343   /// RESET
344   ///
345   
346    AliMUONTriggerCrate* cr;
347    
348    fCrates->FirstCrate();
349    
350    while ( ( cr = fCrates->NextCrate() ) )
351    {            
352       TObjArray *boards = cr->Boards();
353             
354       for (Int_t j=0; j<boards->GetEntries(); j++)
355       {     
356          AliMUONTriggerBoard *b = (AliMUONTriggerBoard*)boards->At(j);
357
358          if (b) b->Reset();
359       }
360    }
361 }
362
363 //_______________________________________________________________________
364 void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData)
365 {
366   // LOAD MASKS FROM CDB
367   
368
369   // SET MASKS
370   
371   AliMUONTriggerCrate* cr;
372   
373   fCrates->FirstCrate();
374   
375   Int_t irb(0);
376   
377   while ( ( cr = fCrates->NextCrate() ) )
378   {            
379     TObjArray *boards = cr->Boards();
380     
381     AliMUONRegionalTriggerBoard *regb =
382       (AliMUONRegionalTriggerBoard*)boards->At(0);
383
384     AliMUONVCalibParam* regionalBoardMasks = calibData->RegionalTriggerBoardMasks(irb);
385     
386     for ( Int_t i = 0; i < regionalBoardMasks->Size(); ++i )
387     {
388       UShort_t rmask = static_cast<UShort_t>(regionalBoardMasks->ValueAsInt(i) & 0x3F);
389       regb->Mask(i,rmask);
390     }
391     
392     for (Int_t j = 1; j < boards->GetEntries(); j++)
393     {
394       AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
395       
396       Int_t cardNumber = b->GetNumber();
397       
398       if (cardNumber) // interface board are not interested
399       {
400         AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
401         for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
402         {
403           UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
404           b->Mask(i,lmask);
405         }
406       }
407     }
408     ++irb;
409   }
410   
411   AliMUONVCalibParam* globalBoardMasks = calibData->GlobalTriggerBoardMasks();
412   for ( Int_t i = 0; i < globalBoardMasks->Size(); ++i )
413   {
414     UShort_t gmask = static_cast<UShort_t>(globalBoardMasks->ValueAsInt(i) & 0xFFF);
415     fGlobalTriggerBoard->Mask(i,gmask);
416   }
417 }
418
419
420 //___________________________________________
421 void AliMUONTriggerElectronics::LocalResponse()
422 {
423 /// \todo add comment
424         
425   AliMUONTriggerCrate* cr;
426   
427   fCrates->FirstCrate();
428   
429   while ( ( cr = fCrates->NextCrate() ) )
430   {            
431     
432     TObjArray *boards = cr->Boards();
433     
434     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
435     
436     UShort_t thisl[16]; for (Int_t j=0; j<16; j++) thisl[j] = 0;
437   
438     for (Int_t j = 1; j < boards->GetEntries(); j++)
439     {     
440         TObject *o = boards->At(j);
441       
442         if (!o) break;
443       
444         AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
445       
446         if (board) // check if empty slot
447         {
448           board->Response();
449                                 
450           UShort_t response = board->GetResponse();            
451         
452           // CRATE CONTAINING INTERFACE BOARD
453           if (board->GetNumber() == 0) // copy boards
454           {
455             if ( response != 0 ) 
456               AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
457                                           board->GetName(),j,cr->GetName()));
458             AliDebug(1, Form("local slot %d, number %d in crate %s\n", j, board->GetNumber(), cr->GetName()));
459
460           }
461         
462           thisl[j-1] = response;
463         }
464       }
465     
466     regb->SetLocalResponse(thisl);
467   }
468 }
469
470 //___________________________________________
471 void AliMUONTriggerElectronics::RegionalResponse()
472 {
473   /// Compute the response for all regional cards.
474   AliMUONTriggerCrate* cr;
475   
476   fCrates->FirstCrate();
477   
478   while ( ( cr = fCrates->NextCrate() ) )
479   {            
480       TObjArray *boards = cr->Boards();
481
482       AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
483       
484       if (regb) 
485       {
486          regb->Response();
487       }  
488    }
489 }
490
491 //___________________________________________
492 void AliMUONTriggerElectronics::GlobalResponse()
493 {
494   /// Compute the global response
495
496   UShort_t regional[16];
497   
498   AliMUONTriggerCrate* cr;
499   
500   fCrates->FirstCrate();
501   Int_t irb(0);
502   
503   if ( !fCrates->NumberOfCrates() >= 16 ) 
504   {
505     AliFatal(Form("Something is wrong : too many crates %d",
506                   fCrates->NumberOfCrates()));
507   }
508   
509   while ( ( cr = fCrates->NextCrate() ) )
510   {            
511     AliMUONTriggerBoard* rb = 
512       static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
513     regional[irb] = rb->GetResponse();
514     ++irb;
515   }
516   
517   fGlobalTriggerBoard->SetRegionalResponse(regional);
518   fGlobalTriggerBoard->Response();
519 }
520
521 //_______________________________________________________________________
522 void 
523 AliMUONTriggerElectronics::Exec(Option_t*)
524 {
525 /// \todo add comment
526 ///
527   Digits2Trigger();
528 }
529
530 //_______________________________________________________________________
531 void AliMUONTriggerElectronics::Trigger()
532 {
533 /// \todo add comment
534 ///
535    FeedM();
536    LocalResponse();
537    RegionalResponse();      
538    GlobalResponse();
539 }
540
541 //_______________________________________________________________________
542 void AliMUONTriggerElectronics::Digits2Trigger()
543 {
544   /// Main method to go from digits to trigger decision
545   AliMUONRegionalTrigger *pRegTrig = new AliMUONRegionalTrigger();
546   ClearDigitNumbers();
547   fMUONData->ResetTrigger(); 
548   // RUN THE FULL BEE CHAIN
549   Trigger();
550 //    DumpOS();
551         
552   AliMUONTriggerCrate* cr;
553   fCrates->FirstCrate();
554
555   while ( ( cr = fCrates->NextCrate() ) )
556   {            
557     TObjArray *boards = cr->Boards();
558
559     UInt_t regInpLpt = 0;
560     UInt_t regInpHpt = 0;
561     UShort_t localMask = 0x0;
562
563     AliMUONRegionalTriggerBoard *regBoard = (AliMUONRegionalTriggerBoard*)boards->At(0);
564
565     for (Int_t j = 1; j < boards->GetEntries(); j++)
566     {     
567       TObject *o = boards->At(j);
568       
569       if (!o) break;
570       
571       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
572       
573       if (board) 
574       {
575         //          L0 TRIGGER
576         if (board->Triggered())
577         {
578           
579           Int_t icirc = board->GetNumber();
580
581           fLocalTrigger->SetLoCircuit(icirc);
582           fLocalTrigger->SetLoStripX(board->GetStripX11());
583           fLocalTrigger->SetLoDev(board->GetDev());
584           fLocalTrigger->SetLoStripY(board->GetStripY11());
585           
586           //             SAVE LUT OUTPUT 
587           UShort_t response = board->GetResponse();
588           fLocalTrigger->SetLoHpt((response & 12) >> 2);
589           fLocalTrigger->SetLoLpt(response &  3);
590
591           // calculates regional inputs from local for the moment
592           UInt_t hPt = (response >> 4) & 0x3;
593           UInt_t lPt = (response >> 2) & 0x3;
594             
595           regInpHpt |= hPt << (30 - (j-1)*2);
596           regInpLpt |= lPt << (30 - (j-1)*2);
597           localMask |= (0x1 << (j-1)); // local mask
598
599           TBits rrr;
600           rrr.Set(6,&response);   
601           
602           //             SAVE BIT PATTERN
603           fLocalTrigger->SetX1Pattern(board->GetXY(0,0));
604           fLocalTrigger->SetX2Pattern(board->GetXY(0,1));
605           fLocalTrigger->SetX3Pattern(board->GetXY(0,2));
606           fLocalTrigger->SetX4Pattern(board->GetXY(0,3));
607           
608           fLocalTrigger->SetY1Pattern(board->GetXY(1,0));
609           fLocalTrigger->SetY2Pattern(board->GetXY(1,1));
610           fLocalTrigger->SetY3Pattern(board->GetXY(1,2));
611           fLocalTrigger->SetY4Pattern(board->GetXY(1,3));
612           
613           fLocalTrigger->SetDigits(fDigitNumbers[icirc]);
614
615           //             ADD A NEW LOCAL TRIGGER          
616           fMUONData->AddLocalTrigger(*fLocalTrigger);  
617           
618         }
619       }
620     }
621     pRegTrig->SetLocalOutput(regInpLpt, 0);
622     pRegTrig->SetLocalOutput(regInpHpt, 1);
623     pRegTrig->SetLocalMask(localMask);
624     pRegTrig->SetOutput((regBoard->GetResponse() >> 4) & 0xF); // to be uniformized (oct06 ?)
625
626     fMUONData->AddRegionalTrigger(*pRegTrig);  
627     
628   }
629   delete pRegTrig;
630   
631   // GLOBAL TRIGGER INFORMATION
632   UShort_t global = fGlobalTriggerBoard->GetResponse();
633   fGlobalTrigger->SetFromGlobalResponse(global);
634
635   
636   // ADD A LOCAL TRIGGER IN THE LIST 
637   fMUONData->AddGlobalTrigger(*fGlobalTrigger);
638
639   // NOW RESET ELECTRONICS
640   Reset();
641 }
642
643 //_______________________________________________________________________
644 void AliMUONTriggerElectronics::ClearDigitNumbers()
645 {
646 // RESET fDigitNumbers
647         for (Int_t i=0; i<AliMUONConstants::NTriggerCircuit(); i++) fDigitNumbers[i].Set(0);
648 }
649
650 //_______________________________________________________________________
651 void AliMUONTriggerElectronics::DigitFiredCircuit(Int_t circuit, Int_t cathode,
652                                                   Int_t chamber, Int_t digit)
653 {
654 // REGISTERS THAT THE SPECIFIED DIGIT FIRED THE SPECIFIED CIRCUIT
655 // THIS DIGIT GETS ADDED TO AN ARRAY WHICH WILL BE COPIED TO
656 // AliMUONLocalTrigger WHEN SUCH AN OBJECT IS CREATED FOR EACH CIRCUIT
657         Int_t digitnumber = AliMUONLocalTrigger::EncodeDigitNumber(chamber, cathode, digit);
658         Int_t last = fDigitNumbers[circuit].GetSize();
659         fDigitNumbers[circuit].Set(last + 1);
660         fDigitNumbers[circuit][last] = digitnumber;
661 }
662