1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
26 // Author: Rachid Guernane (LPCCFd)
27 //-----------------------------------------------------------------------------
29 #include "AliLoader.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"
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"
61 #include "AliLoader.h"
66 #include "AliCodeTimer.h"
70 ClassImp(AliMUONTriggerElectronics)
73 //___________________________________________
74 AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONCalibrationData* calibData)
76 fCrates(new AliMUONTriggerCrateStore),
77 fGlobalTriggerBoard(new AliMUONGlobalTriggerBoard)
83 // force loading of mapping if not already done
84 if ( !AliMpDDLStore::Instance(kFALSE) )
86 AliMpCDB::LoadDDLStore();
94 //___________________________________________
95 AliMUONTriggerElectronics::~AliMUONTriggerElectronics()
99 delete fGlobalTriggerBoard;
104 //___________________________________________
105 void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData)
107 /// BUILD ALL ELECTRONICS
110 fCrates->ReadFromFile(calibData);
113 //___________________________________________
114 void AliMUONTriggerElectronics::Feed(const AliMUONVDigitStore& digitStore)
119 AliCodeTimerAuto("",0);
121 TIter next(digitStore.CreateTriggerIterator());
124 while ( ( mdig = static_cast<AliMUONVDigit*>(next()) ) )
126 // CHECKME ! The TrackCharge is not ok with new digitizerV3 !
127 // for (Int_t ichg=0; ichg<10; ichg++) schg += mdig->TrackCharge(ichg);
128 Int_t ichamber = AliMpDEManager::GetChamberId(mdig->DetElemId());
129 Int_t schg = (Int_t)(mdig->Charge() + 0.5);
131 // APPLY CONDITION ON SOFT BACKGROUND
132 Int_t tchg = schg - (Int_t(schg/10))*10;
134 if (schg<=10 || tchg>0)
136 Int_t detElemId = mdig->DetElemId();
137 Int_t cathode = mdig->Cathode();
139 const AliMpVSegmentation* seg =
140 AliMpSegmentation::Instance()
141 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
143 Int_t ix = mdig->PadX(), iy = mdig->PadY();
145 AliDebug(3,Form("cathode %d ix %d iy %d ",cathode,ix,iy));
147 AliMpPad pad = seg->PadByIndices(ix,iy,kTRUE);
149 for (Int_t i=0; i<pad.GetNofLocations(); i++)
151 Int_t nboard = pad.GetLocalBoardId(i);
153 Int_t ibitxy = pad.GetLocalBoardChannel(i);
155 AliMUONLocalTriggerBoard *b = fCrates->LocalBoard(nboard);
159 if (cathode && b->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) ibitxy += 8;
161 b->SetbitM(ibitxy,cathode,ichamber-10);
163 if ( cathode == 0 ) {
164 // Particular case of the columns with 22 local boards (2R(L) 3R(L))
166 AliMpLocalBoard* mpLocalBoard = AliMpDDLStore::Instance()->GetLocalBoard(nboard);
167 Int_t nboardCopy = mpLocalBoard->GetInputXto();
168 if ( nboardCopy > 0 ) {
169 AliMUONLocalTriggerBoard* copyBoard = fCrates->LocalBoard(nboardCopy);
170 copyBoard->SetbitM(ibitxy,cathode,ichamber-10);
176 AliError(Form("Could not get local board number %d",nboard));
182 FeedCopyNeighbours();
186 //___________________________________________
187 void AliMUONTriggerElectronics::FeedCopyNeighbours()
190 /// Feed the local copies
191 /// and complete the feed with the information of neighbours
194 // FILL UP/DOWN OF CURRENT BOARD (DONE VIA J3 BUS IN REAL LIFE)
195 AliMUONTriggerCrate* cr;
196 TIter next2(fCrates->CreateCrateIterator());
198 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next2()) ) )
200 TObjArray *boards = cr->Boards();
202 for (Int_t j = 1; j < boards->GetEntries()-1; j++)
204 TObject *o = boards->At(j);
208 AliMUONLocalTriggerBoard *currboard = (AliMUONLocalTriggerBoard*)o;
210 AliMUONLocalTriggerBoard *neighbour = (AliMUONLocalTriggerBoard*)boards->At(j+1);
214 if (j==1) {neighbour->GetXY(cXY); currboard->SetXYU(cXY);}
216 // LAST BOARD IN THE CRATE HAS NO UP EXCEPT FOR CRATES 2 & 3
217 if (j < boards->GetEntries()-2)
219 AliMUONLocalTriggerBoard *nextboard = (AliMUONLocalTriggerBoard*)boards->At(j+2);
221 currboard->GetXY(cXY); neighbour->SetXYD(cXY);
222 nextboard->GetXY(cXY); neighbour->SetXYU(cXY);
224 if (j==boards->GetEntries()-3) {neighbour->GetXY(cXY); nextboard->SetXYD(cXY);}
232 //___________________________________________
233 void AliMUONTriggerElectronics::Feed(UShort_t pattern[2][4])
237 AliMUONTriggerCrate* cr;
238 TIter next(fCrates->CreateCrateIterator());
240 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
242 TObjArray *boards = cr->Boards();
244 for (Int_t j = 1; j < boards->GetEntries(); j++)
246 TObject *o = boards->At(j);
250 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
252 board->SetXY(pattern);
257 //___________________________________________
258 void AliMUONTriggerElectronics::DumpOS()
260 /// DUMP IN THE OLD WAY
262 for (Int_t i= 0; i < 234;i++)
264 AliMUONLocalTriggerBoard *board = fCrates->LocalBoard(i);
266 if (board) board->Scan("ALL");
270 //___________________________________________
271 void AliMUONTriggerElectronics::Scan(const Option_t *option)
276 AliMUONTriggerCrate* cr;
277 TIter next(fCrates->CreateCrateIterator());
279 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
281 TObjArray *boards = cr->Boards();
283 for (Int_t j = 0; j < boards->GetEntries(); j++)
285 TObject *o = boards->At(j);
289 Bool_t cdtion = kFALSE;
291 if (op.Contains("LOCAL")) cdtion = o->IsA() == AliMUONLocalTriggerBoard::Class();
292 if (op.Contains("REGIONAL")) cdtion = o->IsA() == AliMUONRegionalTriggerBoard::Class();
293 if (op.Contains("GLOBAL")) cdtion = o->IsA() == AliMUONGlobalTriggerBoard::Class();
295 if (!o || !cdtion) continue;
297 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
304 //___________________________________________
305 void AliMUONTriggerElectronics::Reset()
310 AliMUONTriggerCrate* cr;
311 TIter next(fCrates->CreateCrateIterator());
312 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
314 TObjArray *boards = cr->Boards();
316 for (Int_t j=0; j<boards->GetEntries(); j++)
318 AliMUONTriggerBoard *b = (AliMUONTriggerBoard*)boards->At(j);
326 //_______________________________________________________________________
327 void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData)
329 /// Load mask from config in CDB
333 AliMUONRegionalTriggerConfig* regionalConfig = calibData->RegionalTriggerConfig();
334 if (!regionalConfig) {
335 AliError("No valid regional trigger configuration in CDB");
339 AliMUONTriggerCrate* cr;
340 TIter next(fCrates->CreateCrateIterator());
344 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
346 TObjArray *boards = cr->Boards();
348 AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
350 AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(cr->GetName());
354 AliError(Form("Crate %s not present in configuration !!!", cr->GetName()));
358 UShort_t rmask= crateConfig->GetMask();
362 for (Int_t j = 1; j < boards->GetEntries(); j++)
364 AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
366 Int_t cardNumber = b->GetNumber();
368 if (cardNumber) // skip empty slots
370 AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
371 for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
373 UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
381 AliMUONGlobalCrateConfig * globalConfig = calibData->GlobalTriggerCrateConfig();
383 AliError("No valid trigger crate configuration in CDB");
388 for (Int_t i = 0; i < 4; i++) {
389 gmask = globalConfig->GetGlobalMask(i);
390 fGlobalTriggerBoard->Mask(i,gmask);
394 //___________________________________________
395 void AliMUONTriggerElectronics::LocalResponse()
397 /// Compute the response for local cards
399 AliCodeTimerAuto("",0);
401 AliMUONTriggerCrate* cr;
402 TIter next(fCrates->CreateCrateIterator());
406 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
409 TObjArray *boards = cr->Boards();
411 AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
413 for (Int_t j=0; j<16; ++j) thisl[j] = 0;
415 for (Int_t j = 1; j < boards->GetEntries(); j++)
417 TObject *o = boards->At(j);
421 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
425 UShort_t response = board->GetResponse();
427 // CRATE CONTAINING INTERFACE BOARD
428 if (!board->IsNotified()) // copy boards
431 AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
432 board->GetName(),j,cr->GetName()));
433 AliDebug(1, Form("local slot %d, number %d in crate %s\n", j, board->GetNumber(), cr->GetName()));
437 thisl[j-1] = response;
440 regb->SetLocalResponse(thisl);
444 //___________________________________________
445 void AliMUONTriggerElectronics::RegionalResponse()
447 /// Compute the response for all regional cards.
449 AliCodeTimerAuto("",0);
451 AliMUONTriggerCrate* cr;
452 TIter next(fCrates->CreateCrateIterator());
454 while ( ( cr = static_cast<AliMUONTriggerCrate*>(next()) ) )
456 TObjArray *boards = cr->Boards();
458 AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
465 //___________________________________________
466 void AliMUONTriggerElectronics::GlobalResponse()
468 /// Compute the global response
470 AliCodeTimerAuto("",0);
472 UShort_t regional[16];
474 AliMUONTriggerCrate* cr;
477 if ( fCrates->NumberOfCrates() > 16 )
479 AliFatal(Form("Something is wrong : too many crates %d",
480 fCrates->NumberOfCrates()));
483 // send regional responses to the global trigger in right order
484 // do not used iterator order
486 for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
488 for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
490 cr = fCrates->Crate(iSide, iReg);
492 AliMUONTriggerBoard* rb =
493 static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
494 regional[irb] = rb->GetResponse();
499 fGlobalTriggerBoard->SetRegionalResponse(regional);
500 fGlobalTriggerBoard->Response();
503 //_______________________________________________________________________
504 void AliMUONTriggerElectronics::Digits2Trigger(const AliMUONVDigitStore& digitStore,
505 AliMUONVTriggerStore& triggerStore)
507 AliCodeTimerAuto("",0);
509 /// Main method to go from digits to trigger decision
510 AliMUONRegionalTrigger pRegTrig;
512 triggerStore.Clear();
514 // NOW RESET ELECTRONICS
517 // RUN THE FULL BEE CHAIN
524 AliMUONTriggerCrate* cr;
525 AliMUONLocalTrigger localTrigger;
527 // stored in right order
528 // do not used iterator order
530 for (Int_t iSide = 0; iSide < 2; iSide++) // right & left side
532 for (Int_t iReg = 0; iReg < 8; iReg++) // 8 crates/regional boards for each side.
534 cr = fCrates->Crate(iSide, iReg);
535 TObjArray *boards = cr->Boards();
537 UInt_t regInpLpt = 0;
538 UInt_t regInpHpt = 0;
540 AliMUONRegionalTriggerBoard *regBoard = (AliMUONRegionalTriggerBoard*)boards->At(0);
542 for (Int_t j = 1; j < boards->GetEntries(); j++)
544 TObject *o = boards->At(j);
548 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
553 // pcrochet 181206: MOOD needs ALL boards
554 // if (board->Triggered())
557 Int_t icirc = board->GetNumber();
558 localTrigger.SetLoCircuit(icirc);
559 localTrigger.SetLoStripX(board->GetStripX11());
560 localTrigger.SetLoDev(board->GetDev());
561 localTrigger.SetLoSdev(board->GetSdev());
562 localTrigger.SetLoTrigY(board->GetTrigY());
563 localTrigger.SetLoStripY(board->GetStripY11());
566 UShort_t response = board->GetResponse();
567 localTrigger.SetLoHpt((response & 12) >> 2);
568 localTrigger.SetLoLpt(response & 3);
570 // calculates regional inputs from local for the moment
571 UInt_t hPt = (response >> 2) & 0x3;
572 UInt_t lPt = response & 0x3;
574 regInpHpt |= hPt << (30 - (j-1)*2);
575 regInpLpt |= lPt << (30 - (j-1)*2);
578 rrr.Set(6,&response);
581 localTrigger.SetX1Pattern(board->GetXY(0,0));
582 localTrigger.SetX2Pattern(board->GetXY(0,1));
583 localTrigger.SetX3Pattern(board->GetXY(0,2));
584 localTrigger.SetX4Pattern(board->GetXY(0,3));
586 localTrigger.SetY1Pattern(board->GetXY(1,0));
587 localTrigger.SetY2Pattern(board->GetXY(1,1));
588 localTrigger.SetY3Pattern(board->GetXY(1,2));
589 localTrigger.SetY4Pattern(board->GetXY(1,3));
591 // ADD A NEW LOCAL TRIGGER
592 triggerStore.Add(localTrigger);
596 pRegTrig.SetId(iReg + 8*iSide);
597 pRegTrig.SetLocalOutput(regInpLpt, 0);
598 pRegTrig.SetLocalOutput(regInpHpt, 1);
599 pRegTrig.SetOutput(regBoard->GetResponse());
601 triggerStore.Add(pRegTrig);
605 // GLOBAL TRIGGER INFORMATION
606 UShort_t global = fGlobalTriggerBoard->GetResponse();
607 UInt_t *globalInput = fGlobalTriggerBoard->GetGlobalInput();
609 AliMUONGlobalTrigger globalTrigger;
611 globalTrigger.SetFromGlobalResponse(global);
612 globalTrigger.SetFromGlobalInput(globalInput);
613 // ADD A LOCAL TRIGGER IN THE LIST
614 triggerStore.SetGlobal(globalTrigger);
618 //___________________________________________
619 void AliMUONTriggerElectronics::Feed(const AliMUONVTriggerStore& triggerStore)
622 /// Fill inputs from reconstructed local trigger store
624 AliMUONLocalTrigger* locTrg;
625 TIter next(triggerStore.CreateLocalIterator());
626 TArrayS xyPattern[2];
629 while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
630 locTrg->GetXPattern(xyPattern[0]);
631 locTrg->GetYPattern(xyPattern[1]);
632 loCircuit = locTrg->LoCircuit();
633 AliMUONLocalTriggerBoard* localBoard = fCrates->LocalBoard(loCircuit);
634 for (Int_t icath = 0; icath<2; ++icath){
635 for (Int_t ich = 0; ich < 4; ++ich){
636 xy[icath][ich] = xyPattern[icath][ich];
639 localBoard->SetXY(xy);
642 FeedCopyNeighbours();
645 //_______________________________________________________________________
646 Bool_t AliMUONTriggerElectronics::ModifiedLocalResponse(Int_t loCircuit,
647 Bool_t& bendingPlaneResp,
648 Bool_t& nonBendingPlaneResp,
653 /// Re-compute the local trigger response
654 /// with some modifications (i.e. setting coinc44 or after removing one chamber)
657 bendingPlaneResp = kFALSE;
658 nonBendingPlaneResp = kFALSE;
660 Bool_t isTriggered = kFALSE;
662 AliMUONLocalTriggerBoard* currBoard = fCrates->LocalBoard(loCircuit);
664 if ( ! currBoard ) return isTriggered;
666 AliMUONLocalTriggerBoard localBoard (*currBoard);
668 if (removeChamber>=0 && removeChamber<=3){
670 // Set the bit pattern of selected chamber to 0
675 localBoard.GetXY(xy);
676 localBoard.GetXYU(xyu);
677 localBoard.GetXYD(xyd);
679 for(Int_t icath=0; icath<2; icath++){
680 xy[icath][removeChamber] = 0;
681 xyu[icath][removeChamber] = 0;
682 xyd[icath][removeChamber] = 0;
685 localBoard.SetXY(xy);
686 localBoard.SetXYU(xyu);
687 localBoard.SetXYD(xyd);
690 localBoard.ResetResponse();
692 localBoard.SetCoinc44((Int_t)isCoinc44);
693 localBoard.Response();
695 bendingPlaneResp = localBoard.IsTrigX();
696 nonBendingPlaneResp = localBoard.IsTrigY();
697 isTriggered = localBoard.Triggered();
703 //_______________________________________________________________________
704 void AliMUONTriggerElectronics::ResponseRemovingChambers(AliMUONVTriggerStore& triggerStore)
706 /// Update local board information with the trigger response after removing each chamber
708 AliCodeTimerAuto("", 0);
713 AliMUONLocalTrigger* locTrg;
714 TIter next(triggerStore.CreateLocalIterator());
716 Bool_t planeResp[2], isTrig44;
717 Bool_t bendPlaneRespNoCh, nonBendPlaneRespNoCh, isTrigWithoutCh;
718 while ( ( locTrg = static_cast<AliMUONLocalTrigger*>( next() )) != NULL ){
719 if ( ! ( locTrg->IsTrigX() && locTrg->IsTrigY() ) ) continue;
720 loCircuit = locTrg->LoCircuit();
721 isTrig44 = ModifiedLocalResponse(loCircuit, planeResp[0], planeResp[1], kTRUE);
722 for (Int_t ich=0; ich<4; ++ich){
724 isTrigWithoutCh = ModifiedLocalResponse(loCircuit, bendPlaneRespNoCh, nonBendPlaneRespNoCh, kFALSE, ich);
725 if ( ! isTrigWithoutCh ) continue;
726 for (Int_t icath=0; icath<2; icath++){
727 if ( ! planeResp[icath] )
728 locTrg->SetNoHitInPlane(icath, ich);
729 } // loop on cathodes
731 locTrg->SetTriggerWithoutChamber(ich);
732 } // loop on chambers
733 AliDebug(1, Form("Is44 %i triggers %i pattern %i", isTrig44, locTrg->GetTriggerWithoutChamber(), locTrg->GetHitPatternFromResponse()));