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 //*-- Author: Rachid Guernane (LPCCFd)
19 //* Manager class for muon trigger electronics
20 //* Client of trigger board classes
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 "AliMUONGlobalTrigger.h"
34 #include "AliMUONData.h"
35 #include "AliMUONDigit.h"
36 #include "AliMUONSegmentation.h"
37 #include "AliMUONCalibrationData.h"
38 #include "AliMUONVCalibParam.h"
40 #include "AliMpVSegmentation.h"
43 #include "AliLoader.h"
46 //#include "Riostream.h"
50 ClassImp(AliMUONTriggerElectronics)
52 //___________________________________________
53 AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONData *Data, AliMUONCalibrationData* calibData)
54 : TTask("AliMUONTriggerElectronics",
55 "From trigger digits to Local and Global Trigger objects"),
56 fCrates(new AliMUONTriggerCrateStore),
57 fGlobalTriggerBoard(new AliMUONGlobalTriggerBoard),
64 AliFatal("NO MUON TRIGGER DATA");
72 //______________________________________________________________________________
73 AliMUONTriggerElectronics::AliMUONTriggerElectronics(const AliMUONTriggerElectronics& right)
76 /// Protected copy constructor (not implemented)
78 AliFatal("Copy constructor not provided.");
81 //___________________________________________
82 AliMUONTriggerElectronics::~AliMUONTriggerElectronics()
86 delete fGlobalTriggerBoard;
90 //______________________________________________________________________________
91 AliMUONTriggerElectronics&
92 AliMUONTriggerElectronics::operator=(const AliMUONTriggerElectronics& right)
94 /// Protected assignement operator (not implemented)
96 // check assignement to self
97 if (this == &right) return *this;
99 AliFatal("Assignement operator not provided.");
104 //___________________________________________
105 void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData)
107 //* BUILD ALL ELECTRONICS
110 fCrates->ReadFromFile(gSystem->ExpandPathName(fSourceFileName.Data()));
112 if ( !calibData ) return;
114 AliMUONTriggerLut* lut = calibData->TriggerLut();
118 AliMUONLocalTriggerBoard* localBoard;
120 fCrates->FirstLocalBoard();
122 while ( (localBoard=fCrates->NextLocalBoard()) )
124 localBoard->SetLUT(lut);
128 //___________________________________________
129 void AliMUONTriggerElectronics::FeedM()
133 for (Int_t ichamber=10; ichamber<14; ichamber++)
135 TClonesArray *muonDigits = fMUONData->Digits(ichamber);
136 Int_t ndigits = muonDigits->GetEntriesFast();
138 for (Int_t digit=0; digit<ndigits; digit++)
140 AliMUONDigit *mdig = static_cast<AliMUONDigit*>(muonDigits->UncheckedAt(digit));
142 // CHECKME ! The TrackCharge is not ok with new digitizerV3 !
143 // for (Int_t ichg=0; ichg<10; ichg++) schg += mdig->TrackCharge(ichg);
144 // assert(schg==mdig->Signal());
145 Int_t schg = mdig->Signal();
147 // APPLY CONDITION ON SOFT BACKGROUND
148 Int_t tchg = schg - (Int_t(schg/10))*10;
150 if (schg<=10 || tchg>0)
154 Int_t digitindex = digit;
155 Int_t detElemId = mdig->DetElemId();
156 Int_t cathode = mdig->Cathode();
158 const AliMpVSegmentation *seg = ((AliMUON*)gAlice->GetDetector("MUON"))->GetSegmentation()->GetMpSegmentation(detElemId,cathode);
160 Int_t ix = mdig->PadX(), iy = mdig->PadY();
162 AliDebug(3,Form("cathode %d ix %d iy %d ",cathode,ix,iy));
164 AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
166 for (Int_t i=0; i<pad.GetNofLocations(); i++)
168 AliMpIntPair location = pad.GetLocation(i);
170 Int_t nboard = location.GetFirst();
172 Int_t ibitxy = location.GetSecond();
174 AliMUONLocalTriggerBoard *b = fCrates->LocalBoard(nboard);
178 if (cathode && b->GetSwitch(6)) ibitxy += 8;
180 b->SetbitM(ibitxy,cathode,ichamber-10);
182 DigitFiredCircuit(b->GetI(), cathode, ichamber, digitindex);
186 AliError(Form("Could not get local board number %d",b->GetNumber()));
193 // Particular case of the columns with 22 local boards (2R(L) 3R(L))
194 AliMUONTriggerCrate *crate = 0x0; TObjArray *bs = 0x0;
196 char *scratess[4] = { "2R", "2L", "3L", "3R"};
197 char *scratesd[4] = {"2-3R", "2-3L", "2-3L", "2-3R"};
198 Int_t slotf[4] = { 2, 2, 10, 10};
199 Int_t slotd[4] = { 1, 1, 9, 9};
201 for (Int_t i=0; i<4; i++)
203 crate = fCrates->Crate(scratess[i]);
204 bs = crate->Boards();
205 AliMUONLocalTriggerBoard *desybb = (AliMUONLocalTriggerBoard*)bs->At(14);
206 AliMUONLocalTriggerBoard *fromcb = (AliMUONLocalTriggerBoard*)bs->At(15);
207 AliMUONLocalTriggerBoard *desxbb = (AliMUONLocalTriggerBoard*)bs->At(16);
209 crate = fCrates->Crate(scratesd[i]);
210 bs = crate->Boards();
211 AliMUONLocalTriggerBoard *frombb = (AliMUONLocalTriggerBoard*)bs->At(slotf[i]);
212 AliMUONLocalTriggerBoard *desycb = (AliMUONLocalTriggerBoard*)bs->At(slotd[i]);
216 // COPY X3-4 FROM BOARD 2 OF CRATE 2-3 TO BOARD 16 OF CRATE 2
217 // COPY X3-4 FROM BOARD 10 OF CRATE 2-3 TO BOARD 16 OF CRATE 3
218 frombb->GetX34(cX); desxbb->SetX34(cX);
220 // COPY X3-4 FROM BOARD 15 OF CRATE 2 TO BOARD 1 OF CRATE 2-3
221 // COPY X3-4 FROM BOARD 15 OF CRATE 3 TO BOARD 9 OF CRATE 2-3
222 fromcb->GetX34(cX); desycb->SetX34(cX);
226 desybb->GetY(cY); frombb->SetY(cY);
228 frombb->GetY(cY); desxbb->SetY(cY);
229 fromcb->GetY(cY); desycb->SetY(cY);
232 // FILL UP/DOWN OF CURRENT BOARD (DONE VIA J3 BUS IN REAL LIFE)
233 AliMUONTriggerCrate* cr;
235 fCrates->FirstCrate();
237 while ( ( cr = fCrates->NextCrate() ) )
239 TObjArray *boards = cr->Boards();
241 for (Int_t j=1; j<boards->GetEntries()-1; j++)
243 TObject *o = boards->At(j);
247 AliMUONLocalTriggerBoard *currboard = (AliMUONLocalTriggerBoard*)o;
249 AliMUONLocalTriggerBoard *neighbour = (AliMUONLocalTriggerBoard*)boards->At(j+1);
253 if (j==1) {neighbour->GetXY(cXY); currboard->SetXYU(cXY);}
255 // LAST BOARD IN THE CRATE HAS NO UP EXCEPT FOR CRATES 2 & 3
256 if (j<boards->GetEntries()-2)
258 AliMUONLocalTriggerBoard *nextboard = (AliMUONLocalTriggerBoard*)boards->At(j+2);
260 currboard->GetXY(cXY); neighbour->SetXYD(cXY);
261 nextboard->GetXY(cXY); neighbour->SetXYU(cXY);
263 if (j==boards->GetEntries()-3) {neighbour->GetXY(cXY); nextboard->SetXYD(cXY);}
269 //___________________________________________
270 void AliMUONTriggerElectronics::Feed(UShort_t pattern[2][4])
274 AliMUONTriggerCrate* cr;
276 fCrates->FirstCrate();
278 while ( ( cr = fCrates->NextCrate() ) )
280 TObjArray *boards = cr->Boards();
282 for (Int_t j=1; j<boards->GetEntries(); j++)
284 TObject *o = boards->At(j);
288 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
290 board->SetXY(pattern);
295 //___________________________________________
296 void AliMUONTriggerElectronics::DumpOS()
298 //* DUMP IN THE OLD WAY
300 for (Int_t i=0;i<234;i++)
302 AliMUONLocalTriggerBoard *board = fCrates->LocalBoard(i);
304 if (board) board->Scan("ALL");
308 //___________________________________________
309 void AliMUONTriggerElectronics::Scan(Option_t *option)
314 AliMUONTriggerCrate* cr;
316 fCrates->FirstCrate();
318 while ( ( cr = fCrates->NextCrate() ) )
320 TObjArray *boards = cr->Boards();
322 for (Int_t j=0; j<boards->GetEntries(); j++)
324 TObject *o = boards->At(j);
328 Bool_t cdtion = kFALSE;
330 if (op.Contains("LOCAL")) cdtion = o->IsA() == AliMUONLocalTriggerBoard::Class();
331 if (op.Contains("REGIONAL")) cdtion = o->IsA() == AliMUONRegionalTriggerBoard::Class();
332 if (op.Contains("GLOBAL")) cdtion = o->IsA() == AliMUONGlobalTriggerBoard::Class();
334 if (!o || !cdtion) continue;
336 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
343 //___________________________________________
344 void AliMUONTriggerElectronics::Reset()
349 AliMUONTriggerCrate* cr;
351 fCrates->FirstCrate();
353 while ( ( cr = fCrates->NextCrate() ) )
355 TObjArray *boards = cr->Boards();
357 for (Int_t j=0; j<boards->GetEntries(); j++)
359 AliMUONTriggerBoard *b = (AliMUONTriggerBoard*)boards->At(j);
366 //_______________________________________________________________________
367 void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData)
369 // LOAD MASKS FROM CDB
374 AliMUONTriggerCrate* cr;
376 fCrates->FirstCrate();
380 while ( ( cr = fCrates->NextCrate() ) )
382 TObjArray *boards = cr->Boards();
384 AliMUONRegionalTriggerBoard *regb =
385 (AliMUONRegionalTriggerBoard*)boards->At(0);
387 AliMUONVCalibParam* regionalBoardMasks = calibData->RegionalTriggerBoardMasks(irb);
389 for ( Int_t i = 0; i < regionalBoardMasks->Size(); ++i )
391 UShort_t rmask = static_cast<UShort_t>(regionalBoardMasks->ValueAsInt(i) & 0x3F);
395 for (Int_t j=1; j<boards->GetEntries(); j++)
397 AliMUONLocalTriggerBoard *b = (AliMUONLocalTriggerBoard*)boards->At(j);
399 Int_t cardNumber = b->GetNumber();
401 if (cardNumber) // interface board are not interested
403 AliMUONVCalibParam* localBoardMasks = calibData->LocalTriggerBoardMasks(cardNumber);
404 for ( Int_t i = 0; i < localBoardMasks->Size(); ++i )
406 UShort_t lmask = static_cast<UShort_t>(localBoardMasks->ValueAsInt(i) & 0xFFFF);
414 AliMUONVCalibParam* globalBoardMasks = calibData->GlobalTriggerBoardMasks();
415 for ( Int_t i = 0; i < globalBoardMasks->Size(); ++i )
417 UShort_t gmask = static_cast<UShort_t>(globalBoardMasks->ValueAsInt(i) & 0xFFF);
418 fGlobalTriggerBoard->Mask(i,gmask);
423 //___________________________________________
424 void AliMUONTriggerElectronics::LocalResponse()
434 crate[0].name = "2R"; crate[0].ns = 1; crate[0].slots[0] = 16;
435 crate[1].name = "2L"; crate[1].ns = 1; crate[1].slots[0] = 16;
436 crate[2].name = "3L"; crate[2].ns = 1; crate[2].slots[0] = 16;
437 crate[3].name = "3R"; crate[3].ns = 1; crate[3].slots[0] = 16;
438 crate[4].name = "2-3R"; crate[4].ns = 2; crate[4].slots[0] = 1; crate[4].slots[1] = 9;
439 crate[5].name = "2-3L"; crate[5].ns = 2; crate[5].slots[0] = 1; crate[5].slots[1] = 9;
441 AliMUONTriggerCrate* cr;
443 fCrates->FirstCrate();
445 while ( ( cr = fCrates->NextCrate() ) )
449 for (Int_t icr=0; icr<6; icr++)
451 const char *n = (crate[icr].name).Data();
453 AliMUONTriggerCrate *dcr = fCrates->Crate(n);
455 // THIS CRATE CONTAINS AN INTERFACE BOARD
456 if ( dcr && !strcmp(cr->GetName(),dcr->GetName()) ) iib = icr;
459 TObjArray *boards = cr->Boards();
461 AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
463 UShort_t thisl[16]; for (Int_t j=0; j<16; j++) thisl[j] = 0;
465 for (Int_t j=1; j<boards->GetEntries(); j++)
467 TObject *o = boards->At(j);
471 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
477 UShort_t tmp = board->GetResponse();
479 // CRATE CONTAINING INTERFACE BOARD
482 for (Int_t iid = 0; iid<crate[iib].ns; iid++)
484 if ( j == crate[iib].slots[iid] )
487 AliWarning(Form("Interface board %s in slot %d of crate %s has a non zero response",
488 board->GetName(),j,cr->GetName()));
497 regb->SetLocalResponse(thisl);
501 //___________________________________________
502 void AliMUONTriggerElectronics::RegionalResponse()
504 /// Compute the response for all regional cards.
505 AliMUONTriggerCrate* cr;
507 fCrates->FirstCrate();
509 while ( ( cr = fCrates->NextCrate() ) )
511 TObjArray *boards = cr->Boards();
513 AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0);
522 //___________________________________________
523 void AliMUONTriggerElectronics::GlobalResponse()
525 /// Compute the global response
527 UShort_t regional[16];
529 AliMUONTriggerCrate* cr;
531 fCrates->FirstCrate();
534 if ( !fCrates->NumberOfCrates() >= 16 )
536 AliFatal(Form("Something is wrong : too many crates %d",
537 fCrates->NumberOfCrates()));
540 while ( ( cr = fCrates->NextCrate() ) )
542 AliMUONTriggerBoard* rb =
543 static_cast<AliMUONTriggerBoard*>(cr->Boards()->At(0));
544 regional[irb] = rb->GetResponse();
548 fGlobalTriggerBoard->SetRegionalResponse(regional);
549 fGlobalTriggerBoard->Response();
552 //___________________________________________
553 void AliMUONTriggerElectronics::BoardName(Int_t ix, Int_t iy, char *name)
555 //* BOARD NAME FROM PAD INFO (OLD MAPPING)
557 TString s = (ix>0) ? "R" : "L";
559 Int_t board = iy / 16, bid[4] = {12,34,56,78};
563 Int_t line = ix / 10, column = ix - 10 * line;
565 // old scheme: line==1 is line==9
566 line -= 9; line = TMath::Abs(line); line++;
568 sprintf(name,"%sC%dL%dB%d", s.Data(), column, line, bid[board]);
570 AliDebug(3, Form("Strip ( %d , %d ) connected to board %s ", ix, iy, name));
573 //___________________________________________
574 void AliMUONTriggerElectronics::BuildName(Int_t icirc, char name[20])
576 //* GET BOARD NAME FROM OLD NUMBERING
578 const Int_t kCircuitId[234] =
580 111, 121, 131, 141, 151, 161, 171,
581 211, 212, 221, 222, 231, 232, 241, 242, 251, 252, 261, 262, 271,
582 311, 312, 321, 322, 331, 332, 341, 342, 351, 352, 361, 362, 371,
583 411, 412, 413, 421, 422, 423, 424, 431, 432, 433, 434, 441, 442, 451, 452, 461, 462, 471,
584 521, 522, 523, 524, 531, 532, 533, 534, 541, 542, 551, 552, 561, 562, 571,
585 611, 612, 613, 621, 622, 623, 624, 631, 632, 633, 634, 641, 642, 651, 652, 661, 662, 671,
586 711, 712, 721, 722, 731, 732, 741, 742, 751, 752, 761, 762, 771,
587 811, 812, 821, 822, 831, 832, 841, 842, 851, 852, 861, 862, 871,
588 911, 921, 931, 941, 951, 961, 971,
589 -111, -121, -131, -141, -151, -161, -171,
590 -211, -212, -221, -222, -231, -232, -241, -242, -251, -252, -261, -262, -271,
591 -311, -312, -321, -322, -331, -332, -341, -342, -351, -352, -361, -362, -371,
592 -411, -412, -413, -421, -422, -423, -424, -431, -432, -433, -434, -441, -442, -451, -452, -461, -462, -471,
593 -521, -522, -523, -524, -531, -532, -533, -534, -541, -542, -551, -552, -561, -562, -571,
594 -611, -612, -613, -621, -622, -623, -624, -631, -632, -633, -634, -641, -642, -651, -652, -661, -662, -671,
595 -711, -712, -721, -722, -731, -732, -741, -742, -751, -752, -761, -762, -771,
596 -811, -812, -821, -822, -831, -832, -841, -842, -851, -852, -861, -862, -871,
597 -911, -921, -931, -941, -951, -961, -971
600 Int_t b[4] = {12, 34, 56, 78};
602 Int_t code = TMath::Abs(kCircuitId[icirc]);
604 Int_t lL = code / 100;
606 Int_t cC = ( code - 100 * lL ) / 10;
608 Int_t bB = code - 100 * lL - 10 * cC;
610 const char *side = (kCircuitId[icirc]>0) ? "R" : "L";
613 lL -= 9; lL = abs(lL); lL++;
615 sprintf(name,"%sC%dL%dB%d",side,cC,lL,b[bB-1]);
618 //_______________________________________________________________________
620 AliMUONTriggerElectronics::Exec(Option_t*)
627 //_______________________________________________________________________
628 void AliMUONTriggerElectronics::Trigger()
638 //_______________________________________________________________________
639 void AliMUONTriggerElectronics::Digits2Trigger()
641 /// Main method to go from digits to trigger decision
645 fMUONData->ResetTrigger();
647 // RUN THE FULL BEE CHAIN
651 AliMUONTriggerCrate* cr;
653 fCrates->FirstCrate();
655 while ( ( cr = fCrates->NextCrate() ) )
657 TObjArray *boards = cr->Boards();
659 for (Int_t j=1; j<boards->GetEntries(); j++)
661 TObject *o = boards->At(j);
665 AliMUONLocalTriggerBoard *board = (AliMUONLocalTriggerBoard*)o;
670 if (board->Triggered())
672 Int_t localtr[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
674 Int_t icirc = board->GetNumber();
677 localtr[1] = board->GetStripX11();
678 localtr[2] = board->GetDev();
679 localtr[3] = board->GetStripY11();
682 UShort_t response = board->GetResponse();
683 localtr[4] = (response & 12) >> 2;
684 localtr[5] = (response & 48) >> 4;
685 localtr[6] = (response & 3);
688 rrr.Set(6,&response);
691 localtr[7] = board->GetXY(0,0);
692 localtr[8] = board->GetXY(0,1);
693 localtr[9] = board->GetXY(0,2);
694 localtr[10] = board->GetXY(0,3);
696 localtr[11] = board->GetXY(1,0);
697 localtr[12] = board->GetXY(1,1);
698 localtr[13] = board->GetXY(1,2);
699 localtr[14] = board->GetXY(1,3);
701 // ADD A NEW LOCAL TRIGGER
702 AliMUONLocalTrigger *pLocTrig = new AliMUONLocalTrigger(localtr, fDigitNumbers[icirc]);
704 fMUONData->AddLocalTrigger(*pLocTrig);
710 // GLOBAL TRIGGER INFORMATION: [0] -> LOW PT
713 Int_t globalSinglePlus[3], globalSingleMinus[3], globalSingleUndef[3];
714 Int_t globalPairUnlike[3], globalPairLike[3];
716 UShort_t global = fGlobalTriggerBoard->GetResponse();
718 globalPairUnlike[0] = (global & 16) >> 4;
719 globalPairUnlike[1] = (global & 256) >> 8;
720 globalPairUnlike[2] = (global & 1);
722 globalPairLike[0] = (global & 32) >> 5;
723 globalPairLike[1] = (global & 512) >> 9;
724 globalPairLike[2] = (global & 2) >> 1;
726 globalSinglePlus[0] = ((global & 192) >> 6) == 2;
727 globalSinglePlus[1] = ((global & 3072) >> 10) == 2;
728 globalSinglePlus[2] = ((global & 12) >> 2) == 2;
730 globalSingleMinus[0] = ((global & 192) >> 6) == 1;
731 globalSingleMinus[1] = ((global & 3072) >> 10) == 1;
732 globalSingleMinus[2] = ((global & 12) >> 2) == 1;
734 globalSingleUndef[0] = ((global & 192) >> 6) == 3;
735 globalSingleUndef[1] = ((global & 3072) >> 10) == 3;
736 globalSingleUndef[2] = ((global & 12) >> 2) == 3;
738 AliMUONGlobalTrigger *pGloTrig = new AliMUONGlobalTrigger(globalSinglePlus, globalSingleMinus,
739 globalSingleUndef, globalPairUnlike,
742 // ADD A LOCAL TRIGGER IN THE LIST
743 fMUONData->AddGlobalTrigger(*pGloTrig);
745 // NOW RESET ELECTRONICS
749 //_______________________________________________________________________
750 void AliMUONTriggerElectronics::ClearDigitNumbers()
752 // RESET fDigitNumbers
753 for (Int_t i=0; i<AliMUONConstants::NTriggerCircuit(); i++) fDigitNumbers[i].Set(0);
756 //_______________________________________________________________________
757 void AliMUONTriggerElectronics::DigitFiredCircuit(Int_t circuit, Int_t cathode,
758 Int_t chamber, Int_t digit)
760 // REGISTERS THAT THE SPECIFIED DIGIT FIRED THE SPECIFIED CIRCUIT
761 // THIS DIGIT GETS ADDED TO AN ARRAY WHICH WILL BE COPIED TO
762 // AliMUONLocalTrigger WHEN SUCH AN OBJECT IS CREATED FOR EACH CIRCUIT
763 Int_t digitnumber = AliMUONLocalTrigger::EncodeDigitNumber(chamber, cathode, digit);
764 Int_t last = fDigitNumbers[circuit].GetSize();
765 fDigitNumbers[circuit].Set(last + 1);
766 fDigitNumbers[circuit][last] = digitnumber;