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 #include "AliMUONTriggerIO.h"
19 #include "AliMUONTriggerLut.h"
20 #include "AliMUONCalibParamNI.h"
21 #include "AliMUONVStore.h"
24 #include "AliMpHelper.h"
25 #include "AliMpConstants.h"
27 #include "AliMpFiles.h"
28 #include "AliMpDDLStore.h"
29 #include "AliMpLocalBoard.h"
30 #include "AliMpTriggerCrate.h"
31 #include "AliMUONGlobalCrateConfig.h"
32 #include "AliMUONRegionalTriggerConfig.h"
33 #include "AliMUONTriggerCrateConfig.h"
37 #include <Riostream.h>
40 /// \class AliMUONTriggerIO
42 /// Handles read/write of masks and LUT to/from online files,
43 /// to be used by Shuttle and Trigger DA.
45 /// \author Laurent Aphecetche, Christian Finck Subatech
46 /// \author Bogdan Vulpescu, LPC Clermont-Ferrand
52 ClassImp(AliMUONTriggerIO)
56 const UInt_t AliMUONTriggerIO::fgkLocalLutSize = 1 << 14; // 16384
58 //_____________________________________________________________________________
59 AliMUONTriggerIO::AliMUONTriggerIO()
66 //_____________________________________________________________________________
67 AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead)
72 ReadRegionalConfig(regionalFileToRead,0);
75 //_____________________________________________________________________________
76 AliMUONTriggerIO::~AliMUONTriggerIO()
81 //_____________________________________________________________________________
83 AliMUONTriggerIO::DeCompAddress(UChar_t &ypos, UChar_t &ytri, UChar_t &xdev, UChar_t &xpos,
84 UShort_t address) const
86 /// decompose the 15-bits address
91 // UChar_t bitsXpos = 5;
93 UShort_t maskYpos = 0x000F; // ...0 00001111
94 UShort_t maskYtri = 0x0001; // ...0 00000001
95 UShort_t maskXdev = 0x001F; // ...0 00011111
96 UShort_t maskXpos = 0x001F; // ...0 00011111
98 ypos = address & maskYpos;
99 ytri = (address >> bitsYpos) & maskYtri;
100 xdev = (address >> (bitsYpos+bitsYtri)) & maskXdev;
101 xpos = (address >> (bitsYpos+bitsYtri+bitsXdev)) & maskXpos;
103 // convert deviation format
104 // online: sign 1bit , dev 4bit
108 // 0 0 mu+, mu- infinite momentum (unde)
114 // - 15 mu+, mu- infinite momentum (unde)
116 Int_t iXdevOff, iXdevOn, iXdev, sign;
122 iXdevOn += iXdev & 0x0F;
123 sign += (iXdev >> 4) & 0x01;
135 iXdevOff = - iXdevOn + 15; // gives range 0-14
137 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
147 //_____________________________________________________________________________
149 AliMUONTriggerIO::FillLut(AliMUONTriggerLut& lut,
150 Int_t icirc, UChar_t istripX, UChar_t idev,
151 Int_t lutLpt[16][2], Int_t lutHpt[16][2])
153 /// Fill the LUT histograms
155 if (icirc == 0 && istripX == 0 && idev == 0)
157 AliDebug(1,"Copy board, not filled ...");
161 Short_t iLptPlus, iLptMinu, iLptUnde;
162 Short_t iHptPlus, iHptMinu, iHptUnde;
164 iLptPlus = iLptMinu = iLptUnde = 0;
165 iHptPlus = iHptMinu = iHptUnde = 0;
167 for (Int_t istripY=0; istripY<16; istripY++)
169 if (lutLpt[istripY][1] == 0 && lutLpt[istripY][0] ==1)
170 iLptMinu=iLptMinu+(1 << istripY);
171 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==0)
172 iLptPlus=iLptPlus+(1 << istripY);
173 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==1)
174 iLptUnde=iLptUnde+(1 << istripY);
176 if (lutHpt[istripY][1] == 0 && lutHpt[istripY][0] ==1)
177 iHptMinu=iHptMinu+(1 << istripY);
178 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==0)
179 iHptPlus=iHptPlus+(1 << istripY);
180 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==1)
181 iHptUnde=iHptUnde+(1 << istripY);
185 lut.SetContent("LptMinu",icirc,istripX,idev,iLptMinu);
186 lut.SetContent("LptUnde",icirc,istripX,idev,iLptUnde);
187 lut.SetContent("LptPlus",icirc,istripX,idev,iLptPlus);
189 lut.SetContent("HptMinu",icirc,istripX,idev,iHptMinu);
190 lut.SetContent("HptUnde",icirc,istripX,idev,iHptUnde);
191 lut.SetContent("HptPlus",icirc,istripX,idev,iHptPlus);
194 //_____________________________________________________________________________
196 AliMUONTriggerIO::ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const
198 /// Fills the local masks store from file
200 if ( !NofLocalBoards() )
202 AliError("No local board to read");
206 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"r");
209 AliError(Form("Could not read file %s",localFile));
213 UShort_t maskBuffer[8];
215 Int_t localBoardIndex(0);
217 while ( fread ( maskBuffer, 2, 8, fp ) )
219 Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
220 AliDebug(1,Form("LB %03d X1 %4x X2 %4x X3 %4x X4 %4x "
221 "Y1 %4x Y2 %4x Y3 %4x Y4 %4x",
232 if ( localBoardId > 0 )
234 AliMUONVCalibParam* localBoard = new AliMUONCalibParamNI(1,8,localBoardId,0,0);
235 for ( Int_t index = 0; index < 8; ++index )
237 localBoard->SetValueAsInt(index,0,maskBuffer[index]);
239 localMasks.Add(localBoard);
243 AliError(Form("Oups. Got localBoardId=%d for index=%d",localBoardId,localBoardIndex));
249 if ( localBoardIndex != NofLocalBoards() )
251 AliError(Form("Read %d out of %d local boards",
252 localBoardIndex, NofLocalBoards()));
257 return localBoardIndex+1;
260 //_____________________________________________________________________________
262 AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut,
266 /// Read the LUT for one local board from an online file
270 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
271 UChar_t mask1 = 0xF0;
272 UChar_t mask2 = 0x0F;
273 UChar_t maskHpt = 0x0C;
274 UChar_t maskLpt = 0x03;
275 UChar_t lh, lpt, hpt;
277 UChar_t xpos, xdev, ypos, ytri;
279 Int_t lutLpt[16][2], lutHpt[16][2];
281 Int_t boardnr = localBoardId;
283 AliDebug(1,Form("Reading LUT values for local board %d",boardnr));
286 Bool_t trigx = kFALSE;
288 // read two lut addresses at once, 32768/2=16384 times
289 if (fread(buffer,fgkLocalLutSize,1,flut) == 0) {
290 AliWarning("Error reading the LUT file");
294 // create the 32767 addresses for the 4-bits lpt and hpt half-bytes
295 for (UShort_t ilut = 0; ilut < fgkLocalLutSize*2; ilut += 2)
298 // 1st 4-bits half-byte
300 lh = (buffer[ilut/2] & mask1) >> 4;
302 // Lpt and Hpt response
303 hpt = (lh & maskHpt) >> 2;
306 // decompose the 15-bits address
307 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
309 // calculate group of y-strips
310 if (trigx && (ny < 16))
312 lutLpt[ny][0] = lpt & 1;
313 lutLpt[ny][1] = (lpt & 2) >> 1;
314 lutHpt[ny][0] = hpt & 1;
315 lutHpt[ny][1] = (hpt & 2) >> 1;
320 // ytri == 1 means no trigger in y-direction
323 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
328 // 2nd 4-bits half-byte
330 lh = (buffer[ilut/2] & mask2);
332 // Lpt and Hpt response
333 hpt = (lh & maskHpt) >> 2;
336 // decompose the 15-bits address
337 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
339 // calculate group of y-strips
340 if (trigx && (ny < 16))
342 lutLpt[ny][0] = lpt & 1;
343 lutLpt[ny][1] = (lpt & 2) >> 1;
344 lutHpt[ny][0] = hpt & 1;
345 lutHpt[ny][1] = (hpt & 2) >> 1;
350 // ytri == 1 means no trigger in y-direction
353 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
360 //_____________________________________________________________________________
362 AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut)
364 /// Fill the LUT object from online file
366 if ( !NofLocalBoards() )
368 AliError("No local board id defined. Must read a regional file first");
372 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToRead),"rb");
375 AliError(Form("Could not read LUT file %s",lutFileToRead));
379 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
381 ReadLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
385 // 1st/2nd cut code pt cut [GeV/c]
387 // 0 0.5 (a.k.a. Apt)
388 // 1 1.0 (a.k.a. Lpt)
389 // 2 1.7 (a.k.a. Hpt)
390 // 3 4.2 (a.k.a. infinity)
395 //15 default (for backward compatibility)
397 UChar_t lutCode = 0xFF;
399 if (!fread(&lutCode,1,1,flut)) {
400 AliWarning("No LUT info in the file (old version)");
402 AliInfo(Form("LUT code: 0x%02x",lutCode));
406 lut.SetLutCode(lutCode);
412 //_____________________________________________________________________________
414 AliMUONTriggerIO::ReadConfig(const char* localFile,
415 const char* regionalFile,
416 const char* globalFile,
417 AliMUONVStore* localMasks,
418 AliMUONRegionalTriggerConfig* regionalConfig,
419 AliMUONGlobalCrateConfig* globalConfig)
421 /// Fill the various masks store from files
423 if ( !regionalConfig || !regionalFile || strlen(regionalFile)==0 )
425 AliError("Must have a regional file name to proceeed");
429 AliDebug(1,Form("regionalConfig=%p",regionalConfig));
431 Int_t nCrates = ReadRegionalConfig(regionalFile, regionalConfig);
435 AliError("nCrates=0 !");
439 if (localMasks && localFile && strlen(localFile) > 0 )
441 Int_t nLocal = ReadLocalMasks(localFile,*localMasks);
442 AliDebug(1,Form("Read masks for %d local boards",nLocal));
445 Int_t nDarc = ReadGlobalConfig(globalFile, globalConfig);
446 AliDebug(1,Form("Read config for %d DARC boards",nDarc));
448 if (!nDarc) return kFALSE;
455 //_____________________________________________________________________________
457 AliMUONTriggerIO::ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
459 /// read the global crate file
460 /// the masks are disable bit for each crate, 8 per darc board
461 /// bit value 0 means enable, 1 means disable *
464 if ( !(nDarc = globalConfig->ReadData(globalFile)) ) return 0;
469 //_____________________________________________________________________________
471 AliMUONTriggerIO::ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig)
473 /// Read regional file to fill
475 AliDebug(1,Form("regionalConfig=%p",regionalConfig));
478 if ( !(nCrates = regionalConfig->ReadData(regionalFile)) ) return 0;
480 // read the mapping file also
481 if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0;
487 //_____________________________________________________________________________
489 AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut,
490 const char* lutFileToWrite)
492 /// Convert an offline lut into an online (binary) lut file
494 if ( !NofLocalBoards() )
496 AliError("No local board id defined. Must read a regional file first");
500 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToWrite),"wb");
503 AliError(Form("Could not create output LUT file %s",lutFileToWrite));
507 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
509 WriteLocalLUT(lut,fRegionalTrigger.LocalBoardId(i),flut);
518 //_____________________________________________________________________________
520 AliMUONTriggerIO::WriteConfig(const char* localFile,
521 const char* regionalFile,
522 const char* globalFile,
523 const AliMUONVStore* localMasks,
524 AliMUONRegionalTriggerConfig* regionalConfig,
525 AliMUONGlobalCrateConfig* globalConfig) const
527 /// write config files
530 ok = WriteLocalMasks(localFile, *localMasks);
531 ok &= WriteRegionalConfig(regionalFile, regionalConfig);
532 ok &= WriteGlobalConfig(globalFile, globalConfig);
540 //_____________________________________________________________________________
542 AliMUONTriggerIO::WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
544 /// write global config
549 out.open(globalFile);
552 AliError(Form("Could not create output global file %s", globalFile));
556 out << globalConfig->GetName() << endl;
557 out << Form("0x%x",globalConfig->GetGlobalCrateEnable()) << endl;
560 out << globalConfig->GetJtagName() << endl;
561 out << Form("0x%08lx", globalConfig->GetJtagVmeAddr()) << endl;
562 out << Form("%d %d %d", globalConfig->GetJtagClockDiv(),
563 globalConfig->GetJtagRxPhase(), globalConfig->GetJtagRdDelay()) << endl;
565 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
566 out << Form("%d ", globalConfig->GetEnableJtag(i));
570 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
573 for (Int_t j = 0; j < globalConfig->GetJtagNofLines(); ++j)
574 out << Form(" %s", globalConfig->GetJtagCrateName(i,j).Data()) << endl;
578 out << globalConfig->GetFirstDarcName() << endl;
579 out << Form("0x%08lx", globalConfig->GetFirstDarcVmeAddr()) << endl;
580 out << globalConfig->GetFirstDarcType() << endl;
581 disable = globalConfig->GetFirstDarcDisable();
582 out << Form("0x%02x", disable) << endl;
583 out << Form("0x%x", globalConfig->GetFirstDarcL0Delay()) << endl;
584 out << Form("0x%x", globalConfig->GetFirstDarcL1TimeOut()) << endl;
585 out << Form("0x%x", globalConfig->GetFirstDarcGlobalL0()) << endl;
586 out << Form("0x%x", globalConfig->GetFirstDarcConfig()) << endl;
589 out << globalConfig->GetSecondDarcName() << endl;
590 out << Form("0x%08lx", globalConfig->GetSecondDarcVmeAddr()) << endl;
591 out << globalConfig->GetSecondDarcType() << endl;
592 disable = globalConfig->GetSecondDarcDisable();
593 out << Form("0x%02x", disable) << endl;
594 out << Form("0x%x", globalConfig->GetSecondDarcL0Delay()) << endl;
595 out << Form("0x%x", globalConfig->GetSecondDarcL1TimeOut()) << endl;
596 out << Form("0x%x", globalConfig->GetSecondDarcGlobalL0()) << endl;
597 out << Form("0x%x", globalConfig->GetSecondDarcConfig()) << endl;
600 out << globalConfig->GetGlobalName() << endl;
601 out << Form("0x%08lx", globalConfig->GetGlobalVmeAddr()) << endl;
602 for (Int_t i = 0; i < globalConfig->GetGlobalNofRegisters(); ++i)
603 out << Form("0x%x", globalConfig->GetGlobalRegister(i)) << endl;
606 out << globalConfig->GetFetName() << endl;
607 out << Form("0x%08lx", globalConfig->GetFetVmeAddr()) << endl;
608 for (Int_t i = 0; i < globalConfig->GetFetNofRegisters(); ++i)
609 out << Form("0x%x", globalConfig->GetFetRegister(i)) << endl;
614 //_____________________________________________________________________________
616 AliMUONTriggerIO::WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const
619 /// write regional mask with the current configuration
620 /// if regional masks not defined, take the one from current configuration
623 out.open(regionalFile);
627 AliError(Form("Could not create output regional file %s",regionalFile));
631 Int_t nCrate = fRegionalTrigger.GetNofTriggerCrates();
634 AliError("Could not write regional no configuration in memory");
640 AliMpTriggerCrate* crate;
641 for (Int_t ddlId = 0; ddlId < 2; ddlId++) // right & left side
643 for (Int_t crateId = 0; crateId < 8; crateId++) // 8 crates/regional boards for each side.
646 name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
648 crate = fRegionalTrigger.FindTriggerCrate(name, false);
650 AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crate->GetName());
653 AliError(Form("Cannot find crate %s in CDB", crate->GetName()));
657 out << crate->GetName() << endl;
658 out << Form("%02x", crate->GetId()) << endl;
659 out << crateConfig->GetMode() << endl;
660 out << crateConfig->GetCoinc() << endl;
661 out << Form("%04x", crateConfig->GetMask()) << endl;
662 out << Form("%02d",crate->GetNofLocalBoards()) << endl;
664 for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal)
666 Int_t localBoardId = crate->GetLocalBoardId(iLocal);
668 AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId);
670 out << Form("%02d ", board->GetSlot())
672 << Form(" %03d ", localBoardId)
673 << Form("%03x", board->GetSwitch())
678 if (board->IsNotified()) {
679 for (Int_t i = 0; i < board->GetNofDEs(); ++i)
680 out << Form("%4d ", board->GetDEId(i));
682 out << Form("%4d ", 0);
686 // print copy card numbers & TC
687 out << Form(" %4d %4d", board->GetInputXfrom(), board->GetInputXto());
688 out << Form(" %4d %4d", board->GetInputYfrom(), board->GetInputYto());
689 out << Form(" %4d", board->GetTC()) << endl;
700 //_____________________________________________________________________________
702 AliMUONTriggerIO::WriteLocalMasks(const char* localFile, const AliMUONVStore& localMasks) const
705 /// removing/adding enable for a local board need a update of the configuration
706 /// before calling this method
707 /// mask are written for all boards including the copy card (Ch.F.)
709 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"wb");
712 AliError(Form("Could not create output local file %s",localFile));
716 UShort_t maskBuffer[8];
717 Int_t localBoardIndex(0);
718 while (localBoardIndex < NofLocalBoards()) {
720 Int_t localBoardId = fRegionalTrigger.LocalBoardId(localBoardIndex);
722 AliMUONVCalibParam* localMask =
723 static_cast<AliMUONVCalibParam*>(localMasks.FindObject(localBoardId));
725 for (Int_t index = 0; index < 8; ++index)
727 maskBuffer[index] = localMask->ValueAsInt(index,0);
730 fwrite ( maskBuffer, 2, 8, fp);
742 //_____________________________________________________________________________
744 AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut,
748 /// loop over the address for the 4-bits lpt and hpt decisions
750 const Int_t kMaskYpos = 0x0F;
751 const Int_t kMaskYtri = 0x01;
752 const Int_t kMaskXdev = 0x1F;
753 const Int_t kMaskXpos = 0x1F;
755 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
758 for (UInt_t i = 0; i < fgkLocalLutSize*2; ++i)
760 Int_t lutLpt[2] = { 0 };
761 Int_t lutHpt[2] = { 0 };
764 Int_t iYpos = i & kMaskYpos;
765 Int_t iYtri = ( i >> 4 ) & kMaskYtri;
766 Int_t iXdev = ( i >> ( 4 + 1 ) ) & kMaskXdev;
767 Int_t iXpos = ( i >> ( 4 + 1 + 5 ) ) & kMaskXpos;
769 // convert deviation format
770 // online: sign 1bit , dev 4bit
774 // 0 0 mu+, mu- infinite momentum (unde)
780 // - 15 mu+, mu- infinite momentum (unde)
784 Bool_t trigx = kFALSE;
785 iXdevOn += iXdev & 0x0F;
786 sign += (iXdev >> 4) & 0x01;
798 iXdevOff = - iXdevOn + 15; // gives range 0-14
800 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
805 // iYtri == 1 means no trigger in y-direction
806 if (iYtri == 0 && trigx)
808 lut.GetLutOutput(localBoardId,iXpos,iXdev,iYpos,lutLpt,lutHpt);
816 buffer[bc] += lutHpt[1] << 7;
817 buffer[bc] += lutHpt[0] << 6;
818 buffer[bc] += lutLpt[1] << 5;
819 buffer[bc] += lutLpt[0] << 4;
822 buffer[bc] += lutHpt[1] << 3;
823 buffer[bc] += lutHpt[0] << 2;
824 buffer[bc] += lutLpt[1] << 1;
825 buffer[bc] += lutLpt[0] << 0;
829 fwrite(&buffer,bc,1,flut);
832 //_____________________________________________________________________________
834 AliMUONTriggerIO::LocalBoardId(Int_t index) const
836 /// Return the i-th localBoardId, or -1 if index is out of bounds
838 return fRegionalTrigger.LocalBoardId(index);
842 //______________________________________________________________________________
844 Int_t AliMUONTriggerIO::LocalBoardId(Int_t ddlId, Int_t crateId, Int_t localId) const
846 /// Return local board id from crate and local indexes.
849 TString name = AliMpTriggerCrate::GenerateName(crateId, ddlId, nofDDLs);
851 AliMpTriggerCrate* crate = fRegionalTrigger.FindTriggerCrate(name, false);
852 return crate->GetLocalBoardId(localId);