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