Fixes for #86059: Install data when ALICE_ROOT does not point to source (Christian)
[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 //-----------------------------------------------------------------------------
19 // Class AliMUONTriggerElectronics
20 //--------------------------------
21 // Manager class for muon trigger electronics
22 // Client of trigger board classes
23 // Debugged by Ph. Crochet & Ch. Finck
24 // Interfaced with new mapping Ch. Finck
25 //
26 // Author: Rachid Guernane (LPCCFd)
27 //-----------------------------------------------------------------------------
28
29 #include "AliLoader.h"
30 #include "AliLog.h"
31 #include "AliMUONCalibrationData.h"
32 #include "AliMUONVDigit.h"
33 #include "AliMUONVDigitStore.h"
34 #include "AliMUONGlobalTrigger.h"
35 #include "AliMUONGlobalTriggerBoard.h"
36 #include "AliMUONLocalTrigger.h"
37 #include "AliMUONLocalTriggerBoard.h"
38 #include "AliMUONRegionalTrigger.h"
39 #include "AliMUONRegionalTriggerBoard.h"
40 #include "AliMUONTriggerCrate.h"
41 #include "AliMUONTriggerCrateStore.h"
42 #include "AliMUONTriggerElectronics.h"
43 #include "AliMUONTriggerCrateConfig.h"
44 #include "AliMUONRegionalTriggerConfig.h"
45 #include "AliMUONGlobalCrateConfig.h"
46 #include "AliMUONVTriggerStore.h"
47 #include "AliMUONVCalibParam.h"
48 #include "AliMpCathodType.h"
49 #include "AliMpCDB.h"
50 #include "AliMpDEManager.h"
51 #include "AliMpSegmentation.h"
52 #include "AliMpVSegmentation.h"
53 #include "AliMpCathodType.h"
54 #include "AliMpTriggerCrate.h"
55 #include "AliMpLocalBoard.h"
56 #include "AliMpDDLStore.h"
57 #include "AliMpExMap.h"
58 #include "AliMpIntPair.h"
59
60 #include "AliLog.h"
61 #include "AliLoader.h"
62 #include "AliRun.h"
63 #include <TBits.h>
64 #include <TSystem.h>
65
66 #include "AliCodeTimer.h"
67
68
69 /// \cond CLASSIMP
70 ClassImp(AliMUONTriggerElectronics)
71 /// \endcond
72
73 //___________________________________________
74 AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONCalibrationData* calibData) 
75 : TObject(),
76   fCrates(new AliMUONTriggerCrateStore),
77   fGlobalTriggerBoard(new AliMUONGlobalTriggerBoard)
78 {
79  /// CONSTRUCTOR
80 ///
81
82   for (Int_t i = 0; i < 2; ++i) {
83     fCopyXInput[i] = new TList();
84     fCopyXInput[i]->SetOwner();
85     fCopyYInput[i] = new TList();
86     fCopyYInput[i]->SetOwner();
87   }
88
89   // force loading of mapping if not already done
90   if ( !AliMpDDLStore::Instance(kFALSE) )
91   {
92     AliMpCDB::LoadDDLStore();
93   }
94   
95   SetCopyInput();
96   
97   Factory(calibData);
98   LoadMasks(calibData); 
99 }
100
101 //___________________________________________
102 AliMUONTriggerElectronics::~AliMUONTriggerElectronics()
103 {
104 /// DESTRUCTOR
105 ///
106   delete fGlobalTriggerBoard;
107   delete fCrates;
108   for (Int_t i = 0; i < 2; ++i) {
109     delete fCopyXInput[i];
110     delete fCopyYInput[i];
111   }
112
113 }
114
115 //___________________________________________
116 void AliMUONTriggerElectronics::SetCopyInput()
117 {  
118   /// set list of copy input
119   
120     for (Int_t iDDL = 0; iDDL < 2; ++iDDL) { 
121     
122       for(Int_t iReg = 0; iReg < 8; ++iReg){   //reg loop
123       
124         AliMpTriggerCrate* crateMapping = AliMpDDLStore::Instance()->GetTriggerCrate(iDDL, iReg);
125       
126         for(Int_t iLocal = 0; iLocal < crateMapping->GetNofLocalBoards(); ++iLocal) { 
127         
128           Int_t localBoardFromId = crateMapping->GetLocalBoardId(iLocal);
129           if (!localBoardFromId) continue; //empty slot, should not happen
130         
131           AliMpLocalBoard* localBoardFrom = AliMpDDLStore::Instance()->GetLocalBoard(localBoardFromId);
132           Int_t localBoardToId;
133           if ((localBoardToId = localBoardFrom->GetInputXto())) {
134               AliMpLocalBoard* localBoardTo = AliMpDDLStore::Instance()->GetLocalBoard(localBoardToId);
135               TString crateFrom = localBoardFrom->GetCrate();
136               Int_t   slotFrom  = localBoardFrom->GetSlot();
137               TString crateTo   = localBoardTo->GetCrate();
138               Int_t   slotTo    = localBoardTo->GetSlot();
139           
140               fCopyXInput[0]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateFrom), slotFrom));
141               fCopyXInput[1]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateTo), slotTo));
142               AliDebug(3, Form("copy xInputs from local  %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, 
143                                crateTo.Data(), slotTo));
144           }
145         
146           if ((localBoardToId = localBoardFrom->GetInputYto())) {
147               AliMpLocalBoard* localBoardTo = AliMpDDLStore::Instance()->GetLocalBoard(localBoardToId);
148               TString crateFrom = localBoardFrom->GetCrate();
149               Int_t   slotFrom  = localBoardFrom->GetSlot();
150               TString crateTo   = localBoardTo->GetCrate();
151               Int_t   slotTo    = localBoardTo->GetSlot();
152           
153               fCopyYInput[0]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateFrom), slotFrom));
154               fCopyYInput[1]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateTo), slotTo));
155               AliDebug(3, Form("copy yInputs from local  %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, 
156                                crateTo.Data(), slotTo));
157           
158           }
159  
160         }
161       }
162     }
163 }
164
165 //___________________________________________
166 void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData)
167 {  
168  /// BUILD ALL ELECTRONICS
169  ///
170
171     fCrates->ReadFromFile(calibData);
172 }
173
174 //___________________________________________
175 void AliMUONTriggerElectronics::Feed(const AliMUONVDigitStore& digitStore)
176 {
177   /// FILL INPUTS
178   ///
179
180   AliCodeTimerAuto("",0);
181   
182   TIter next(digitStore.CreateTriggerIterator());
183   AliMUONVDigit* mdig;
184   
185   while ( ( mdig = static_cast<AliMUONVDigit*>(next()) ) )
186   {      
187     //       CHECKME ! The TrackCharge is not ok with new digitizerV3 !
188     //                  for (Int_t ichg=0; ichg<10; ichg++) schg += mdig->TrackCharge(ichg);
189     Int_t ichamber = AliMpDEManager::GetChamberId(mdig->DetElemId());
190     Int_t schg = (Int_t)(mdig->Charge() + 0.5);
191     
192     //       APPLY CONDITION ON SOFT BACKGROUND 
193     Int_t tchg = schg - (Int_t(schg/10))*10;    
194     
195     if (schg<=10 || tchg>0) 
196     {
197       Int_t detElemId  = mdig->DetElemId();
198       Int_t cathode    = mdig->Cathode();
199     
200       const AliMpVSegmentation* seg = 
201           AliMpSegmentation::Instance()
202           ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
203   
204       Int_t ix = mdig->PadX(), iy = mdig->PadY();
205       
206       AliDebug(3,Form("cathode %d ix %d iy %d ",cathode,ix,iy));
207
208       AliMpPad pad = seg->PadByIndices(ix,iy,kTRUE);
209       
210       for (Int_t i=0; i<pad.GetNofLocations(); i++) 
211       {
212         Int_t nboard = pad.GetLocalBoardId(i);
213         
214         Int_t ibitxy = pad.GetLocalBoardChannel(i);
215         
216         AliMUONLocalTriggerBoard *b = fCrates->LocalBoard(nboard);
217         
218         if (b) 
219         {
220           if (cathode && b->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) ibitxy += 8;
221           
222           b->SetbitM(ibitxy,cathode,ichamber-10);
223         }
224         else
225         {
226           AliError(Form("Could not get local board number %d",nboard));
227         }
228       }
229     }           
230   }
231
232   FeedCopyNeighbours();
233 }
234
235
236 //___________________________________________
237 void AliMUONTriggerElectronics::FeedCopyNeighbours()
238 {
239   //
240   /// Feed the local copies
241   /// and complete the feed with the information of neighbours
242   //
243
244   // Particular case of the columns with 22 local boards (2R(L) 3R(L))   
245   // fill copy input from mapping instead of hardcoded valued (Ch.F)
246   AliMUONTriggerCrate *crate = 0x0; TObjArray *bs = 0x0;
247
248   for (Int_t i = 0; i < fCopyXInput[0]->GetEntries(); ++i) 
249   {
250     AliMpIntPair* pair = (AliMpIntPair*)fCopyXInput[0]->At(i);
251     TString crateFrom  =  AliMpExMap::GetString(pair->GetFirst());
252     Int_t   slotFrom   =  pair->GetSecond();
253
254     pair = (AliMpIntPair*)fCopyXInput[1]->At(i);
255     TString crateTo  =  AliMpExMap::GetString(pair->GetFirst());
256     Int_t   slotTo   =  pair->GetSecond();
257
258     AliDebug(3, Form("copy xInputs from local  %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, 
259                      crateTo.Data(), slotTo));
260
261     UShort_t cX[2];
262     crate = fCrates->Crate(crateFrom); 
263     bs = crate->Boards();
264     AliMUONLocalTriggerBoard *fromxb = (AliMUONLocalTriggerBoard*)bs->At(slotFrom);
265     crate = fCrates->Crate(crateTo); 
266     bs = crate->Boards();
267     AliMUONLocalTriggerBoard *desxb = (AliMUONLocalTriggerBoard*)bs->At(slotTo);
268     fromxb->GetX34(cX); desxb->SetX34(cX);
269
270
271   }
272
273   for (Int_t i = 0; i < fCopyYInput[0]->GetEntries(); ++i) 
274   {
275     AliMpIntPair* pair = (AliMpIntPair*)fCopyYInput[0]->At(i);
276     TString crateFrom  =  AliMpExMap::GetString(pair->GetFirst());
277     Int_t   slotFrom   =  pair->GetSecond();
278
279     pair = (AliMpIntPair*)fCopyYInput[1]->At(i);
280     TString crateTo  =  AliMpExMap::GetString(pair->GetFirst());
281     Int_t   slotTo   =  pair->GetSecond();
282
283     AliDebug(3, Form("copy yInputs from local  %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, 
284                      crateTo.Data(), slotTo));
285
286     UShort_t cY[4];
287     crate = fCrates->Crate(crateFrom); 
288     bs = crate->Boards();
289     AliMUONLocalTriggerBoard *fromyb = (AliMUONLocalTriggerBoard*)bs->At(slotFrom);
290     crate = fCrates->Crate(crateTo); 
291     bs = crate->Boards();
292     AliMUONLocalTriggerBoard *desyb = (AliMUONLocalTriggerBoard*)bs->At(slotTo);
293     fromyb->GetY(cY); desyb->SetY(cY);
294   }
295   
296   // FILL UP/DOWN OF CURRENT BOARD (DONE VIA J3 BUS IN REAL LIFE)
297   AliMUONTriggerCrate* cr;
298   TIter next2(fCrates->CreateCrateIterator());
299   
300   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next2()) ) )
301   {            
302     TObjArray *boards = cr->Boards();
303     
304     for (Int_t j = 1; j < boards->GetEntries()-1; j++)
305     {
306       TObject *o = boards->At(j);
307                         
308       if (!o) break;
309                         
310       AliMUONLocalTriggerBoard *currboard = (AliMUONLocalTriggerBoard*)o;
311                         
312       AliMUONLocalTriggerBoard *neighbour = (AliMUONLocalTriggerBoard*)boards->At(j+1);
313                         
314       UShort_t cXY[2][4];
315                         
316       if (j==1) {neighbour->GetXY(cXY); currboard->SetXYU(cXY);}
317                         
318       //       LAST BOARD IN THE CRATE HAS NO UP EXCEPT FOR CRATES 2 & 3
319       if (j < boards->GetEntries()-2)  
320       {
321               AliMUONLocalTriggerBoard *nextboard = (AliMUONLocalTriggerBoard*)boards->At(j+2);
322                                 
323               currboard->GetXY(cXY); neighbour->SetXYD(cXY);
324               nextboard->GetXY(cXY); neighbour->SetXYU(cXY);
325                                 
326               if (j==boards->GetEntries()-3) {neighbour->GetXY(cXY); nextboard->SetXYD(cXY);}
327       }
328     }
329   }
330  
331 }
332
333
334 //___________________________________________
335 void AliMUONTriggerElectronics::Feed(UShort_t pattern[2][4])
336 {
337   /// FILL INPUTS
338   ///
339   AliMUONTriggerCrate* cr;
340   TIter next(fCrates->CreateCrateIterator());
341    
342    while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
343    {                 
344      TObjArray *boards = cr->Boards();
345      
346      for (Int_t j = 1; j < boards->GetEntries(); j++)
347      {
348        TObject *o = boards->At(j);
349        
350        if (!o) break;
351        
352        AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
353        
354        board->SetXY(pattern);
355      }
356    }
357 }
358
359 //___________________________________________
360 void AliMUONTriggerElectronics::DumpOS()
361 {
362 /// DUMP IN THE OLD WAY
363 ///
364    for (Int_t i= 0; i < 234;i++)
365    {
366       AliMUONLocalTriggerBoard *board = fCrates->LocalBoard(i);
367
368       if (board) board->Scan("ALL");
369    }
370 }
371
372 //___________________________________________
373 void AliMUONTriggerElectronics::Scan(const Option_t *option)
374 {
375   /// SCAN
376   ///
377
378   AliMUONTriggerCrate* cr;
379   TIter next(fCrates->CreateCrateIterator());  
380   
381   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
382   {                
383     TObjArray *boards = cr->Boards();
384     
385     for (Int_t j = 0; j < boards->GetEntries(); j++)
386     {
387       TObject *o = boards->At(j);
388       
389       TString op = option;
390       
391       Bool_t cdtion = kFALSE;
392       
393       if (op.Contains("LOCAL"))    cdtion = o->IsA() == AliMUONLocalTriggerBoard::Class();
394       if (op.Contains("REGIONAL")) cdtion = o->IsA() == AliMUONRegionalTriggerBoard::Class();
395       if (op.Contains("GLOBAL"))   cdtion = o->IsA() == AliMUONGlobalTriggerBoard::Class();
396       
397       if (!o || !cdtion) continue;
398       
399       AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
400       
401       board->Scan();
402     }
403   }
404 }
405
406 //___________________________________________
407 void AliMUONTriggerElectronics::Reset()
408 {
409   /// RESET
410   ///
411   
412    AliMUONTriggerCrate* cr;
413   TIter next(fCrates->CreateCrateIterator());
414    while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
415    {            
416       TObjArray *boards = cr->Boards();
417             
418       for (Int_t j=0; j<boards->GetEntries(); j++)
419       {     
420          AliMUONTriggerBoard *b = (AliMUONTriggerBoard*)boards->At(j);
421
422          if (b) b->Reset();
423       }
424    }
425 }
426
427
428 //_______________________________________________________________________
429 void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData)
430 {
431   /// Load mask from config in CDB 
432   
433   // Set mask
434   
435   AliMUONRegionalTriggerConfig* regionalConfig = calibData->RegionalTriggerConfig();
436   if (!regionalConfig) {
437      AliError("No valid regional trigger configuration in CDB");
438      return;
439   }   
440   
441   AliMUONTriggerCrate* cr;
442   TIter next(fCrates->CreateCrateIterator());
443   
444   Int_t irb(0);
445   
446   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
447   {            
448     TObjArray *boards = cr->Boards();
449     
450     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
451
452     AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(cr->GetName());
453     
454     if (!crateConfig)
455     {
456       AliError(Form("Crate %s not present in configuration !!!", cr->GetName()));
457       return;
458     }
459     
460     UShort_t rmask= crateConfig->GetMask();
461
462     regb->Mask(rmask);
463     
464     for (Int_t j = 1; j < boards->GetEntries(); j++)
465     {
466       AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
467       
468       Int_t cardNumber = b->GetNumber();
469       
470       if (cardNumber) // interface board are not interested
471       {
472         AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
473         for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
474         {
475           UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
476           b->Mask(i,lmask);
477         }
478       }
479     }
480     ++irb;
481   }
482   
483    AliMUONGlobalCrateConfig * globalConfig = calibData->GlobalTriggerCrateConfig();
484    if (!globalConfig) {
485      AliError("No valid trigger crate configuration in CDB");
486      return;
487    }   
488
489     UInt_t gmask = 0;
490     for (Int_t i = 0; i < 4; i++) {
491       gmask = globalConfig->GetGlobalMask(i);
492       fGlobalTriggerBoard->Mask(i,gmask);
493     }
494 }
495
496 //___________________________________________
497 void AliMUONTriggerElectronics::LocalResponse()
498 {
499 /// Compute the response for local cards
500
501   AliCodeTimerAuto("",0);
502         
503   AliMUONTriggerCrate* cr;
504   TIter next(fCrates->CreateCrateIterator());
505
506   UShort_t thisl[16];
507   
508   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
509   {            
510     
511     TObjArray *boards = cr->Boards();
512     
513     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
514     
515     for (Int_t j=0; j<16; ++j) thisl[j] = 0;
516   
517     for (Int_t j = 1; j < boards->GetEntries(); j++)
518     {     
519         TObject *o = boards->At(j);
520       
521         if (!o) break;
522       
523         AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
524
525         board->Response();
526                                 
527         UShort_t response = board->GetResponse();            
528         
529         // CRATE CONTAINING INTERFACE BOARD
530         if (board->GetNumber() == 0) // copy boards
531         {
532           if ( response != 0 ) 
533             AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
534                             board->GetName(),j,cr->GetName()));
535           AliDebug(1, Form("local slot %d, number %d in crate %s\n", j, board->GetNumber(), cr->GetName()));
536           
537         }
538         
539         thisl[j-1] = response;
540     }
541     
542     regb->SetLocalResponse(thisl);
543   }
544 }
545
546 //___________________________________________
547 void AliMUONTriggerElectronics::RegionalResponse()
548 {
549   /// Compute the response for all regional cards.
550
551   AliCodeTimerAuto("",0);
552
553   AliMUONTriggerCrate* cr;
554   TIter next(fCrates->CreateCrateIterator());
555   
556   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
557   {            
558       TObjArray *boards = cr->Boards();
559
560       AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
561
562       regb->Response();
563
564    }
565 }
566
567 //___________________________________________
568 void AliMUONTriggerElectronics::GlobalResponse()
569 {
570   /// Compute the global response
571
572   AliCodeTimerAuto("",0);
573
574   UShort_t regional[16];
575   
576   AliMUONTriggerCrate* cr;
577   Int_t irb(0);
578   
579   if ( fCrates->NumberOfCrates() > 16 ) 
580   {
581     AliFatal(Form("Something is wrong : too many crates %d",
582                   fCrates->NumberOfCrates()));
583   }
584
585   // send regional responses to the global trigger in right order
586   // do not used iterator order
587   
588   for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
589   {            
590     for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
591     {
592       cr = fCrates->Crate(iSide, iReg);     
593
594       AliMUONTriggerBoard* rb = 
595         static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
596       regional[irb] = rb->GetResponse();
597       ++irb;
598     }
599   }
600
601   fGlobalTriggerBoard->SetRegionalResponse(regional);
602   fGlobalTriggerBoard->Response();
603 }
604
605 //_______________________________________________________________________
606 void AliMUONTriggerElectronics::Digits2Trigger(const AliMUONVDigitStore& digitStore,
607                                                AliMUONVTriggerStore& triggerStore)
608 {
609   AliCodeTimerAuto("",0);
610
611   /// Main method to go from digits to trigger decision
612   AliMUONRegionalTrigger pRegTrig;
613   
614   triggerStore.Clear();
615
616   // NOW RESET ELECTRONICS
617   Reset();
618   
619   // RUN THE FULL BEE CHAIN
620   Feed(digitStore);
621   LocalResponse();
622   RegionalResponse();      
623   GlobalResponse();
624   //    DumpOS();
625         
626   AliMUONTriggerCrate* cr;
627   AliMUONLocalTrigger localTrigger;
628   
629   // stored in right order
630   // do not used iterator order
631   
632   for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
633   {            
634     for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
635     {
636       cr = fCrates->Crate(iSide, iReg);     
637       TObjArray *boards = cr->Boards();
638       
639       UInt_t regInpLpt = 0;
640       UInt_t regInpHpt = 0;
641       
642       AliMUONRegionalTriggerBoard *regBoard = (AliMUONRegionalTriggerBoard*)boards->At(0);
643       
644       for (Int_t j = 1; j < boards->GetEntries(); j++)
645       {     
646         TObject *o = boards->At(j);
647         
648         if (!o) break;
649         
650         AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
651         
652         if (board) 
653         {
654           //          L0 TRIGGER
655           // pcrochet 181206: MOOD needs ALL boards
656           //      if (board->Triggered())
657           //      {
658           
659           Int_t icirc = board->GetNumber();
660           if (icirc != 0) { // pcrochet 181206: MOOD needs ALL boards
661             
662             localTrigger.SetLoCircuit(icirc);
663             localTrigger.SetLoStripX(board->GetStripX11());
664             localTrigger.SetLoDev(board->GetDev());
665             localTrigger.SetLoSdev(board->GetSdev());
666             localTrigger.SetLoTrigY(board->GetTrigY());
667             localTrigger.SetLoStripY(board->GetStripY11());
668             
669             //             SAVE LUT OUTPUT 
670             UShort_t response = board->GetResponse();
671             localTrigger.SetLoHpt((response & 12) >> 2);
672             localTrigger.SetLoLpt(response &  3);
673             
674             // calculates regional inputs from local for the moment
675             UInt_t hPt = (response >> 2) & 0x3;
676             UInt_t lPt =  response       & 0x3;
677             
678             regInpHpt |= hPt << (30 - (j-1)*2);
679             regInpLpt |= lPt << (30 - (j-1)*2);
680             
681             TBits rrr;
682             rrr.Set(6,&response);         
683             
684             //             SAVE BIT PATTERN
685             localTrigger.SetX1Pattern(board->GetXY(0,0));
686             localTrigger.SetX2Pattern(board->GetXY(0,1));
687             localTrigger.SetX3Pattern(board->GetXY(0,2));
688             localTrigger.SetX4Pattern(board->GetXY(0,3));
689             
690             localTrigger.SetY1Pattern(board->GetXY(1,0));
691             localTrigger.SetY2Pattern(board->GetXY(1,1));
692             localTrigger.SetY3Pattern(board->GetXY(1,2));
693             localTrigger.SetY4Pattern(board->GetXY(1,3));
694             
695             //             ADD A NEW LOCAL TRIGGER          
696             triggerStore.Add(localTrigger);  
697             
698           }
699           }
700         }
701       pRegTrig.SetId(iReg + 8*iSide);
702       pRegTrig.SetLocalOutput(regInpLpt, 0);
703       pRegTrig.SetLocalOutput(regInpHpt, 1);
704       pRegTrig.SetOutput(regBoard->GetResponse());
705       
706       triggerStore.Add(pRegTrig);  
707       }
708     }
709   
710   // GLOBAL TRIGGER INFORMATION
711   UShort_t global = fGlobalTriggerBoard->GetResponse();
712   UInt_t *globalInput = fGlobalTriggerBoard->GetGlobalInput();  
713
714   AliMUONGlobalTrigger globalTrigger;
715   
716   globalTrigger.SetFromGlobalResponse(global);
717   globalTrigger.SetFromGlobalInput(globalInput);
718   // ADD A LOCAL TRIGGER IN THE LIST 
719   triggerStore.SetGlobal(globalTrigger);
720
721 }
722
723 //___________________________________________
724 void AliMUONTriggerElectronics::Feed(const AliMUONVTriggerStore& triggerStore)
725 {
726   //
727   /// Fill inputs from reconstructed local trigger store
728   //
729   AliMUONLocalTrigger* locTrg;
730   TIter next(triggerStore.CreateLocalIterator());
731   TArrayS xyPattern[2];
732   UShort_t xy[2][4];
733   Int_t loCircuit;
734   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
735     locTrg->GetXPattern(xyPattern[0]);
736     locTrg->GetYPattern(xyPattern[1]);
737     loCircuit = locTrg->LoCircuit();
738     AliMUONLocalTriggerBoard* localBoard = fCrates->LocalBoard(loCircuit);
739     for (Int_t icath = 0; icath<2; ++icath){
740       for (Int_t ich = 0; ich < 4; ++ich){
741         xy[icath][ich] = xyPattern[icath][ich];
742       }
743     }
744     localBoard->SetXY(xy);
745   }
746
747   FeedCopyNeighbours();
748 }
749
750 //_______________________________________________________________________
751 Bool_t AliMUONTriggerElectronics::ModifiedLocalResponse(Int_t loCircuit,
752                                                         Bool_t& bendingPlaneResp,
753                                                         Bool_t& nonBendingPlaneResp,
754                                                         Bool_t isCoinc44,
755                                                         Int_t removeChamber)
756 {
757   //
758   /// Re-compute the local trigger response
759   /// with some modifications (i.e. setting coinc44 or after removing one chamber)
760   //
761
762   bendingPlaneResp = kFALSE;
763   nonBendingPlaneResp = kFALSE;
764
765   Bool_t isTriggered = kFALSE;
766
767   AliMUONLocalTriggerBoard* currBoard = fCrates->LocalBoard(loCircuit);
768
769   if ( ! currBoard ) return isTriggered;
770
771   AliMUONLocalTriggerBoard localBoard (*currBoard);
772
773   if (removeChamber>=0 && removeChamber<=3){
774
775     // Set the bit pattern of selected chamber to 0
776     UShort_t xy[2][4];
777     UShort_t xyu[2][4];
778     UShort_t xyd[2][4];
779
780     localBoard.GetXY(xy);
781     localBoard.GetXYU(xyu);
782     localBoard.GetXYD(xyd);
783
784     for(Int_t icath=0; icath<2; icath++){
785       xy[icath][removeChamber] = 0;
786       xyu[icath][removeChamber] = 0;
787       xyd[icath][removeChamber] = 0;
788     }
789
790     localBoard.SetXY(xy);
791     localBoard.SetXYU(xyu);
792     localBoard.SetXYD(xyd);
793   }
794
795   localBoard.ResetResponse();
796
797   localBoard.SetCoinc44((Int_t)isCoinc44);
798   localBoard.Response();
799
800   bendingPlaneResp = localBoard.IsTrigX();
801   nonBendingPlaneResp = localBoard.IsTrigY();
802   isTriggered = localBoard.Triggered();
803
804   return isTriggered;
805 }
806
807
808 //_______________________________________________________________________
809 void AliMUONTriggerElectronics::ResponseRemovingChambers(AliMUONVTriggerStore& triggerStore)
810 {
811   /// Update local board information with the trigger response after removing each chamber
812
813   AliCodeTimerAuto("", 0);
814
815   Reset();
816   Feed(triggerStore);
817
818   AliMUONLocalTrigger* locTrg;
819   TIter next(triggerStore.CreateLocalIterator());
820   Int_t loCircuit;
821   Bool_t planeResp[2], isTrig44;
822   Bool_t bendPlaneRespNoCh, nonBendPlaneRespNoCh, isTrigWithoutCh;
823   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
824     if ( ! ( locTrg->IsTrigX() && locTrg->IsTrigY() ) ) continue;
825     loCircuit = locTrg->LoCircuit();
826     isTrig44 = ModifiedLocalResponse(loCircuit, planeResp[0], planeResp[1], kTRUE);
827     for (Int_t ich=0; ich<4; ++ich){
828       if ( ! isTrig44 ){
829         isTrigWithoutCh = ModifiedLocalResponse(loCircuit, bendPlaneRespNoCh, nonBendPlaneRespNoCh, kFALSE, ich);
830         if ( ! isTrigWithoutCh ) continue;
831         for (Int_t icath=0; icath<2; icath++){
832           if ( ! planeResp[icath] )
833             locTrg->SetNoHitInPlane(icath, ich);
834         } // loop on cathodes
835       }
836       locTrg->SetTriggerWithoutChamber(ich);
837     } // loop on chambers
838     AliDebug(1, Form("Is44 %i  triggers %i  pattern %i", isTrig44, locTrg->GetTriggerWithoutChamber(), locTrg->GetHitPatternFromResponse()));
839   }
840 }