]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTriggerElectronics.cxx
In AliMUONTriggerQAChecker:
[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",b->GetNumber()));
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      AliWarning("No valid regional trigger configuration in CDB");
438
439   
440   AliMUONTriggerCrate* cr;
441   TIter next(fCrates->CreateCrateIterator());
442   
443   Int_t irb(0);
444   
445   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
446   {            
447     TObjArray *boards = cr->Boards();
448     
449     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
450
451     AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(cr->GetName());
452     
453     if (!crateConfig)
454     {
455       AliError(Form("Crate %s not present in configuration !!!", cr->GetName()));
456       return;
457     }
458     
459     UShort_t rmask= crateConfig->GetMask();
460
461     regb->Mask(rmask);
462     
463     for (Int_t j = 1; j < boards->GetEntries(); j++)
464     {
465       AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
466       
467       Int_t cardNumber = b->GetNumber();
468       
469       if (cardNumber) // interface board are not interested
470       {
471         AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
472         for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
473         {
474           UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
475           b->Mask(i,lmask);
476         }
477       }
478     }
479     ++irb;
480   }
481   
482    AliMUONGlobalCrateConfig * globalConfig = calibData->GlobalTriggerCrateConfig();
483   if (!globalConfig)
484      AliWarning("No valid trigger crate configuration in CDB");
485
486     UInt_t gmask = 0;
487     for (Int_t i = 0; i < 4; i++) {
488       gmask = globalConfig->GetGlobalMask(i);
489       fGlobalTriggerBoard->Mask(i,gmask);
490     }
491 }
492
493 //___________________________________________
494 void AliMUONTriggerElectronics::LocalResponse()
495 {
496 /// Compute the response for local cards
497
498   AliCodeTimerAuto("",0);
499         
500   AliMUONTriggerCrate* cr;
501   TIter next(fCrates->CreateCrateIterator());
502
503   UShort_t thisl[16];
504   
505   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
506   {            
507     
508     TObjArray *boards = cr->Boards();
509     
510     AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
511     
512     for (Int_t j=0; j<16; ++j) thisl[j] = 0;
513   
514     for (Int_t j = 1; j < boards->GetEntries(); j++)
515     {     
516         TObject *o = boards->At(j);
517       
518         if (!o) break;
519       
520         AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
521
522         board->Response();
523                                 
524         UShort_t response = board->GetResponse();            
525         
526         // CRATE CONTAINING INTERFACE BOARD
527         if (board->GetNumber() == 0) // copy boards
528         {
529           if ( response != 0 ) 
530             AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
531                             board->GetName(),j,cr->GetName()));
532           AliDebug(1, Form("local slot %d, number %d in crate %s\n", j, board->GetNumber(), cr->GetName()));
533           
534         }
535         
536         thisl[j-1] = response;
537     }
538     
539     regb->SetLocalResponse(thisl);
540   }
541 }
542
543 //___________________________________________
544 void AliMUONTriggerElectronics::RegionalResponse()
545 {
546   /// Compute the response for all regional cards.
547
548   AliCodeTimerAuto("",0);
549
550   AliMUONTriggerCrate* cr;
551   TIter next(fCrates->CreateCrateIterator());
552   
553   while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
554   {            
555       TObjArray *boards = cr->Boards();
556
557       AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
558
559       regb->Response();
560
561    }
562 }
563
564 //___________________________________________
565 void AliMUONTriggerElectronics::GlobalResponse()
566 {
567   /// Compute the global response
568
569   AliCodeTimerAuto("",0);
570
571   UShort_t regional[16];
572   
573   AliMUONTriggerCrate* cr;
574   Int_t irb(0);
575   
576   if ( !fCrates->NumberOfCrates() >= 16 ) 
577   {
578     AliFatal(Form("Something is wrong : too many crates %d",
579                   fCrates->NumberOfCrates()));
580   }
581
582   // send regional responses to the global trigger in right order
583   // do not used iterator order
584   
585   for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
586   {            
587     for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
588     {
589       cr = fCrates->Crate(iSide, iReg);     
590
591       AliMUONTriggerBoard* rb = 
592         static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
593       regional[irb] = rb->GetResponse();
594       ++irb;
595     }
596   }
597
598   fGlobalTriggerBoard->SetRegionalResponse(regional);
599   fGlobalTriggerBoard->Response();
600 }
601
602 //_______________________________________________________________________
603 void AliMUONTriggerElectronics::Digits2Trigger(const AliMUONVDigitStore& digitStore,
604                                                AliMUONVTriggerStore& triggerStore)
605 {
606   AliCodeTimerAuto("",0);
607
608   /// Main method to go from digits to trigger decision
609   AliMUONRegionalTrigger pRegTrig;
610   
611   triggerStore.Clear();
612
613   // NOW RESET ELECTRONICS
614   Reset();
615   
616   // RUN THE FULL BEE CHAIN
617   Feed(digitStore);
618   LocalResponse();
619   RegionalResponse();      
620   GlobalResponse();
621   //    DumpOS();
622         
623   AliMUONTriggerCrate* cr;
624   AliMUONLocalTrigger localTrigger;
625   
626   // stored in right order
627   // do not used iterator order
628   
629   for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
630   {            
631     for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
632     {
633       cr = fCrates->Crate(iSide, iReg);     
634       TObjArray *boards = cr->Boards();
635       
636       UInt_t regInpLpt = 0;
637       UInt_t regInpHpt = 0;
638       
639       AliMUONRegionalTriggerBoard *regBoard = (AliMUONRegionalTriggerBoard*)boards->At(0);
640       
641       for (Int_t j = 1; j < boards->GetEntries(); j++)
642       {     
643         TObject *o = boards->At(j);
644         
645         if (!o) break;
646         
647         AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
648         
649         if (board) 
650         {
651           //          L0 TRIGGER
652           // pcrochet 181206: MOOD needs ALL boards
653           //      if (board->Triggered())
654           //      {
655           
656           Int_t icirc = board->GetNumber();
657           if (icirc != 0) { // pcrochet 181206: MOOD needs ALL boards
658             
659             localTrigger.SetLoCircuit(icirc);
660             localTrigger.SetLoStripX(board->GetStripX11());
661             localTrigger.SetLoDev(board->GetDev());
662             localTrigger.SetLoSdev(board->GetSdev());
663             localTrigger.SetLoTrigY(board->GetTrigY());
664             localTrigger.SetLoStripY(board->GetStripY11());
665             
666             //             SAVE LUT OUTPUT 
667             UShort_t response = board->GetResponse();
668             localTrigger.SetLoHpt((response & 12) >> 2);
669             localTrigger.SetLoLpt(response &  3);
670             
671             // calculates regional inputs from local for the moment
672             UInt_t hPt = (response >> 2) & 0x3;
673             UInt_t lPt =  response       & 0x3;
674             
675             regInpHpt |= hPt << (30 - (j-1)*2);
676             regInpLpt |= lPt << (30 - (j-1)*2);
677             
678             TBits rrr;
679             rrr.Set(6,&response);         
680             
681             //             SAVE BIT PATTERN
682             localTrigger.SetX1Pattern(board->GetXY(0,0));
683             localTrigger.SetX2Pattern(board->GetXY(0,1));
684             localTrigger.SetX3Pattern(board->GetXY(0,2));
685             localTrigger.SetX4Pattern(board->GetXY(0,3));
686             
687             localTrigger.SetY1Pattern(board->GetXY(1,0));
688             localTrigger.SetY2Pattern(board->GetXY(1,1));
689             localTrigger.SetY3Pattern(board->GetXY(1,2));
690             localTrigger.SetY4Pattern(board->GetXY(1,3));
691             
692             //             ADD A NEW LOCAL TRIGGER          
693             triggerStore.Add(localTrigger);  
694             
695           }
696           }
697         }
698       pRegTrig.SetId(iReg + 8*iSide);
699       pRegTrig.SetLocalOutput(regInpLpt, 0);
700       pRegTrig.SetLocalOutput(regInpHpt, 1);
701       pRegTrig.SetOutput(regBoard->GetResponse());
702       
703       triggerStore.Add(pRegTrig);  
704       }
705     }
706   
707   // GLOBAL TRIGGER INFORMATION
708   UShort_t global = fGlobalTriggerBoard->GetResponse();
709   UInt_t *globalInput = fGlobalTriggerBoard->GetGlobalInput();  
710
711   AliMUONGlobalTrigger globalTrigger;
712   
713   globalTrigger.SetFromGlobalResponse(global);
714   globalTrigger.SetFromGlobalInput(globalInput);
715   // ADD A LOCAL TRIGGER IN THE LIST 
716   triggerStore.SetGlobal(globalTrigger);
717
718 }
719
720 //___________________________________________
721 void AliMUONTriggerElectronics::Feed(const AliMUONVTriggerStore& triggerStore)
722 {
723   //
724   /// Fill inputs from reconstructed local trigger store
725   //
726   AliMUONLocalTrigger* locTrg;
727   TIter next(triggerStore.CreateLocalIterator());
728   TArrayS xyPattern[2];
729   UShort_t xy[2][4];
730   Int_t loCircuit;
731   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
732     locTrg->GetXPattern(xyPattern[0]);
733     locTrg->GetYPattern(xyPattern[1]);
734     loCircuit = locTrg->LoCircuit();
735     AliMUONLocalTriggerBoard* localBoard = fCrates->LocalBoard(loCircuit);
736     for (Int_t icath = 0; icath<2; ++icath){
737       for (Int_t ich = 0; ich < 4; ++ich){
738         xy[icath][ich] = xyPattern[icath][ich];
739       }
740     }
741     localBoard->SetXY(xy);
742   }
743
744   FeedCopyNeighbours();
745 }
746
747 //_______________________________________________________________________
748 Bool_t AliMUONTriggerElectronics::ModifiedLocalResponse(Int_t loCircuit,
749                                                         Bool_t& bendingPlaneResp,
750                                                         Bool_t& nonBendingPlaneResp,
751                                                         Bool_t isCoinc44,
752                                                         Int_t removeChamber)
753 {
754   //
755   /// Re-compute the local trigger response
756   /// with some modifications (i.e. setting coinc44 or after removing one chamber)
757   //
758
759   bendingPlaneResp = kFALSE;
760   nonBendingPlaneResp = kFALSE;
761
762   Bool_t isTriggered = kFALSE;
763
764   AliMUONLocalTriggerBoard* currBoard = fCrates->LocalBoard(loCircuit);
765
766   if ( ! currBoard ) return isTriggered;
767
768   AliMUONLocalTriggerBoard localBoard (*currBoard);
769
770   if (removeChamber>=0 && removeChamber<=3){
771
772     // Set the bit pattern of selected chamber to 0
773     UShort_t xy[2][4];
774     UShort_t xyu[2][4];
775     UShort_t xyd[2][4];
776
777     localBoard.GetXY(xy);
778     localBoard.GetXYU(xyu);
779     localBoard.GetXYD(xyd);
780
781     for(Int_t icath=0; icath<2; icath++){
782       xy[icath][removeChamber] = 0;
783       xyu[icath][removeChamber] = 0;
784       xyd[icath][removeChamber] = 0;
785     }
786
787     localBoard.SetXY(xy);
788     localBoard.SetXYU(xyu);
789     localBoard.SetXYD(xyd);
790   }
791
792   localBoard.ResetResponse();
793
794   localBoard.SetCoinc44((Int_t)isCoinc44);
795   localBoard.Response();
796
797   bendingPlaneResp = localBoard.IsTrigX();
798   nonBendingPlaneResp = localBoard.IsTrigY();
799   isTriggered = localBoard.Triggered();
800
801   return isTriggered;
802 }
803
804
805 //_______________________________________________________________________
806 void AliMUONTriggerElectronics::ResponseRemovingChambers(AliMUONVTriggerStore& triggerStore)
807 {
808   /// Update local board information with the trigger response after removing each chamber
809
810   AliCodeTimerAuto("", 0);
811
812   Reset();
813   Feed(triggerStore);
814
815   AliMUONLocalTrigger* locTrg;
816   TIter next(triggerStore.CreateLocalIterator());
817   Int_t loCircuit;
818   Bool_t planeResp[2], isTrig44;
819   Bool_t bendPlaneRespNoCh, nonBendPlaneRespNoCh, isTrigWithoutCh;
820   while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
821     if ( ! ( locTrg->IsTrigX() && locTrg->IsTrigY() ) ) continue;
822     loCircuit = locTrg->LoCircuit();
823     isTrig44 = ModifiedLocalResponse(loCircuit, planeResp[0], planeResp[1], kTRUE);
824     for (Int_t ich=0; ich<4; ++ich){
825       if ( ! isTrig44 ){
826         isTrigWithoutCh = ModifiedLocalResponse(loCircuit, bendPlaneRespNoCh, nonBendPlaneRespNoCh, kFALSE, ich);
827         if ( ! isTrigWithoutCh ) continue;
828         for (Int_t icath=0; icath<2; icath++){
829           if ( ! planeResp[icath] )
830             locTrg->SetNoHitInPlane(icath, ich);
831         } // loop on cathodes
832       }
833       locTrg->SetTriggerWithoutChamber(ich);
834     } // loop on chambers
835     AliDebug(1, Form("Is44 %i  triggers %i  pattern %i", isTrig44, locTrg->GetTriggerWithoutChamber(), locTrg->GetHitPatternFromResponse()));
836   }
837 }