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