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
49 ClassImp(AliMUONTriggerIO)
53 const UInt_t AliMUONTriggerIO::fgkLocalLutSize = 1 << 14; // 16384
55 //_____________________________________________________________________________
56 AliMUONTriggerIO::AliMUONTriggerIO()
64 //_____________________________________________________________________________
65 AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead)
71 ReadRegionalConfig(regionalFileToRead,0);
74 //_____________________________________________________________________________
75 AliMUONTriggerIO::~AliMUONTriggerIO()
80 //_____________________________________________________________________________
82 AliMUONTriggerIO::DeCompAddress(UChar_t &ypos, UChar_t &ytri, UChar_t &xdev, UChar_t &xpos,
83 UShort_t address) const
85 /// decompose the 15-bits address
90 // UChar_t bitsXpos = 5;
92 UShort_t maskYpos = 0x000F; // ...0 00001111
93 UShort_t maskYtri = 0x0001; // ...0 00000001
94 UShort_t maskXdev = 0x001F; // ...0 00011111
95 UShort_t maskXpos = 0x001F; // ...0 00011111
97 ypos = address & maskYpos;
98 ytri = (address >> bitsYpos) & maskYtri;
99 xdev = (address >> (bitsYpos+bitsYtri)) & maskXdev;
100 xpos = (address >> (bitsYpos+bitsYtri+bitsXdev)) & maskXpos;
102 // convert deviation format
103 // online: sign 1bit , dev 4bit
107 // 0 0 mu+, mu- infinite momentum (unde)
113 // - 15 mu+, mu- infinite momentum (unde)
115 Int_t iXdevOff, iXdevOn, iXdev, sign;
121 iXdevOn += iXdev & 0x0F;
122 sign += (iXdev >> 4) & 0x01;
134 iXdevOff = - iXdevOn + 15; // gives range 0-14
136 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
146 //_____________________________________________________________________________
148 AliMUONTriggerIO::FillLut(AliMUONTriggerLut& lut,
149 Int_t icirc, UChar_t istripX, UChar_t idev,
150 Int_t lutLpt[16][2], Int_t lutHpt[16][2])
152 /// Fill the LUT histograms
154 if (icirc == 0 && istripX == 0 && idev == 0)
156 AliDebug(1,"Copy board, not filled ...");
160 Short_t iLptPlus, iLptMinu, iLptUnde;
161 Short_t iHptPlus, iHptMinu, iHptUnde;
163 iLptPlus = iLptMinu = iLptUnde = 0;
164 iHptPlus = iHptMinu = iHptUnde = 0;
166 for (Int_t istripY=0; istripY<16; istripY++)
168 if (lutLpt[istripY][1] == 0 && lutLpt[istripY][0] ==1)
169 iLptMinu=iLptMinu+(1 << istripY);
170 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==0)
171 iLptPlus=iLptPlus+(1 << istripY);
172 if (lutLpt[istripY][1] == 1 && lutLpt[istripY][0] ==1)
173 iLptUnde=iLptUnde+(1 << istripY);
175 if (lutHpt[istripY][1] == 0 && lutHpt[istripY][0] ==1)
176 iHptMinu=iHptMinu+(1 << istripY);
177 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==0)
178 iHptPlus=iHptPlus+(1 << istripY);
179 if (lutHpt[istripY][1] == 1 && lutHpt[istripY][0] ==1)
180 iHptUnde=iHptUnde+(1 << istripY);
184 lut.SetContent("LptMinu",icirc,istripX,idev,iLptMinu);
185 lut.SetContent("LptUnde",icirc,istripX,idev,iLptUnde);
186 lut.SetContent("LptPlus",icirc,istripX,idev,iLptPlus);
188 lut.SetContent("HptMinu",icirc,istripX,idev,iHptMinu);
189 lut.SetContent("HptUnde",icirc,istripX,idev,iHptUnde);
190 lut.SetContent("HptPlus",icirc,istripX,idev,iHptPlus);
193 //_____________________________________________________________________________
195 AliMUONTriggerIO::ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const
197 /// Fills the local masks store from file
199 if ( !NofLocalBoards() )
201 AliError("No local board to read");
205 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"r");
208 AliError(Form("Could not read file %s",localFile));
212 UShort_t maskBuffer[8];
214 Int_t nLocalBoards(0);
216 while ( fread ( maskBuffer, 2, 8, fp ) )
218 Int_t localBoardId = LocalBoardId(nLocalBoards);
219 AliDebug(1,Form("LB %03d X1 %4x X2 %4x X3 %4x X4 %4x "
220 "Y1 %4x Y2 %4x Y3 %4x Y4 %4x",
233 AliMUONVCalibParam* localBoard = new AliMUONCalibParamNI(1,8,localBoardId,0,0);
234 for ( Int_t index = 0; index < 8; ++index )
236 localBoard->SetValueAsInt(index,0,maskBuffer[index]);
238 localMasks.Add(localBoard);
244 if ( nLocalBoards != NofLocalBoards() )
246 AliError(Form("Read %d out of %d local boards",
247 nLocalBoards, NofLocalBoards()));
255 //_____________________________________________________________________________
257 AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut,
261 /// Read the LUT for one local board from an online file
265 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
266 UChar_t mask1 = 0xF0;
267 UChar_t mask2 = 0x0F;
268 UChar_t maskHpt = 0x0C;
269 UChar_t maskLpt = 0x03;
270 UChar_t lh, lpt, hpt;
272 UChar_t xpos, xdev, ypos, ytri;
274 Int_t lutLpt[16][2], lutHpt[16][2];
276 Int_t boardnr = localBoardId;
278 AliDebug(1,Form("Reading LUT values for local board %d",boardnr));
281 Bool_t trigx = kFALSE;
283 // read two lut addresses at once, 32768/2=16384 times
284 fread(buffer,fgkLocalLutSize,1,flut);
286 // create the 32767 addresses for the 4-bits lpt and hpt half-bytes
287 for (UShort_t ilut = 0; ilut < fgkLocalLutSize*2; ilut += 2)
290 // 1st 4-bits half-byte
292 lh = (buffer[ilut/2] & mask1) >> 4;
294 // Lpt and Hpt response
295 hpt = (lh & maskHpt) >> 2;
298 // decompose the 15-bits address
299 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
301 // calculate group of y-strips
302 if (trigx && (ny < 16))
304 lutLpt[ny][0] = lpt & 1;
305 lutLpt[ny][1] = (lpt & 2) >> 1;
306 lutHpt[ny][0] = hpt & 1;
307 lutHpt[ny][1] = (hpt & 2) >> 1;
312 // ytri == 1 means no trigger in y-direction
315 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
320 // 2nd 4-bits half-byte
322 lh = (buffer[ilut/2] & mask2);
324 // Lpt and Hpt response
325 hpt = (lh & maskHpt) >> 2;
328 // decompose the 15-bits address
329 trigx = DeCompAddress(ypos,ytri,xdev,xpos,address);
331 // calculate group of y-strips
332 if (trigx && (ny < 16))
334 lutLpt[ny][0] = lpt & 1;
335 lutLpt[ny][1] = (lpt & 2) >> 1;
336 lutHpt[ny][0] = hpt & 1;
337 lutHpt[ny][1] = (hpt & 2) >> 1;
342 // ytri == 1 means no trigger in y-direction
345 FillLut(lut,boardnr,xpos,xdev,lutLpt,lutHpt);
352 //_____________________________________________________________________________
354 AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut)
356 /// Fill the LUT object from online file
358 if ( !NofLocalBoards() )
360 AliError("No local board id defined. Must read a regional file first");
364 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToRead),"rb");
367 AliError(Form("Could not read LUT file %s",lutFileToRead));
371 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
373 ReadLocalLUT(lut,LocalBoardId(i),flut);
382 //_____________________________________________________________________________
384 AliMUONTriggerIO::ReadConfig(const char* localFile,
385 const char* regionalFile,
386 const char* globalFile,
387 AliMUONVStore* localMasks,
388 AliMUONRegionalTriggerConfig* regionalConfig,
389 AliMUONGlobalCrateConfig* globalConfig)
391 /// Fill the various masks store from files
395 AliError("Must have a regional file name to proceeed");
399 Int_t nCrates = ReadRegionalConfig(regionalFile, regionalConfig);
401 if (!nCrates) return kFALSE;
403 if (localMasks && localFile)
405 Int_t nLocal = ReadLocalMasks(localFile,*localMasks);
406 AliDebug(1,Form("Read masks for %d local boards",nLocal));
409 Int_t nDarc = ReadGlobalConfig(globalFile, globalConfig);
410 AliDebug(1,Form("Read disable for %d DARC boards",nDarc));
412 if (!nDarc) return kFALSE;
419 //_____________________________________________________________________________
421 AliMUONTriggerIO::ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig)
423 /// read the global crate file
424 /// the masks are disable bit for each crate, 8 per darc board
425 /// bit value 0 means enable, 1 means disable *
428 if ( !(nDarc = globalConfig->ReadData(globalFile)) ) return 0;
433 //_____________________________________________________________________________
435 AliMUONTriggerIO::ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig)
437 /// Read regional file to fill
439 if ( !(nCrates = regionalConfig->ReadData(regionalFile)) ) return 0;
441 // read the mapping file also
442 if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0;
448 //_____________________________________________________________________________
450 AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut,
451 const char* lutFileToWrite)
453 /// Convert an offline lut into an online (binary) lut file
455 if ( !NofLocalBoards() )
457 AliError("No local board id defined. Must read a regional file first");
461 FILE* flut = fopen(gSystem->ExpandPathName(lutFileToWrite),"wb");
464 AliError(Form("Could not create output LUT file %s",lutFileToWrite));
468 for ( Int_t i = 0; i < NofLocalBoards(); ++i )
470 WriteLocalLUT(lut,LocalBoardId(i),flut);
479 //_____________________________________________________________________________
481 AliMUONTriggerIO::WriteConfig(const char* localFile,
482 const char* regionalFile,
483 const char* globalFile,
484 AliMUONVStore* localMasks,
485 AliMUONRegionalTriggerConfig* regionalConfig,
486 AliMUONGlobalCrateConfig* globalConfig) const
488 /// write config files
491 ok = WriteLocalMasks(localFile, *localMasks, regionalConfig);
492 ok &= WriteRegionalConfig(regionalFile, regionalConfig);
493 ok &= WriteGlobalConfig(globalFile, globalConfig);
501 //_____________________________________________________________________________
503 AliMUONTriggerIO::WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const
505 /// write global config
510 out.open(globalFile);
513 AliError(Form("Could not create output global file %s", globalFile));
517 out << globalConfig->GetName() << endl;
518 out << globalConfig->GetGlobalCrateEnable() << endl;
521 out << globalConfig->GetJtagName() << endl;
522 out << Form("0x%08x", globalConfig->GetJtagVmeAddr()) << endl;
523 out << Form("%d %d %d", globalConfig->GetJtagClockDiv(),
524 globalConfig->GetJtagRxPhase(), globalConfig->GetJtagRdDelay()) << endl;
526 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
527 out << Form("%d ", globalConfig->GetEnableJtag(i));
531 for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i)
534 for (Int_t j = 0; j < globalConfig->GetJtagNofLines(); ++j)
535 out << Form(" %s", globalConfig->GetJtagCrateName(i,j).Data()) << endl;
539 out << globalConfig->GetFirstDarcName() << endl;
540 out << Form("0x%08x", globalConfig->GetFirstDarcVmeAddr()) << endl;
541 out << globalConfig->GetFirstDarcType() << endl;
542 disable = globalConfig->GetFirstDarcDisable();
543 out << Form("0x%02x", disable) << endl;
544 out << Form("0x%x", globalConfig->GetFirstDarcL0Delay()) << endl;
545 out << Form("0x%x", globalConfig->GetFirstDarcL1TimeOut()) << endl;
546 out << Form("0x%x", globalConfig->GetFirstDarcGlobalL0()) << endl;
547 out << Form("0x%x", globalConfig->GetFirstDarcConfig()) << endl;
550 out << globalConfig->GetSecondDarcName() << endl;
551 out << Form("0x%08x", globalConfig->GetSecondDarcVmeAddr()) << endl;
552 out << globalConfig->GetSecondDarcType() << endl;
553 disable = globalConfig->GetSecondDarcDisable();
554 out << Form("0x%02x", disable) << endl;
555 out << Form("0x%x", globalConfig->GetSecondDarcL0Delay()) << endl;
556 out << Form("0x%x", globalConfig->GetSecondDarcL1TimeOut()) << endl;
557 out << Form("0x%x", globalConfig->GetSecondDarcGlobalL0()) << endl;
558 out << Form("0x%x", globalConfig->GetSecondDarcConfig()) << endl;
561 out << globalConfig->GetGlobalName() << endl;
562 out << Form("0x%08x", globalConfig->GetGlobalVmeAddr()) << endl;
563 for (Int_t i = 0; i < globalConfig->GetGlobalNofRegisters(); ++i)
564 out << Form("0x%x", globalConfig->GetGlobalRegister(i)) << endl;
567 out << globalConfig->GetFetName() << endl;
568 out << Form("0x%08x", globalConfig->GetFetVmeAddr()) << endl;
569 for (Int_t i = 0; i < globalConfig->GetFetNofRegisters(); ++i)
570 out << Form("0x%x", globalConfig->GetFetRegister(i)) << endl;
575 //_____________________________________________________________________________
577 AliMUONTriggerIO::WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const
580 /// write regional mask with the current configuration
581 /// if regional masks not defined, take the one from current configuration
584 out.open(regionalFile);
588 AliError(Form("Could not create output regional file %s",regionalFile));
592 Int_t nCrate = fRegionalTrigger.GetNofTriggerCrates();
595 AliError("Could not write regional no configuration in memory");
600 for (Int_t iCrate = 0; iCrate < nCrate; ++iCrate)
602 AliMpTriggerCrate* crate = fRegionalTrigger.GetTriggerCrateFast(iCrate);
604 AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crate->GetName());
607 AliError(Form("Cannot find crate %s in CDB", crate->GetName()));
611 out << crate->GetName() << endl;
612 out << Form("%02x", crate->GetId()) << endl;
613 out << crateConfig->GetMode() << endl;
614 out << crateConfig->GetCoinc() << endl;
615 out << Form("%04x", crateConfig->GetMask()) << endl;
617 for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal)
619 Int_t localBoardId = crate->GetLocalBoardId(iLocal);
621 AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId);
623 out << Form("%02d ", board->GetSlot())
625 << Form(" %03d ", localBoardId)
626 << Form("%03x", board->GetSwitch())
630 for (Int_t i = 0; i < board->GetNofDEs(); ++i)
631 out << Form("%4d ", board->GetDEId(i));
634 // print copy card numbers & TC
635 out << Form(" %4d %4d", board->GetInputXfrom(), board->GetInputXto());
636 out << Form(" %4d %4d", board->GetInputYfrom(), board->GetInputYto());
637 out << Form(" %4d", board->GetTC()) << endl;
646 //_____________________________________________________________________________
648 AliMUONTriggerIO::WriteLocalMasks(const char* localFile, AliMUONVStore& localMasks, AliMUONRegionalTriggerConfig* regionalConfig) const
651 /// removing/adding enable for a local board need a update of the configuration
652 /// before calling this method
653 /// mask are written for all boards including the copy card (Ch.F.)
655 FILE* fp = fopen(gSystem->ExpandPathName(localFile),"wb");
658 AliError(Form("Could not create output local file %s",localFile));
662 UShort_t maskBuffer[8];
664 for (Int_t iCrate = 0; iCrate < regionalConfig->GetNofTriggerCrates(); ++iCrate)
666 AliMUONTriggerCrateConfig* crate = regionalConfig->GetTriggerCrateFast(iCrate);
668 UShort_t mask = crate->GetMask(); // getting mask from current config
670 for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal)
672 Int_t localBoardId = crate->GetLocalBoardId(iLocal);
674 if ( (mask >> iLocal ) & 0x1 )
676 AliMUONVCalibParam* localMask =
677 static_cast<AliMUONVCalibParam*>(localMasks.FindObject(localBoardId));
679 for (Int_t index = 0; index < 8; ++index)
681 maskBuffer[index] = localMask->ValueAsInt(index,0);
684 fwrite ( maskBuffer, 2, 8, fp);
696 //_____________________________________________________________________________
698 AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut,
702 /// loop over the address for the 4-bits lpt and hpt decisions
704 const Int_t kMaskYpos = 0x0F;
705 const Int_t kMaskYtri = 0x01;
706 const Int_t kMaskXdev = 0x1F;
707 const Int_t kMaskXpos = 0x1F;
709 UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two
712 for (UInt_t i = 0; i < fgkLocalLutSize*2; ++i)
714 Int_t lutLpt[2] = { 0 };
715 Int_t lutHpt[2] = { 0 };
718 Int_t iYpos = i & kMaskYpos;
719 Int_t iYtri = ( i >> 4 ) & kMaskYtri;
720 Int_t iXdev = ( i >> ( 4 + 1 ) ) & kMaskXdev;
721 Int_t iXpos = ( i >> ( 4 + 1 + 5 ) ) & kMaskXpos;
723 // convert deviation format
724 // online: sign 1bit , dev 4bit
728 // 0 0 mu+, mu- infinite momentum (unde)
734 // - 15 mu+, mu- infinite momentum (unde)
738 Bool_t trigx = kFALSE;
739 iXdevOn += iXdev & 0x0F;
740 sign += (iXdev >> 4) & 0x01;
752 iXdevOff = - iXdevOn + 15; // gives range 0-14
754 iXdevOff = + iXdevOn + 15; // gives range 16-30 !
759 // iYtri == 1 means no trigger in y-direction
760 if (iYtri == 0 && trigx)
762 lut.GetLutOutput(localBoardId,iXpos,iXdev,iYpos,lutLpt,lutHpt);
770 buffer[bc] += lutHpt[1] << 7;
771 buffer[bc] += lutHpt[0] << 6;
772 buffer[bc] += lutLpt[1] << 5;
773 buffer[bc] += lutLpt[0] << 4;
776 buffer[bc] += lutHpt[1] << 3;
777 buffer[bc] += lutHpt[0] << 2;
778 buffer[bc] += lutLpt[1] << 1;
779 buffer[bc] += lutLpt[0] << 0;
783 fwrite(&buffer,bc,1,flut);
786 //_____________________________________________________________________________
788 AliMUONTriggerIO::LocalBoardId(Int_t index) const
790 /// Return the i-th localBoardId, or -1 if index is out of bounds
792 AliMpLocalBoard* board = fRegionalTrigger.GetLocalBoard(index);
793 if ( ! board ) return -1;
795 return board->GetId();