From 92c23b09d8263caf283ea958a86fd82f6fe74832 Mon Sep 17 00:00:00 2001 From: ivana Date: Mon, 19 May 2008 16:00:19 +0000 Subject: [PATCH] Gros chantier trigger: - Adding new classes for the trigger configuration: AliMUONTriggerCrateConfig, AliMUONGlobalCrateConfig, AliMUONRegionalTriggerConfig - Instantiated CalibrationData in AliMUON class - Added interface for new trigger configuration object in AliMUONCDB, AliMUONCalibrationData, AliMUONTriggerIO classes - In AliMUONDigitizerV3: set CalibrationData from outside - In AliMUONTriggerCrateStore, AliMUONTriggerElectronics: added new method to create configuration from CDB - In mapping/data/stationTrigger/GlobalCrate.dat: fixed a bug in regional mask and add new members - In AliMUONRawWriter: take crate and local number from constant/mapping - In AliMUONTriggerSubprocessor: modified interface for new config objects - In AliMUONTriggerGUIbdmap, AliMUONTriggerGUI: put ugly patch to interface with TriggerCrateStore (not used anyhow ?) - In AliMUONReconstructor: removed unnecessary call to TriggerCrateStore - In MUONTRGda.cxx: changed interface and added method to write into online DB - In AliMpDDLStore: removed AliMpGlobalCrate object - In AliMpRegionalTrigger: skipping coicidence, mode & mask while reading file - In AliMpTriggerCrate: removed coincidence, mode and mask as members (Christian) --- MUON/AliMUON.cxx | 28 +- MUON/AliMUON.h | 7 +- MUON/AliMUONCDB.cxx | 58 ++- MUON/AliMUONCDB.h | 14 +- MUON/AliMUONCalibrationData.cxx | 82 ++-- MUON/AliMUONCalibrationData.h | 22 +- MUON/AliMUONDigitizerV3.cxx | 12 +- MUON/AliMUONDigitizerV3.h | 6 +- MUON/AliMUONGlobalCrateConfig.cxx | 401 ++++++++++++++++++ MUON/AliMUONGlobalCrateConfig.h | 251 +++++++++++ MUON/AliMUONRawWriter.cxx | 15 +- MUON/AliMUONReconstructor.cxx | 14 - MUON/AliMUONReconstructor.h | 4 +- MUON/AliMUONRegionalTriggerConfig.cxx | 213 ++++++++++ MUON/AliMUONRegionalTriggerConfig.h | 72 ++++ MUON/AliMUONTriggerCrateConfig.cxx | 117 +++++ MUON/AliMUONTriggerCrateConfig.h | 89 ++++ MUON/AliMUONTriggerCrateStore.cxx | 42 +- MUON/AliMUONTriggerCrateStore.h | 4 +- MUON/AliMUONTriggerElectronics.cxx | 94 ++-- MUON/AliMUONTriggerGUI.cxx | 2 +- MUON/AliMUONTriggerGUIbdmap.cxx | 2 +- MUON/AliMUONTriggerIO.cxx | 315 +++++--------- MUON/AliMUONTriggerIO.h | 62 +-- MUON/AliMUONTriggerSubprocessor.cxx | 44 +- MUON/AliMUONTriggerSubprocessor.h | 10 +- MUON/Calib/DDLStore/Run0_999999999_v0_s0.root | Bin 59445 -> 58421 bytes .../Run0_999999999_v0_s0.root | Bin 0 -> 3448 bytes MUON/Calib/Mapping/Run0_999999999_v0_s0.root | Bin 5897389 -> 5897389 bytes .../Run0_999999999_v0_s0.root | Bin 0 -> 3123 bytes MUON/MUONTRGda.cxx | 77 ++-- MUON/MUONcalibLinkDef.h | 4 + MUON/libMUONcalib.pkg | 3 + MUON/mapping/AliMpDDLStore.cxx | 6 +- MUON/mapping/AliMpDDLStore.h | 6 +- MUON/mapping/AliMpRegionalTrigger.cxx | 8 +- MUON/mapping/AliMpTriggerCrate.cxx | 17 +- MUON/mapping/AliMpTriggerCrate.h | 21 +- .../data/stationTrigger/GlobalCrate.dat | 7 +- 39 files changed, 1608 insertions(+), 521 deletions(-) create mode 100644 MUON/AliMUONGlobalCrateConfig.cxx create mode 100644 MUON/AliMUONGlobalCrateConfig.h create mode 100644 MUON/AliMUONRegionalTriggerConfig.cxx create mode 100644 MUON/AliMUONRegionalTriggerConfig.h create mode 100644 MUON/AliMUONTriggerCrateConfig.cxx create mode 100644 MUON/AliMUONTriggerCrateConfig.h create mode 100644 MUON/Calib/GlobalTriggerCrateConfig/Run0_999999999_v0_s0.root create mode 100644 MUON/Calib/RegionalTriggerConfig/Run0_999999999_v0_s0.root diff --git a/MUON/AliMUON.cxx b/MUON/AliMUON.cxx index a6765b48194..d9bbf384dae 100644 --- a/MUON/AliMUON.cxx +++ b/MUON/AliMUON.cxx @@ -49,6 +49,7 @@ //#include "AliHeader.h" #include "AliLoader.h" +#include "AliCDBManager.h" #include "AliRunDigitizer.h" #include "AliMC.h" #include "AliRun.h" @@ -68,6 +69,7 @@ #include "AliMUONSDigitizerV2.h" #include "AliMUONDigitizerV3.h" #include "AliMUONDigitMaker.h" +#include "AliMUONCalibrationData.h" #include "AliMUONSt1GeometryBuilderV2.h" #include "AliMUONSt2GeometryBuilderV2.h" @@ -122,7 +124,8 @@ AliMUON::AliMUON() fRawWriter(0x0), fDigitMaker(0x0), fHitStore(0x0), - fDigitStoreConcreteClassName() + fDigitStoreConcreteClassName(), + fCalibrationData(0x0) { /// Default Constructor @@ -156,13 +159,15 @@ AliMUON::AliMUON(const char *name, const char* title) fRawWriter(0x0), fDigitMaker(new AliMUONDigitMaker), fHitStore(0x0), - fDigitStoreConcreteClassName("AliMUONDigitStoreV2S") + fDigitStoreConcreteClassName("AliMUONDigitStoreV2S"), + fCalibrationData() + { -/// Standard constructor + /// Standard constructor AliDebug(1,Form("ctor this=%p",this)); fIshunt = 0; - + //PH SetMarkerColor(kRed);// // Geometry builder @@ -171,11 +176,11 @@ AliMUON::AliMUON(const char *name, const char* title) // Common geometry definitions fGeometryBuilder ->AddBuilder(new AliMUONCommonGeometryBuilder(this)); - + // By default, add also all the needed geometry builders. // If you want to change this from outside, please use ResetGeometryBuilder // method, followed by AddGeometryBuilder ones. - + AddGeometryBuilder(new AliMUONSt1GeometryBuilderV2(this)); AddGeometryBuilder(new AliMUONSt2GeometryBuilderV2(this)); AddGeometryBuilder(new AliMUONSlatGeometryBuilder(this)); @@ -202,7 +207,10 @@ AliMUON::AliMUON(const char *name, const char* title) } } // Chamber stCH (0, 1) in } // Station st (0...) - + + Int_t runnumber = AliCDBManager::Instance()->GetRun(); + + fCalibrationData = new AliMUONCalibrationData(runnumber); } //____________________________________________________________________ @@ -216,6 +224,7 @@ AliMUON::~AliMUON() delete fRawWriter; delete fDigitMaker; delete fHitStore; + delete fCalibrationData; } //_____________________________________________________________________________ @@ -455,7 +464,9 @@ AliDigitizer* AliMUON::CreateDigitizer(AliRunDigitizer* manager) const { /// Return digitizer - return new AliMUONDigitizerV3(manager, fDigitizerWithNoise); + AliMUONDigitizerV3* digitizer = new AliMUONDigitizerV3(manager, fDigitizerWithNoise); + digitizer->setCalibrationData(fCalibrationData); + return digitizer; } //_____________________________________________________________________ @@ -529,7 +540,6 @@ void AliMUON::Digits2Raw() Bool_t AliMUON::Raw2SDigits(AliRawReader* rawReader) { /// Convert raw data to SDigit -/// Only for tracking for the moment (ChF) fLoader->LoadDigits("READ"); if (!fLoader->TreeS()) fLoader->MakeSDigitsContainer(); diff --git a/MUON/AliMUON.h b/MUON/AliMUON.h index b7047041fa1..4bd61b0ad6b 100644 --- a/MUON/AliMUON.h +++ b/MUON/AliMUON.h @@ -36,6 +36,7 @@ class AliMUONVGeometryBuilder; class AliESD; class AliMUONDigitMaker; class AliMUONVHitStore; +class AliMUONCalibrationData; class AliMUON : public AliDetector { @@ -183,7 +184,7 @@ class AliMUON : public AliDetector Bool_t fTriggerEffCells; ///< Flag to select TriggerEffCells Int_t fDigitizerWithNoise; ///< Flag to switch on/off generation of noisy digits Bool_t fIsTailEffect; ///< Switch to turn on/off the tail effect - + AliMUONRawWriter* fRawWriter; //!< Raw data writer AliMUONDigitMaker* fDigitMaker; //!< pointer to the digit maker class @@ -192,7 +193,9 @@ class AliMUON : public AliDetector TString fDigitStoreConcreteClassName; ///< to be able to select what the sdigitizer uses - ClassDef(AliMUON,16) // MUON Detector base class + AliMUONCalibrationData* fCalibrationData; ///< pointer of calibration data + + ClassDef(AliMUON,17) // MUON Detector base class }; #endif diff --git a/MUON/AliMUONCDB.cxx b/MUON/AliMUONCDB.cxx index 9a0af849b9f..0c21366daad 100644 --- a/MUON/AliMUONCDB.cxx +++ b/MUON/AliMUONCDB.cxx @@ -43,6 +43,8 @@ #include "AliMUONVStore.h" #include "AliMUONVCalibParam.h" #include "AliMUONVCalibParam.h" +#include "AliMUONGlobalCrateConfig.h" +#include "AliMUONRegionalTriggerConfig.h" #include "AliMpCDB.h" #include "AliMpConstants.h" @@ -50,6 +52,7 @@ #include "AliMpDEIterator.h" #include "AliMpDEManager.h" #include "AliMpDetElement.h" +#include "AliMpFiles.h" #include "AliMpHVNamer.h" #include "AliMpManuIterator.h" #include "AliMpSegmentation.h" @@ -650,44 +653,29 @@ AliMUONCDB::MakeLocalTriggerMaskStore(AliMUONVStore& localBoardMasks) const //_____________________________________________________________________________ Int_t -AliMUONCDB::MakeRegionalTriggerMaskStore(AliMUONVStore& rtm) const +AliMUONCDB::MakeRegionalTriggerConfigStore(AliMUONRegionalTriggerConfig& rtm) const { - /// Make a regional trigger masks store. Mask is set to FFFF for each local board (Ch.F.) + /// Make a regional trigger config store. Mask is set to FFFF for each local board (Ch.F.) AliCodeTimerAuto(""); - Int_t ngenerated(0); - for ( Int_t i = 0; i < 16; ++i ) - { - AliMUONVCalibParam* regionalBoard = new AliMUONCalibParamNI(1,1,i,0,0); - - regionalBoard->SetValueAsInt(0,0,0xFFFF); - ++ngenerated; + return rtm.ReadData(AliMpFiles::LocalTriggerBoardMapping()); - rtm.Add(regionalBoard); - } - - return ngenerated; } + //_____________________________________________________________________________ Int_t -AliMUONCDB::MakeGlobalTriggerMaskStore(AliMUONVCalibParam& gtm) const +AliMUONCDB::MakeGlobalTriggerConfigStore(AliMUONGlobalCrateConfig& gtm) const { - /// Make a global trigger masks store. All masks (disable) set to 0x00 for each Darc board (Ch.F.) + /// Make a global trigger config store. All masks (disable) set to 0x00 for each Darc board (Ch.F.) AliCodeTimerAuto(""); - - Int_t ngenerated(0); - - for ( Int_t j = 0; j < 2; ++j ) - { - gtm.SetValueAsInt(j,0,0x00); - ++ngenerated; - } - return ngenerated; + + return gtm.ReadData(AliMpFiles::GlobalTriggerBoardMapping()); } + //_____________________________________________________________________________ AliMUONTriggerLut* AliMUONCDB::MakeTriggerLUT(const char* file) const @@ -856,37 +844,39 @@ AliMUONCDB::WriteLocalTriggerMasks(Int_t startRun, Int_t endRun) //_____________________________________________________________________________ void -AliMUONCDB::WriteRegionalTriggerMasks(Int_t startRun, Int_t endRun) +AliMUONCDB::WriteRegionalTriggerConfig(Int_t startRun, Int_t endRun) { /// Write regional trigger masks to OCDB - AliMUONVStore* rtm = new AliMUON1DArray(16); - Int_t ngenerated = MakeRegionalTriggerMaskStore(*rtm); + AliMUONRegionalTriggerConfig* rtm = new AliMUONRegionalTriggerConfig(); + Int_t ngenerated = MakeRegionalTriggerConfigStore(*rtm); AliInfo(Form("Ngenerated = %d",ngenerated)); if (ngenerated>0) { - WriteToCDB("MUON/Calib/RegionalTriggerBoardMasks",rtm,startRun,endRun,true); + WriteToCDB("MUON/Calib/RegionalTriggerConfig",rtm,startRun,endRun,true); } delete rtm; } + //_____________________________________________________________________________ void -AliMUONCDB::WriteGlobalTriggerMasks(Int_t startRun, Int_t endRun) +AliMUONCDB::WriteGlobalTriggerConfig(Int_t startRun, Int_t endRun) { /// Write global trigger masks to OCDB - AliMUONVCalibParam* gtm = new AliMUONCalibParamNI(1,2,1,0,0); + AliMUONGlobalCrateConfig* gtm = new AliMUONGlobalCrateConfig(); - Int_t ngenerated = MakeGlobalTriggerMaskStore(*gtm); + Int_t ngenerated = MakeGlobalTriggerConfigStore(*gtm); AliInfo(Form("Ngenerated = %d",ngenerated)); if (ngenerated>0) { - WriteToCDB("MUON/Calib/GlobalTriggerBoardMasks",gtm,startRun,endRun,true); + WriteToCDB("MUON/Calib/GlobalTriggerCrateConfig",gtm,startRun,endRun,true); } delete gtm; } + //_____________________________________________________________________________ void AliMUONCDB::WriteTriggerLut(Int_t startRun, Int_t endRun) @@ -1028,8 +1018,8 @@ AliMUONCDB::WriteTrigger(Int_t startRun, Int_t endRun) { /// Writes all Trigger related calibration to CDB WriteLocalTriggerMasks(startRun,endRun); - WriteRegionalTriggerMasks(startRun,endRun); - WriteGlobalTriggerMasks(startRun,endRun); + WriteRegionalTriggerConfig(startRun,endRun); + WriteGlobalTriggerConfig(startRun,endRun); WriteTriggerLut(startRun,endRun); WriteTriggerEfficiency(startRun,endRun); } diff --git a/MUON/AliMUONCDB.h b/MUON/AliMUONCDB.h index cae2ac7956b..d9be4f4fc07 100644 --- a/MUON/AliMUONCDB.h +++ b/MUON/AliMUONCDB.h @@ -21,6 +21,8 @@ class TMap; class AliMUONVCalibParam; class AliMUONTriggerLut; class AliMUONTriggerEfficiencyCells; +class AliMUONRegionalTriggerConfig; +class AliMUONGlobalCrateConfig; class AliMUONCDB : public TObject { @@ -40,9 +42,10 @@ public: Int_t MakeCapacitanceStore(AliMUONVStore& capaStore, const char* file); Int_t MakeGainStore(AliMUONVStore& gainStore, Bool_t defaultValues); - Int_t MakeLocalTriggerMaskStore(AliMUONVStore& ltm) const; - Int_t MakeRegionalTriggerMaskStore(AliMUONVStore& rtm) const; - Int_t MakeGlobalTriggerMaskStore(AliMUONVCalibParam& gtm) const; + Int_t MakeLocalTriggerMaskStore(AliMUONVStore& ltm) const; + Int_t MakeRegionalTriggerConfigStore(AliMUONRegionalTriggerConfig& rtm) const; + Int_t MakeGlobalTriggerConfigStore(AliMUONGlobalCrateConfig& gtm) const; + AliMUONTriggerLut* MakeTriggerLUT(const char* file="$(ALICE_ROOT)/MUON/data/lutAptLpt1Hpt1p7.root") const; AliMUONTriggerEfficiencyCells* MakeTriggerEfficiency(const char* file="$ALICE_ROOT/MUON/data/efficiencyCells.dat") const; @@ -68,8 +71,9 @@ public: void WriteCapacitances(const char* file, Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); void WriteLocalTriggerMasks(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); - void WriteRegionalTriggerMasks(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); - void WriteGlobalTriggerMasks(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); + void WriteRegionalTriggerConfig(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); + void WriteGlobalTriggerConfig(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); + void WriteTriggerLut(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); void WriteTriggerEfficiency(Int_t startRun=0, Int_t endRun=AliCDBRunRange::Infinity()); diff --git a/MUON/AliMUONCalibrationData.cxx b/MUON/AliMUONCalibrationData.cxx index b9fd9acd26e..fb0c0860d65 100644 --- a/MUON/AliMUONCalibrationData.cxx +++ b/MUON/AliMUONCalibrationData.cxx @@ -26,6 +26,9 @@ #include "AliMUONVStore.h" #include "AliMUONVStore.h" #include "AliMUONVCalibParam.h" +#include "AliMUONGlobalCrateConfig.h" +#include "AliMUONRegionalTriggerConfig.h" + #include #include #include @@ -60,8 +63,8 @@ fGains(0x0), fPedestals(0x0), fHV(0x0), fLocalTriggerBoardMasks(0x0), -fRegionalTriggerBoardMasks(0x0), -fGlobalTriggerBoardMasks(0x0), +fRegionalTriggerConfig(0x0), +fGlobalTriggerCrateConfig(0x0), fTriggerLut(0x0), fTriggerEfficiency(0x0), fCapacitances(0x0), @@ -81,8 +84,8 @@ fNeighbours(0x0) Pedestals(); HV(); LocalTriggerBoardMasks(0); - RegionalTriggerBoardMasks(0); - GlobalTriggerBoardMasks(); + RegionalTriggerConfig(); + GlobalTriggerCrateConfig(); TriggerLut(); TriggerEfficiency(); Capacitances(); @@ -128,14 +131,16 @@ AliMUONCalibrationData::CreateGains(Int_t runNumber) } //_____________________________________________________________________________ -AliMUONVCalibParam* -AliMUONCalibrationData::CreateGlobalTriggerBoardMasks(Int_t runNumber) +AliMUONGlobalCrateConfig* +AliMUONCalibrationData::CreateGlobalTriggerCrateConfig(Int_t runNumber) { - /// Create the internal store for GlobalTriggerBoardMasks from OCDB + /// Create the internal store for GlobalTriggerCrateConfig from OCDB - return dynamic_cast(CreateObject(runNumber,"MUON/Calib/GlobalTriggerBoardMasks")); + return dynamic_cast(CreateObject(runNumber,"MUON/Calib/GlobalTriggerCrateConfig")); } + + //_____________________________________________________________________________ TMap* AliMUONCalibrationData::CreateHV(Int_t runNumber) @@ -205,13 +210,14 @@ AliMUONCalibrationData::CreatePedestals(Int_t runNumber) return dynamic_cast(CreateObject(runNumber,"MUON/Calib/Pedestals")); } + //_____________________________________________________________________________ -AliMUONVStore* -AliMUONCalibrationData::CreateRegionalTriggerBoardMasks(Int_t runNumber) +AliMUONRegionalTriggerConfig* +AliMUONCalibrationData::CreateRegionalTriggerConfig(Int_t runNumber) { - /// Create the internal store for RegionalTriggerBoardMasks from OCDB + /// Create the internal store for RegionalTriggerConfig from OCDB - return dynamic_cast(CreateObject(runNumber,"MUON/Calib/RegionalTriggerBoardMasks")); + return dynamic_cast(CreateObject(runNumber,"MUON/Calib/RegionalTriggerConfig")); } //_____________________________________________________________________________ @@ -262,18 +268,19 @@ AliMUONCalibrationData::Gains(Int_t detElemId, Int_t manuId) const } //_____________________________________________________________________________ -AliMUONVCalibParam* -AliMUONCalibrationData::GlobalTriggerBoardMasks() const +AliMUONGlobalCrateConfig* +AliMUONCalibrationData::GlobalTriggerCrateConfig() const { - /// Return the masks for the global trigger board. + /// Return the config for the global trigger board. - if (!fGlobalTriggerBoardMasks) + if (!fGlobalTriggerCrateConfig) { - fGlobalTriggerBoardMasks = CreateGlobalTriggerBoardMasks(fRunNumber); + fGlobalTriggerCrateConfig = CreateGlobalTriggerCrateConfig(fRunNumber); } - return fGlobalTriggerBoardMasks; + return fGlobalTriggerCrateConfig; } + //_____________________________________________________________________________ TMap* AliMUONCalibrationData::HV() const @@ -363,37 +370,27 @@ AliMUONCalibrationData::Print(Option_t*) const << " fPedestals=" << fPedestals << " fHV=" << fHV << " fLocalTriggerBoardMasks=" << fLocalTriggerBoardMasks - << " fRegionalTriggerBoardMasks=" << fRegionalTriggerBoardMasks - << " fGlobalTriggerBoardMasks=" << fGlobalTriggerBoardMasks + << " fRegionalTriggerConfig=" << fRegionalTriggerConfig + << " fGlobalTriggerCrateConfig=" << fGlobalTriggerCrateConfig << " fTriggerLut=" << fTriggerLut << endl; } + //_____________________________________________________________________________ -AliMUONVCalibParam* -AliMUONCalibrationData::RegionalTriggerBoardMasks(Int_t regionalBoardNumber) const +AliMUONRegionalTriggerConfig* +AliMUONCalibrationData::RegionalTriggerConfig() const { -/// Return the masks for a given trigger regional board. - - if ( !fRegionalTriggerBoardMasks ) - { - fRegionalTriggerBoardMasks = CreateRegionalTriggerBoardMasks(fRunNumber); - } + /// Return the config for the regional trigger board. - if ( fRegionalTriggerBoardMasks ) + if (!fRegionalTriggerConfig) { - AliMUONVCalibParam* rtbm = - static_cast(fRegionalTriggerBoardMasks->FindObject(regionalBoardNumber)); - - if (!rtbm) - { - AliError(Form("Could not get mask for regionalBoard index=%d",regionalBoardNumber)); + fRegionalTriggerConfig = CreateRegionalTriggerConfig(fRunNumber); } - return rtbm; - } - return 0x0; + return fRegionalTriggerConfig; } + //_____________________________________________________________________________ AliMUONTriggerEfficiencyCells* AliMUONCalibrationData::TriggerEfficiency() const @@ -435,10 +432,11 @@ AliMUONCalibrationData::Reset() fHV = 0x0; delete fLocalTriggerBoardMasks; fLocalTriggerBoardMasks = 0x0; - delete fRegionalTriggerBoardMasks; - fRegionalTriggerBoardMasks = 0x0; - delete fGlobalTriggerBoardMasks; - fGlobalTriggerBoardMasks = 0x0; + delete fRegionalTriggerConfig; + fRegionalTriggerConfig = 0x0; + delete fGlobalTriggerCrateConfig; + fGlobalTriggerCrateConfig = 0x0; + delete fTriggerLut; fTriggerLut = 0x0; delete fTriggerEfficiency; diff --git a/MUON/AliMUONCalibrationData.h b/MUON/AliMUONCalibrationData.h index 6dc468109a3..86a1a9a871d 100644 --- a/MUON/AliMUONCalibrationData.h +++ b/MUON/AliMUONCalibrationData.h @@ -22,6 +22,8 @@ class AliMUONTriggerLut; class AliMUONVStore; class AliMUONVStore; class AliMUONVCalibParam; +class AliMUONGlobalCrateConfig; +class AliMUONRegionalTriggerConfig; class TMap; class AliMUONCalibrationData : public TObject @@ -44,7 +46,7 @@ public: static AliMUONVStore* CreateGains(Int_t runNumber); /// Create a global trigger mask (which must be deleted) from OCDB for the given run - static AliMUONVCalibParam* CreateGlobalTriggerBoardMasks(Int_t runNumber); + static AliMUONGlobalCrateConfig* CreateGlobalTriggerCrateConfig(Int_t runNumber); /// Create a hv map (which must be deleted) from OCDB for the given run static TMap* CreateHV(Int_t runNumber); @@ -59,7 +61,7 @@ public: static AliMUONVStore* CreatePedestals(Int_t runNumber); /// Create a regional trigger mask store (which must be deleted) for a given run - static AliMUONVStore* CreateRegionalTriggerBoardMasks(Int_t runNumber); + static AliMUONRegionalTriggerConfig* CreateRegionalTriggerConfig(Int_t runNumber); /// Create a trigger Look Up Table (which must be deleted) for a given run static AliMUONTriggerLut* CreateTriggerLut(Int_t runNumber); @@ -70,8 +72,8 @@ public: /// Get all the gains AliMUONVStore* Gains() const; - /// Get the mask for the global trigger board. - AliMUONVCalibParam* GlobalTriggerBoardMasks() const; + /// Get the configuration for the global trigger board. + AliMUONGlobalCrateConfig* GlobalTriggerCrateConfig() const; /// Get the Gain calibration object for channels within (detElemId,manuId). AliMUONVCalibParam* Gains(Int_t detElemId, Int_t manuId) const; @@ -97,8 +99,9 @@ public: /// Dump to screen. virtual void Print(Option_t* opt="") const; - /// Get the mask for a given regional trigger board. - AliMUONVCalibParam* RegionalTriggerBoardMasks(Int_t index) const; + /// Get the config for regional trigger. + AliMUONRegionalTriggerConfig* RegionalTriggerConfig() const; + /// The runnumber used by this object. Int_t RunNumber() const { return fRunNumber; } @@ -125,9 +128,10 @@ private: mutable AliMUONVStore* fGains; //!< Gains mutable AliMUONVStore* fPedestals; //!< Pedestals mutable TMap* fHV; //!< HV - mutable AliMUONVStore* fLocalTriggerBoardMasks; //!< Local trigger board maska - mutable AliMUONVStore* fRegionalTriggerBoardMasks; //!< Regional trigger board maska - mutable AliMUONVCalibParam* fGlobalTriggerBoardMasks; //!< Global trigger board maska + mutable AliMUONVStore* fLocalTriggerBoardMasks; //!< Local trigger board maska + mutable AliMUONRegionalTriggerConfig* fRegionalTriggerConfig; //!< Regional trigger config + mutable AliMUONGlobalCrateConfig* fGlobalTriggerCrateConfig; //!< Global trigger crate config + mutable AliMUONTriggerLut* fTriggerLut; //!< TRigger LUTs mutable AliMUONTriggerEfficiencyCells* fTriggerEfficiency; //!< Trigger efficiency cells mutable AliMUONVStore* fCapacitances; //!< Manu capacitances diff --git a/MUON/AliMUONDigitizerV3.cxx b/MUON/AliMUONDigitizerV3.cxx index 204ea6ec55f..f61e3294493 100644 --- a/MUON/AliMUONDigitizerV3.cxx +++ b/MUON/AliMUONDigitizerV3.cxx @@ -119,7 +119,7 @@ AliMUONDigitizerV3::~AliMUONDigitizerV3() AliDebug(1,"dtor"); - delete fCalibrationData; + // delete fCalibrationData; delete fTriggerProcessor; delete fNoiseFunctionTrig; delete fTriggerStore; @@ -697,14 +697,14 @@ AliMUONDigitizerV3::Init() return kFALSE; } - Int_t runnumber = AliCDBManager::Instance()->GetRun(); - // Load mapping if ( ! AliMpCDB::LoadDDLStore() ) { AliFatal("Could not access mapping from OCDB !"); } - fCalibrationData = new AliMUONCalibrationData(runnumber); + if (!fCalibrationData) + AliFatal("Calibration data object not defined"); + if ( !fCalibrationData->Pedestals() ) { AliFatal("Could not access pedestals from OCDB !"); @@ -713,6 +713,10 @@ AliMUONDigitizerV3::Init() { AliFatal("Could not access gains from OCDB !"); } + + + AliInfo("Using trigger configuration from CDB"); + fTriggerProcessor = new AliMUONTriggerElectronics(fCalibrationData); AliDebug(1, Form("Will %s generate noise-only digits for tracker", diff --git a/MUON/AliMUONDigitizerV3.h b/MUON/AliMUONDigitizerV3.h index bd1a1218ff5..e8978cf0156 100644 --- a/MUON/AliMUONDigitizerV3.h +++ b/MUON/AliMUONDigitizerV3.h @@ -46,6 +46,10 @@ public: Bool_t addNoise=kFALSE, Bool_t noiseOnly=kFALSE); + /// Set calibration data + void setCalibrationData(AliMUONCalibrationData* calibrationData) + {fCalibrationData = calibrationData;} + private: /// Not implemented AliMUONDigitizerV3(const AliMUONDigitizerV3& other); @@ -83,7 +87,7 @@ private: AliMUONVTriggerStore* fTriggerStore; //!< trigger objects AliMUONVDigitStore* fDigitStore; //!< temporary digits AliMUONVDigitStore* fOutputDigitStore; //!< digits we'll output to disk - + ClassDef(AliMUONDigitizerV3,7) // MUON Digitizer V3-5 }; diff --git a/MUON/AliMUONGlobalCrateConfig.cxx b/MUON/AliMUONGlobalCrateConfig.cxx new file mode 100644 index 00000000000..a90d174167a --- /dev/null +++ b/MUON/AliMUONGlobalCrateConfig.cxx @@ -0,0 +1,401 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +// $Id$ +// $MpId: AliMpTrigger.cxx,v 1.4 2006/05/24 13:58:52 ivana Exp $ + +//----------------------------------------------------------------------------- +// Class AliMUONGlobalCrateConfig +// -------------------- +// The class defines the configuration of trigger crate +// Author: Ch. Finck, Subatech Nantes +//----------------------------------------------------------------------------- + +#include "AliMUONGlobalCrateConfig.h" +#include "AliMpConstants.h" +#include "AliMpFiles.h" +#include "AliMpHelper.h" + +#include "AliLog.h" + +#include +#include +#include + +/// \cond CLASSIMP +ClassImp(AliMUONGlobalCrateConfig) +/// \endcond + +const Char_t* AliMUONGlobalCrateConfig::fgkJtagName = "JtagBoard"; +const Char_t* AliMUONGlobalCrateConfig::fgkFirstDarcName = "LeftDarcBoard"; +const Char_t* AliMUONGlobalCrateConfig::fgkSecondDarcName = "RightDarcBoard"; +const Char_t* AliMUONGlobalCrateConfig::fgkGlobalName = "GlobalBoard"; +const Char_t* AliMUONGlobalCrateConfig::fgkFetName = "FetBoard"; + +const Int_t AliMUONGlobalCrateConfig::fgkGlobalNofRegisters = 13; +const Int_t AliMUONGlobalCrateConfig::fgkFetNofRegisters = 7; +const Int_t AliMUONGlobalCrateConfig::fgkJtagNofLines = 4; +//______________________________________________________________________________ +AliMUONGlobalCrateConfig::AliMUONGlobalCrateConfig() + : TNamed("GlobalCrate", "mapping trigger global crate"), + fGlobalCrateEnable(0x0), + fJtagVmeAddr(0x0), + fJtagClockDiv(0), + fJtagRxPhase(0), + fJtagRdDelay(0), + fEnableJtag(0), + fJtagCrateName(), + fFirstDarcVmeAddr(0x0), + fFirstDarcType(0), + fFirstDarcDisable(0), + fFirstDarcL0Delay(0), + fFirstDarcL1TimeOut(0), + fFirstDarcConfig(0), + fSecondDarcVmeAddr(0x0), + fSecondDarcType(0), + fSecondDarcDisable(0), + fSecondDarcL0Delay(0), + fSecondDarcL1TimeOut(0), + fSecondDarcGlobalL0(0), + fSecondDarcConfig(0), + fGlobalVmeAddr(0x0), + fFetVmeAddr(0x0) +{ +/// Standard constructor + + for (Int_t i = 0; i < fgkGlobalNofRegisters; ++i) + fGlobalRegisters[i] = 0; + + for (Int_t j = 0; j < fgkFetNofRegisters; ++j) + fFetRegisters[j] = 0; +} + +//______________________________________________________________________________ +AliMUONGlobalCrateConfig::~AliMUONGlobalCrateConfig() +{ +/// Destructor +} + +//______________________________________________________________________________ +Int_t AliMUONGlobalCrateConfig::ReadData(const TString& fileName) +{ + /// Fill trigger global crate object from ascii file + /// put the method static to be used by other class w/o initializing object + + TString inFileName(fileName); + if ( inFileName == "" ) + inFileName = AliMpFiles::GlobalTriggerBoardMapping(); + + inFileName = gSystem->ExpandPathName(inFileName.Data()); + + ifstream in(inFileName.Data(), ios::in); + + if (!in) { + AliErrorStream() + << "Global Trigger Board Mapping File " << fileName.Data() << " not found" << endl; + return kFALSE; + } + + TArrayI list; + Int_t nDarc = 0; + + char line[255]; + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + + if (!tmp.Contains(GetName())) + AliWarning("Wrong Global Crate File"); + + // enable + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + UChar_t en = 0; + sscanf(tmp.Data(), "%c", &en); + SetGlobalCrateEnable(en); + + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + + if (tmp.Contains(GetJtagName())) { + // vme addr + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + ULong_t addr; + sscanf(tmp.Data(), "%lx", &addr); + SetJtagVmeAddr(addr); + AliDebug(1, Form("Jtag Vme Address: 0x%x", addr)); + + // clk div, rx phase, read delay + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + TArrayI list; + AliMpHelper::DecodeName(line, ' ', list); + SetJtagClockDiv(list[0]); + SetJtagRxPhase(list[1]); + SetJtagRdDelay(list[2]); + AliDebug(1, Form("Jtag Clock Div: %d, Rx Phase: %d, Read Delay %d", list[0], list[1], list[2])); + + // enable + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + AliMpHelper::DecodeName(line, ' ', list); + UChar_t enable = 0; + for (Int_t i = 0; i < GetJtagNofLines(); ++i) + enable |= (list[i] << i); + SetEnableJtag(enable); + AliDebug(1, Form("Jtag Enable: 0x%x", enable)); + + for (Int_t i = 0; i < GetJtagNofLines(); ++i) { + in.getline(line, 255); + for (Int_t j = 0; j < GetJtagNofLines(); ++j) { + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + SetJtagCrateName(i*GetJtagNofLines() + j, tmp); + //AliDebug(1, Form("Jtag Crate Name: %s", tmp.Data())); + } + } + } + + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + if (tmp.Contains(GetFirstDarcName())) { + // vme addr + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + ULong_t addr; + sscanf(tmp.Data(), "%lx", &addr); + if (addr) nDarc++; + SetFirstDarcVmeAddr(addr); + AliDebug(1, Form("First Darc Vme Address: 0x%x", addr)); + + // type + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + SetFirstDarcType(tmp.Atoi()); + AliDebug(1, Form("First Darc Type: %d", tmp.Atoi())); + + // disable + in.getline(line, 255); + UInt_t item; + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetFirstDarcDisable(item); + AliDebug(1, Form("First Darc Disable: 0x%x", item)); + + // L0 + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetFirstDarcL0Delay(item); + AliDebug(1, Form("First Darc L0 Delay: 0x%x", item)); + + // L1 + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetFirstDarcL1TimeOut(item); + AliDebug(1, Form("First Darc L1 Time Out: 0x%x", item)); + + // Global L0 delay + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetFirstDarcGlobalL0(item); + AliDebug(1, Form("First Darc Global L0 delay: 0x%x", item)); + + // Trigger configuration + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetFirstDarcConfig(item); + AliDebug(1, Form("First Darc Config: 0x%x", item)); + + } + + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + if (tmp.Contains(GetSecondDarcName())) { + // vme addr + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + ULong_t addr; + if (addr) nDarc++; + sscanf(tmp.Data(), "%lx", &addr); + SetSecondDarcVmeAddr(addr); + AliDebug(1, Form("Second Darc Vme Address: 0x%x", addr)); + + // type + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + SetSecondDarcType(tmp.Atoi()); + AliDebug(1, Form("Second Darc Type: %d", tmp.Atoi())); + + // enable + in.getline(line, 255); + UInt_t item; + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetSecondDarcDisable(item); + AliDebug(1, Form("Second Darc Disable: 0x%x", item)); + + // L0 + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetSecondDarcL0Delay(item); + AliDebug(1, Form("Second Darc L0 Delay: 0x%x", item)); + + // L1 + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetSecondDarcL1TimeOut(item); + AliDebug(1, Form("Second Darc L1 Time Out: 0x%x", item)); + + // Global L0 delay + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetSecondDarcGlobalL0(item); + AliDebug(1, Form("Second Darc Global L0 delay: 0x%x", item)); + + // Trigger configuration + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + sscanf(tmp.Data(), "%x", &item); + SetSecondDarcConfig(item); + AliDebug(1, Form("Second Darc Config: 0x%x", item)); + } + + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + if (tmp.Contains(GetGlobalName())) { + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + ULong_t addr; + sscanf(tmp.Data(), "%lx", &addr); + SetGlobalVmeAddr(addr); + AliDebug(1, Form("Global Vme Address: 0x%x", addr)); + + for (Int_t i = 0; i < GetGlobalNofRegisters(); ++i) { + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + UInt_t reg; + sscanf(tmp.Data(), "%x", ®); + SetGlobalRegister(i, reg); + AliDebug(1, Form("Global Register %d: 0x%x", i, reg)); + } + } + + in.getline(line, 255); + tmp = AliMpHelper::Normalize(line); + if (tmp.Contains(GetFetName())) { + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + ULong_t addr; + sscanf(tmp.Data(), "%lx", &addr); + SetFetVmeAddr(addr); + AliDebug(1, Form("Fet Vme Address: 0x%x", addr)); + + for (Int_t i = 0; i < GetFetNofRegisters(); ++i) { + in.getline(line, 255); + TString tmp(AliMpHelper::Normalize(line)); + UInt_t reg; + sscanf(tmp.Data(), "%x", ®); + SetFetRegister(i, reg); + AliDebug(1, Form("Fet Register %d: 0x%x", i, reg)); + } + } + + return nDarc; +} + +//______________________________________________________________________________ +Bool_t AliMUONGlobalCrateConfig::GetEnableJtag(Int_t index) const +{ + /// returns enable mask for a given Jtag line + + if (index > fgkJtagNofLines) { + AliWarning("Index size too big for Jtag line"); + return kFALSE; + } + return ((fEnableJtag >> index) & 0x1); + +} + +//______________________________________________________________________________ +void AliMUONGlobalCrateConfig::SetJtagCrateName(Int_t index, TString name) +{ + /// Get Jtag crate name for a given index + if (index > AliMpConstants::LocalBoardNofChannels()) { + AliWarning("Index size too big for Jtag line"); + return; + } + fJtagCrateName[index] = name; +} + +//______________________________________________________________________________ +TString AliMUONGlobalCrateConfig::GetJtagCrateName(Int_t jtagLine, Int_t index) const +{ + /// Get the crate name for a given line and a given index + if (jtagLine > AliMpConstants::LocalBoardNofChannels() || index > AliMpConstants::LocalBoardNofChannels()) + return 0x0; + else + return fJtagCrateName[jtagLine*fgkJtagNofLines + index]; +} + +//______________________________________________________________________________ +UInt_t AliMUONGlobalCrateConfig::GetGlobalRegister(Int_t index) const +{ + /// return global register for a given index + if (index > fgkGlobalNofRegisters) { + AliWarning("Index size too big for Global Register"); + return 0; + } else + return fGlobalRegisters[index]; +} + +//______________________________________________________________________________ +void AliMUONGlobalCrateConfig::SetGlobalRegister(Int_t index, UInt_t reg) +{ + /// set Global register for a given index + if (index > fgkGlobalNofRegisters) { + AliWarning("Index size too big for Global Register"); + return; + } + fGlobalRegisters[index] = reg; +} + +//______________________________________________________________________________ +UInt_t AliMUONGlobalCrateConfig::GetFetRegister(Int_t index) const +{ + /// return global register for a given index + if (index > fgkFetNofRegisters) { + AliWarning("Index size too big for Fet Register"); + return 0; + } else + return fFetRegisters[index]; +} + +//______________________________________________________________________________ +void AliMUONGlobalCrateConfig::SetFetRegister(Int_t index, UInt_t reg) +{ + /// set Global register for a given index + if (index > fgkFetNofRegisters) { + AliWarning("Index size too big for Global Register"); + return; + } + fFetRegisters[index] = reg; +} diff --git a/MUON/AliMUONGlobalCrateConfig.h b/MUON/AliMUONGlobalCrateConfig.h new file mode 100644 index 00000000000..b27280bdec7 --- /dev/null +++ b/MUON/AliMUONGlobalCrateConfig.h @@ -0,0 +1,251 @@ +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +// $MpId: $ + +/// \ingroup calib +/// \class AliMUONGlobalCrateConfig +/// \brief The class defines the configuration of global crate +/// +/// \author Ch. Finck, Subatech Nantes + +#ifndef ALIMUON_GLOBAL_CRATE_CONFIG_H +#define ALIMUON_GLOBAL_CRATE_CONFIG_H + +#include +#include + +class AliMUONGlobalCrateConfig : public TNamed { + + public: + AliMUONGlobalCrateConfig(); + virtual ~AliMUONGlobalCrateConfig(); + + // methods + Int_t ReadData(const TString& fileName = ""); + + // global crate enable + /// set global crate enbale + void SetGlobalCrateEnable(UChar_t enable) {fGlobalCrateEnable = enable;} + /// Get global crate enbale + UChar_t GetGlobalCrateEnable() {return fGlobalCrateEnable;} + + // Jtag + /// Get Jtag board VME address + ULong_t GetJtagVmeAddr() const {return fJtagVmeAddr;} + /// Set Jtag board VME address + void SetJtagVmeAddr(ULong_t addr) {fJtagVmeAddr = addr;} + + /// Get Jtag board Clock Divider + UInt_t GetJtagClockDiv() const {return fJtagClockDiv;} + /// Set Jtag board Clock Divider + void SetJtagClockDiv(UInt_t clk) {fJtagClockDiv = clk;} + + /// Get Jtag board Rx Phase + UInt_t GetJtagRxPhase() const {return fJtagRxPhase;} + /// Set Jtag board Rx Phase + void SetJtagRxPhase(UInt_t rx) {fJtagRxPhase = rx;} + + /// Get Jtag board Read out Delay + UInt_t GetJtagRdDelay() const {return fJtagRdDelay;} + /// Set Jtag board Read out Delay + void SetJtagRdDelay(UInt_t rd) {fJtagRdDelay = rd;} + + /// Get Jtag enabled lines + Bool_t GetEnableJtag(Int_t index) const; + /// Set Jtag enable word + void SetEnableJtag(UChar_t en) {fEnableJtag = en;} + /// Get Jtag enable word + UChar_t GetEnableJtag() const {return fEnableJtag;} + + /// Get Jtag Crate names + TString GetJtagCrateName(Int_t jtagLine, Int_t index) const; + /// Set Jtag Crate names + void SetJtagCrateName(Int_t index, TString name); + + // first Darc Board + /// Get First Darc board VME address + ULong_t GetFirstDarcVmeAddr() const {return fFirstDarcVmeAddr;} + /// Get First Darc board VME address + void SetFirstDarcVmeAddr(ULong_t addr) {fFirstDarcVmeAddr = addr;} + + /// Get type for First Darc board + Int_t GetFirstDarcType() const {return fFirstDarcType;} + /// Get type for First Darc board + void SetFirstDarcType(Int_t type) {fFirstDarcType = type;} + + /// Get disable word for First Darc board + UChar_t GetFirstDarcDisable() const {return fFirstDarcDisable;} + /// Get disable per regional crate for First Darc board + Bool_t GetFirstDarcDisable(Int_t iCrate) const {return !((fFirstDarcDisable >> iCrate) & 0x1);} + /// Set disable word for First Darc board + void SetFirstDarcDisable(UChar_t en) {fFirstDarcDisable = en;} + + /// Get L0 Delay for First Darc board + UInt_t GetFirstDarcL0Delay() const {return fFirstDarcL0Delay;} + /// Set L0 Delay for First Darc board + void SetFirstDarcL0Delay(UInt_t delay) {fFirstDarcL0Delay = delay;} + + /// Get L1 Time Out for First Darc board + UInt_t GetFirstDarcL1TimeOut() const {return fFirstDarcL1TimeOut;} + /// Set L1 Time Out for First Darc board + void SetFirstDarcL1TimeOut(UInt_t time) {fFirstDarcL1TimeOut = time;} + + /// Get global L0 delay for First Darc board + UInt_t GetFirstDarcGlobalL0() const {return fFirstDarcGlobalL0;} + /// set global L0 delay for First Darc board + void SetFirstDarcGlobalL0(UInt_t time) {fFirstDarcGlobalL0 = time;} + + /// Get configuration for First Darc board + UInt_t GetFirstDarcConfig() const {return fFirstDarcConfig;} + /// set configuration for First Darc board + void SetFirstDarcConfig(UInt_t conf) {fFirstDarcConfig = conf;} + + // second Darc Board + /// Get Second Darc board VME address + ULong_t GetSecondDarcVmeAddr() const {return fSecondDarcVmeAddr;} + /// Set Second Darc board VME address + void SetSecondDarcVmeAddr(ULong_t addr) {fSecondDarcVmeAddr = addr;} + + /// Get type for Second Darc board + Int_t GetSecondDarcType() const {return fSecondDarcType;} + /// Set type for Second Darc board + void SetSecondDarcType(Int_t type) {fSecondDarcType = type;} + + /// Get disable word for Second Darc board + UChar_t GetSecondDarcDisable() const {return fSecondDarcDisable;} + /// Get disable per regional crate for Second Darc board + Bool_t GetSecondDarcDisable(Int_t iCrate) const {return !((fSecondDarcDisable >> iCrate) & 0x1);} + /// Set disable word for Second Darc board + void SetSecondDarcDisable(UChar_t en) {fSecondDarcDisable = en;} + + /// Get L0 Delay for Second Darc board + UInt_t GetSecondDarcL0Delay() const {return fSecondDarcL0Delay;} + /// Set L0 Delay for Second Darc board + void SetSecondDarcL0Delay(UInt_t delay) {fSecondDarcL0Delay = delay;} + /// Get L1 Time Out for Second Darc board + UInt_t GetSecondDarcL1TimeOut() const {return fSecondDarcL1TimeOut;} + /// Set L1 Time Out for Second Darc board + void SetSecondDarcL1TimeOut(UInt_t time) {fSecondDarcL1TimeOut = time;} + + /// Get global L0 delay for Second Darc board + UInt_t GetSecondDarcGlobalL0() const {return fSecondDarcGlobalL0;} + /// set global L0 delay for Second Darc board + void SetSecondDarcGlobalL0(UInt_t time) {fSecondDarcGlobalL0 = time;} + + /// Get configuration for Second Darc board + UInt_t GetSecondDarcConfig() const {return fSecondDarcConfig;} + /// set configuration for Second Darc board + void SetSecondDarcConfig(UInt_t conf) {fSecondDarcConfig = conf;} + + + // global board + /// Get Global board VME address + ULong_t GetGlobalVmeAddr() const {return fGlobalVmeAddr;} + /// Set Global board VME address + void SetGlobalVmeAddr(ULong_t addr) {fGlobalVmeAddr = addr;} + + /// Get register for Global + UInt_t GetGlobalRegister(Int_t index) const; + /// Set register for Global + void SetGlobalRegister(Int_t index, UInt_t reg); + /// Get register word for Global + UInt_t* GetGlobalRegister() {return fGlobalRegisters;} + + // fet board + /// Get FET board VME address + ULong_t GetFetVmeAddr() const {return fFetVmeAddr;} + /// Set FET board VME address + void SetFetVmeAddr(ULong_t addr) {fFetVmeAddr = addr;} + + /// Get register for FET + UInt_t GetFetRegister(Int_t index) const; + /// Set register for FET + void SetFetRegister(Int_t index, UInt_t reg); + /// Set register word for FET + UInt_t* GetFetRegister() {return fFetRegisters;} + + //static members + /// Get Jtag Name identifier + const Char_t* GetJtagName() const {return fgkJtagName;} + /// Get First Darc Name identifier + const Char_t* GetFirstDarcName() const {return fgkFirstDarcName;} + /// Get Second Darc Name identifier + const Char_t* GetSecondDarcName() const {return fgkSecondDarcName;} + /// Get Global Name identifier + const Char_t* GetGlobalName() const {return fgkGlobalName;} + /// Get Global Name identifier + const Char_t* GetFetName() const {return fgkFetName;} + + /// Get number of registers for Global + const Int_t GetGlobalNofRegisters() const {return fgkGlobalNofRegisters;} + /// Get number of registers for FET + const Int_t GetFetNofRegisters() const {return fgkFetNofRegisters;} + /// Get number of JTag lines + const Int_t GetJtagNofLines() const {return fgkJtagNofLines;} + + private: + /// Not implemented + AliMUONGlobalCrateConfig(const AliMUONGlobalCrateConfig& rhs); + /// Not implemented + AliMUONGlobalCrateConfig& operator=(const AliMUONGlobalCrateConfig& rhs); + + // data members + UChar_t fGlobalCrateEnable; ///< Global Crate Enable + ULong_t fJtagVmeAddr; ///< JTag VME address + UInt_t fJtagClockDiv; ///< Clock Divider number for JTag + UInt_t fJtagRxPhase; ///< Rx phase number for JTag + UInt_t fJtagRdDelay; ///< Read delay for JTag + UChar_t fEnableJtag; ///< Enable mask for JTag lines + TString fJtagCrateName[16]; ///< Crate name for the Jtag lines + + ULong_t fFirstDarcVmeAddr; ///< First Darc Board VME Address + Int_t fFirstDarcType; ///< Type of the first Darc Board + UChar_t fFirstDarcDisable; ///< disable the readout of the 8 crates connected to this board + UInt_t fFirstDarcL0Delay; ///< L0 delay for this board + UInt_t fFirstDarcL1TimeOut; ///< L1 time out for this board + UInt_t fFirstDarcGlobalL0 ; ///< L0 global l0 delay this board + UInt_t fFirstDarcConfig ; ///< Trigger configuration this board + + ULong_t fSecondDarcVmeAddr; ///< Second Darc Board VME Address + Int_t fSecondDarcType; ///< Type of the first Darc Board + UChar_t fSecondDarcDisable; ///< disable the readout of the 8 crates connected to this board + UInt_t fSecondDarcL0Delay; ///< L0 delay for this board + UInt_t fSecondDarcL1TimeOut; ///< L1 time out for this board + UInt_t fSecondDarcGlobalL0; ///< Global L0 delay for this board + UInt_t fSecondDarcConfig ; ///< Trigger configuration this board + + ULong_t fGlobalVmeAddr; ///< Global Board VME Address + UInt_t fGlobalRegisters[13]; ///< Global registers + + ULong_t fFetVmeAddr; ///< Fet Board VME Address + UInt_t fFetRegisters[7]; ///< Fet registers + + static const Char_t* fgkJtagName; ///< JTag Board name + static const Char_t* fgkFirstDarcName; ///< First DARC board name + static const Char_t* fgkSecondDarcName; ///< Second DARC board name + static const Char_t* fgkGlobalName; ///< Global Board name + static const Char_t* fgkFetName; ///< FET Board name + + static const Int_t fgkGlobalNofRegisters; ///< Number of registers for Global Board + static const Int_t fgkFetNofRegisters; ///< Number of registers for Fet + static const Int_t fgkJtagNofLines; ///< Number of lines for Jtag + + ClassDef(AliMUONGlobalCrateConfig,2) +}; + +#endif + + + + + + + + + + + + + + diff --git a/MUON/AliMUONRawWriter.cxx b/MUON/AliMUONRawWriter.cxx index 3444154ff89..670a7e0ced2 100644 --- a/MUON/AliMUONRawWriter.cxx +++ b/MUON/AliMUONRawWriter.cxx @@ -65,6 +65,7 @@ #include "AliMpDDLStore.h" #include "AliMpDDL.h" +#include "AliMpRegionalTrigger.h" #include "AliMpTriggerCrate.h" #include "AliMpLocalBoard.h" #include "AliMpDetElement.h" @@ -556,9 +557,11 @@ Int_t AliMUONRawWriter::WriteTriggerDDL(const AliMUONVTriggerStore& triggerStore // end of global word buffer[index++] = fDarcHeader->GetEndOfGlobal(); + const AliMpRegionalTrigger* reg = AliMpDDLStore::Instance()->GetRegionalTrigger(); + Int_t nCrate = reg->GetNofTriggerCrates()/2; // 8 regional cards per DDL - for (Int_t iReg = 0; iReg < 8; ++iReg) { + for (Int_t iReg = 0; iReg < nCrate; ++iReg) { // crate info AliMpTriggerCrate* crate = AliMpDDLStore::Instance()->GetTriggerCrate(iDDL, iReg); @@ -567,8 +570,10 @@ Int_t AliMUONRawWriter::WriteTriggerDDL(const AliMUONVTriggerStore& triggerStore AliWarning(Form("Missing crate number %d in DDL %d\n", iReg, iDDL)); // regional info tree, make sure that no reg card missing - AliMUONRegionalTrigger* regTrg = triggerStore.FindRegional(iReg+iDDL*8); - + AliMUONRegionalTrigger* regTrg = triggerStore.FindRegional(crate->GetId()); + if (!regTrg) + AliError(Form("Missing regional board %d in trigger Store\n", crate->GetId())); + // Regional card header word = 0; @@ -605,7 +610,9 @@ Int_t AliMUONRawWriter::WriteTriggerDDL(const AliMUONVTriggerStore& triggerStore // 16 local card per regional board // UShort_t localMask = 0x0; - for (Int_t iLoc = 0; iLoc < 16; iLoc++) { + Int_t nLocalBoard = AliMpConstants::LocalBoardNofChannels(); + + for (Int_t iLoc = 0; iLoc < nLocalBoard; iLoc++) { // slot zero for Regional card Int_t localBoardId = crate->GetLocalBoardId(iLoc); diff --git a/MUON/AliMUONReconstructor.cxx b/MUON/AliMUONReconstructor.cxx index 5ad4de38e18..a34ce6ae94b 100644 --- a/MUON/AliMUONReconstructor.cxx +++ b/MUON/AliMUONReconstructor.cxx @@ -104,7 +104,6 @@ #include "AliMUONSimpleClusterServer.h" #include "AliMUONTracker.h" #include "AliMUONTriggerCircuit.h" -#include "AliMUONTriggerCrateStore.h" #include "AliMUONTriggerStoreV1.h" #include "AliMUONVClusterFinder.h" #include "AliMUONVClusterServer.h" @@ -135,7 +134,6 @@ AliMUONRecoParam* AliMUONReconstructor::fgRecoParam = 0x0; // reconstruction par //_____________________________________________________________________________ AliMUONReconstructor::AliMUONReconstructor() : AliReconstructor(), -fCrateManager(0x0), fDigitMaker(0x0), fTransformer(new AliMUONGeometryTransformer()), fDigitStore(0x0), @@ -165,7 +163,6 @@ AliMUONReconstructor::~AliMUONReconstructor() delete fDigitMaker; delete fDigitStore; delete fTransformer; - delete fCrateManager; delete fTriggerCircuit; delete fCalibrationData; delete fDigitCalibrator; @@ -261,17 +258,6 @@ AliMUONReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) } } -//_____________________________________________________________________________ -AliMUONTriggerCrateStore* -AliMUONReconstructor::CrateManager() const -{ - /// Return (and create if necessary) the trigger crate store - if (fCrateManager) return fCrateManager; - fCrateManager = new AliMUONTriggerCrateStore; - fCrateManager->ReadFromFile(); - return fCrateManager; -} - //_____________________________________________________________________________ void AliMUONReconstructor::CreateDigitMaker() const diff --git a/MUON/AliMUONReconstructor.h b/MUON/AliMUONReconstructor.h index 0994b9d9e59..cfd199de615 100644 --- a/MUON/AliMUONReconstructor.h +++ b/MUON/AliMUONReconstructor.h @@ -22,7 +22,6 @@ class AliMUONVTriggerStore; class AliMUONGeometryTransformer; -class AliMUONTriggerCrateStore; class AliMUONTriggerCircuit; class TClonesArray; class AliMUONVTriggerStore; @@ -69,7 +68,6 @@ private: AliMUONVDigitStore* digitStore, AliMUONVTriggerStore* triggerStore) const; void Calibrate(AliMUONVDigitStore& digitStore) const; - AliMUONTriggerCrateStore* CrateManager() const; void CreateCalibrator() const; void CreateDigitMaker() const; void CreateTriggerCircuit() const; @@ -81,7 +79,7 @@ private: AliMUONVTriggerStore* TriggerStore() const; private: - mutable AliMUONTriggerCrateStore* fCrateManager; //!< Trigger Crate manager + mutable AliMUONDigitMaker* fDigitMaker; //!< Raw to Digits converter AliMUONGeometryTransformer* fTransformer; //!< Geometry transformer (local<->global) mutable AliMUONVDigitStore* fDigitStore; //!< Digit container diff --git a/MUON/AliMUONRegionalTriggerConfig.cxx b/MUON/AliMUONRegionalTriggerConfig.cxx new file mode 100644 index 00000000000..f745d72c8d9 --- /dev/null +++ b/MUON/AliMUONRegionalTriggerConfig.cxx @@ -0,0 +1,213 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +// $Id$ +// $MpId: AliMpTrigger.cxx,v 1.4 2006/05/24 13:58:52 ivana Exp $ + +//----------------------------------------------------------------------------- +// Class AliMUONRegionalTriggerConfig +// -------------------- +// The class defines the configuration of regional trigger crate +// Author: Ch. Finck, Subatech Nantes +//----------------------------------------------------------------------------- + +#include "AliMUONRegionalTriggerConfig.h" +#include "AliMUONTriggerCrateConfig.h" +#include "AliMpConstants.h" +#include "AliMpFiles.h" +#include "AliMpHelper.h" + +#include "AliLog.h" + +#include +#include +#include +#include + + +/// \cond CLASSIMP +ClassImp(AliMUONRegionalTriggerConfig) +/// \endcond + + +//______________________________________________________________________________ +AliMUONRegionalTriggerConfig::AliMUONRegionalTriggerConfig() + : TObject(), + fTriggerCrates(true) +{ +/// Standard constructor + + fTriggerCrates.SetOwner(true); + fTriggerCrates.SetSize(AliMpConstants::LocalBoardNofChannels()); +} + +//______________________________________________________________________________ +AliMUONRegionalTriggerConfig::AliMUONRegionalTriggerConfig(const AliMUONRegionalTriggerConfig& rhs) + : TObject(rhs), + fTriggerCrates(rhs.fTriggerCrates) +{ +/// Copy constructor +} + +//______________________________________________________________________________ +AliMUONRegionalTriggerConfig& AliMUONRegionalTriggerConfig::operator=(const AliMUONRegionalTriggerConfig& rhs) +{ +/// Assignment operator + + // check assignment to self + if (this == &rhs) return *this; + + // base class assignment + TObject::operator=(rhs); + + // assignment operator + fTriggerCrates = rhs.fTriggerCrates; + + return *this; +} + +//______________________________________________________________________________ +AliMUONRegionalTriggerConfig::~AliMUONRegionalTriggerConfig() +{ +/// Destructor +} + +// +// public methods +// + +//______________________________________________________________________________ +Int_t AliMUONRegionalTriggerConfig::ReadData(const TString& fileName) +{ +/// Load the Regional trigger from ASCII data files +/// and return its instance + + TString inFileName(fileName); + if ( inFileName == "" ) + inFileName = AliMpFiles::LocalTriggerBoardMapping(); + + inFileName = gSystem->ExpandPathName(inFileName.Data()); + + ifstream in(inFileName.Data(), ios::in); + + if (!in) { + AliErrorStream() + << "Local Trigger Board Mapping File " << fileName.Data() << " not found" << endl; + return kFALSE; + } + + AliMUONTriggerCrateConfig* crate = 0x0; + + TArrayI list; + UShort_t crateId, mask; + Int_t mode, coincidence; + Int_t localBoardId = 0; + char line[80]; + + while (!in.eof()) + { + in.getline(line,80); + if (!strlen(line)) break; + TString crateName(AliMpHelper::Normalize(line)); + + in.getline(line,80); + sscanf(line,"%hx",&crateId); + + in.getline(line,80); + sscanf(line,"%d",&mode); + + in.getline(line,80); + sscanf(line,"%d",&coincidence); + + in.getline(line,80); + sscanf(line,"%hx",&mask); + + crate = (AliMUONTriggerCrateConfig*)(fTriggerCrates.GetValue(crateName.Data())); + if (!crate) + { + // cout << "Creating crate: " << crateName.Data() << endl; + crate = new AliMUONTriggerCrateConfig(crateName.Data(), crateId, mask, mode, coincidence); + fTriggerCrates.Add(crateName.Data(), crate); + } + + Char_t localBoardName[20]; + Int_t slot; + UInt_t switches; + + for ( Int_t i = 0; i < AliMpConstants::LocalBoardNofChannels(); ++i ) + { + if ( (mask >> i ) & 0x1 ) + { + // read local board + in.getline(line,80); + sscanf(line,"%02d %s %03d %03x",&slot,localBoardName,&localBoardId,&switches); + crate->AddLocalBoard(localBoardId); + + // skip DEs for local board + in.getline(line,80); + + // skip copy number and transverse connector + in.getline(line,80); + } + } + } + return fTriggerCrates.GetSize(); +} + + +//______________________________________________________________________________ +AliMUONTriggerCrateConfig* AliMUONRegionalTriggerConfig::FindTriggerCrate(TString name, + Bool_t warn) const { + /// Return trigger crate with given name + + AliMUONTriggerCrateConfig* crate + = (AliMUONTriggerCrateConfig*) fTriggerCrates.GetValue(name.Data()); + + if ( ! crate && warn ) { + AliErrorStream() + << "Trigger crate with name = " << name.Data() << " not defined." << endl; + } + + return crate; +} + +//______________________________________________________________________________ +Int_t AliMUONRegionalTriggerConfig::GetNofTriggerCrates() const +{ + /// Return number of trigger crates + + return fTriggerCrates.GetSize(); +} + +//______________________________________________________________________________ +AliMUONTriggerCrateConfig* AliMUONRegionalTriggerConfig::GetTriggerCrate(Int_t index) const +{ + /// Return the trigger crates with given index; + + return static_cast(fTriggerCrates.GetObject(index)); +} + +//______________________________________________________________________________ +AliMUONTriggerCrateConfig* AliMUONRegionalTriggerConfig::GetTriggerCrateFast(Int_t index) const +{ + /// Return the trigger crates with given index; + /// the index is not checked as we use the fast method in AliMpExMap. + + return static_cast(fTriggerCrates.GetObjectFast(index)); +} + + + + diff --git a/MUON/AliMUONRegionalTriggerConfig.h b/MUON/AliMUONRegionalTriggerConfig.h new file mode 100644 index 00000000000..99b7c1a9e76 --- /dev/null +++ b/MUON/AliMUONRegionalTriggerConfig.h @@ -0,0 +1,72 @@ +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +// $MpId: $ + +/// \ingroup calib +/// \class AliMUONRegionalTriggerConfig +/// \brief The class defines the properties of regional trigger crate +/// +/// \author Ch. Finck, Subatech Nantes; I. Hrivnacova, IPN Orsay + +#ifndef ALIMUON_REGIONAL_TRIGGER_CONFIG_H +#define ALIMUON_REGIONAL_TRIGGER_CONFIG_H + +#include + +#include "AliMpExMap.h" + +#include + +class AliMUONTriggerCrateConfig; +class AliMUONLocalBoardConfig; + +class AliMUONRegionalTriggerConfig : public TObject{ + + public: + AliMUONRegionalTriggerConfig(); + AliMUONRegionalTriggerConfig(const AliMUONRegionalTriggerConfig& rhs); + virtual ~AliMUONRegionalTriggerConfig(); + + // operators + AliMUONRegionalTriggerConfig& operator=(const AliMUONRegionalTriggerConfig& rhs); + + // methods + Int_t ReadData(const TString& fileName = ""); + + AliMUONTriggerCrateConfig* FindTriggerCrate(TString crateName, Bool_t warn = true) const; + + // method for looping + + Int_t GetNofTriggerCrates() const; + AliMUONTriggerCrateConfig* GetTriggerCrate(Int_t index) const; + AliMUONTriggerCrateConfig* GetTriggerCrateFast(Int_t index) const; + TExMapIter GetTriggerCrateItr() const; + + + private: + // data members + AliMpExMap fTriggerCrates; ///< map for trigger crates + + ClassDef(AliMUONRegionalTriggerConfig,1) // Regional trigger crate config +}; + +/// Return trigger crates iterator +inline TExMapIter AliMUONRegionalTriggerConfig::GetTriggerCrateItr() const { + return fTriggerCrates.GetIterator(); +} +#endif + + + + + + + + + + + + + + diff --git a/MUON/AliMUONTriggerCrateConfig.cxx b/MUON/AliMUONTriggerCrateConfig.cxx new file mode 100644 index 00000000000..c37dec7497a --- /dev/null +++ b/MUON/AliMUONTriggerCrateConfig.cxx @@ -0,0 +1,117 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +// $Id$ +// $MpId: AliMpTrigger.cxx,v 1.4 2006/05/24 13:58:52 ivana Exp $ + +//----------------------------------------------------------------------------- +// Class AliMUONTriggerCrateConfig +// -------------------- +// The class defines the configuration of trigger crate +// Author: Ch. Finck, Subatech Nantes +//----------------------------------------------------------------------------- + +#include "AliMUONTriggerCrateConfig.h" + +#include "AliLog.h" + +#include + +/// \cond CLASSIMP +ClassImp(AliMUONTriggerCrateConfig) +/// \endcond + + + //______________________________________________________________________________ +AliMUONTriggerCrateConfig::AliMUONTriggerCrateConfig() + : TNamed("Trigger Crate","configuration trigger crate"), + fId(0), + fMask(0), + fMode(0), + fCoinc(0), + fLocalBoard(false) +{ +/// Standard constructor for Shuttle + DA +} + + + //______________________________________________________________________________ +AliMUONTriggerCrateConfig::AliMUONTriggerCrateConfig(const Char_t* name, UShort_t id, UShort_t mask, UShort_t mode, UShort_t coinc) + : TNamed(name, "configuration trigger crate"), + fId(id), + fMask(mask), + fMode(mode), + fCoinc(coinc), + fLocalBoard(false) +{ +/// Standard constructor for Shuttle + DA +} + + +//______________________________________________________________________________ +AliMUONTriggerCrateConfig::~AliMUONTriggerCrateConfig() +{ +/// Destructor +} + +// +// public methods +// + +//______________________________________________________________________________ +Bool_t AliMUONTriggerCrateConfig::AddLocalBoard(Int_t localBoardId) +{ +/// Add detection element with given detElemId. +/// Return true if the detection element was added + + if ( HasLocalBoard(localBoardId) ) { + AliWarningStream() + << "Local board with Id=" << localBoardId << " already present." + << endl; + return false; + } + + fLocalBoard.Add(localBoardId); + return true; +} + + +//______________________________________________________________________________ +Int_t AliMUONTriggerCrateConfig::GetNofLocalBoards() const +{ +/// Return the number of local board in this crate + + return fLocalBoard.GetSize(); +} + +//______________________________________________________________________________ +Int_t AliMUONTriggerCrateConfig::GetLocalBoardId(Int_t index) const +{ +/// Return the local board by index (in loop) + + if (index >= 0 && index < fLocalBoard.GetSize()) + return fLocalBoard.GetValue(index); + else + return 0; // begin at 1 +} + +//______________________________________________________________________________ +Bool_t AliMUONTriggerCrateConfig::HasLocalBoard(Int_t localBoardId) const +{ +/// Return true if crate has local boardwith given localBoardId + + return fLocalBoard.HasValue(localBoardId); +} + diff --git a/MUON/AliMUONTriggerCrateConfig.h b/MUON/AliMUONTriggerCrateConfig.h new file mode 100644 index 00000000000..37c38a3d59a --- /dev/null +++ b/MUON/AliMUONTriggerCrateConfig.h @@ -0,0 +1,89 @@ +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +// $MpId: $ + +/// \ingroup calib +/// \class AliMUONTriggerCrateConfig +/// \brief The class defines the configuration of trigger crate +/// +/// \author Ch. Finck, Subatech Nantes + +#ifndef ALIMUON_TRIGGER_CRATE_CONFIG_H +#define ALIMUON_TRIGGER_CRATE_CONFIG_H + +#include "AliMpArrayI.h" + +#include +#include +#include "AliMpArrayI.h" + +class AliMUONTriggerCrateConfig : public TNamed { + + public: + + AliMUONTriggerCrateConfig(); + AliMUONTriggerCrateConfig(const Char_t* name, UShort_t Id, UShort_t mask, + UShort_t mode, UShort_t coinc); + virtual ~AliMUONTriggerCrateConfig(); + + /// get methods + UShort_t GetId() const; + UShort_t GetMask() const; + UShort_t GetMode() const; + UShort_t GetCoinc() const; + Int_t GetNofLocalBoards() const; + Int_t GetLocalBoardId(Int_t index) const; + Bool_t HasLocalBoard(Int_t localBoardId) const; + Bool_t AddLocalBoard(Int_t localBoardId); + + private: + + /// Not implemented + AliMUONTriggerCrateConfig(const AliMUONTriggerCrateConfig& rhs); + /// Not implemented + AliMUONTriggerCrateConfig& operator=(const AliMUONTriggerCrateConfig& rhs); + + // data members + UShort_t fId; ///< crate number + UShort_t fMask; ///< regional mask + UShort_t fMode; ///< mode operating for crate + UShort_t fCoinc; ///< coincidence mode for crate + AliMpArrayI fLocalBoard; ///< local board connected to this crate + + ClassDef(AliMUONTriggerCrateConfig,1) // The class collectiong electronics properties of DDL +}; + +// inline functions + +/// Return Id +inline UShort_t AliMUONTriggerCrateConfig::GetId() const +{ return fId; } + +/// Return mask +inline UShort_t AliMUONTriggerCrateConfig::GetMask() const +{ return fMask; } + +/// Return Mode +inline UShort_t AliMUONTriggerCrateConfig::GetMode() const +{ return fMode; } + +/// Return coinc +inline UShort_t AliMUONTriggerCrateConfig::GetCoinc() const +{ return fCoinc; } + +#endif + + + + + + + + + + + + + + diff --git a/MUON/AliMUONTriggerCrateStore.cxx b/MUON/AliMUONTriggerCrateStore.cxx index 12f3616efe0..2a2f715f466 100644 --- a/MUON/AliMUONTriggerCrateStore.cxx +++ b/MUON/AliMUONTriggerCrateStore.cxx @@ -20,6 +20,11 @@ #include "AliMUONTriggerCrate.h" #include "AliMUONLocalTriggerBoard.h" #include "AliMUONRegionalTriggerBoard.h" +#include "AliMUONRegionalTriggerConfig.h" +#include "AliMUONGlobalCrateConfig.h" +#include "AliMUONTriggerCrateConfig.h" +#include "AliMUONCalibrationData.h" +#include "AliMUONTriggerLut.h" #include "AliMpTriggerCrate.h" #include "AliMpLocalBoard.h" @@ -278,24 +283,36 @@ AliMUONTriggerCrateStore::NumberOfLocalBoards() const //_____________________________________________________________________________ void -AliMUONTriggerCrateStore::ReadFromFile(const char* /*file*/) // keep old name for the moment +AliMUONTriggerCrateStore::ReadFromFile(AliMUONCalibrationData* calibData) { - /// create crate and local board objects from mapping (Ch.F) + /// create crate and local board objects from mapping & calib (Ch.F) fCrates = new AliMpExMap(kTRUE); fCrates->SetOwner(kTRUE); fLocalBoards = new AliMpExMap(kTRUE); fLocalBoards->SetOwner(kFALSE); - TExMapIter itr = AliMpDDLStore::Instance()->GetTriggerCrateItr(); + + AliMUONTriggerLut* lut = calibData->TriggerLut(); + if (!lut) + AliWarning("No valid trigger LUT in CDB"); + + AliMUONRegionalTriggerConfig* regionalConfig = calibData->RegionalTriggerConfig(); + if (!regionalConfig) + AliWarning("No valid regional trigger configuration in CDB"); + + TExMapIter itr = AliMpDDLStore::Instance()->GetTriggerCrateItr(); + Long_t key, value; - + while(itr.Next(key, value)) { AliMpTriggerCrate* crateMapping = reinterpret_cast(value); - + TString crateName = crateMapping->GetName(); AliMUONTriggerCrate *crate = Crate(crateName.Data()); + + AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crateName); if (!crate) { @@ -307,23 +324,26 @@ AliMUONTriggerCrateStore::ReadFromFile(const char* /*file*/) // keep old name fo } for(Int_t iLocal = 0; iLocal < crateMapping->GetNofLocalBoards(); ++iLocal) { - + Int_t localBoardId = crateMapping->GetLocalBoardId(iLocal); if (!localBoardId) continue; //empty slot, should not happen AliMpLocalBoard* localBoardMapping = AliMpDDLStore::Instance()->GetLocalBoard(localBoardId); AliDebug(3, Form("local name %s id %d\n", localBoardMapping->GetName(), localBoardId)); - + Int_t slot = localBoardMapping->GetSlot(); - AliMUONLocalTriggerBoard *board = - new AliMUONLocalTriggerBoard(localBoardMapping); + AliMUONLocalTriggerBoard *board = new AliMUONLocalTriggerBoard(localBoardMapping); + board->SetCoinc44(crateConfig->GetCoinc()); + board->SetLUT(lut); + if (localBoardMapping->IsNotified()) { fLocalBoards->Add(localBoardId, board); } - + crate->AddBoard(board, slot); - + } // iLocal } // while } + diff --git a/MUON/AliMUONTriggerCrateStore.h b/MUON/AliMUONTriggerCrateStore.h index e2460fa0097..6a5e81d44e8 100644 --- a/MUON/AliMUONTriggerCrateStore.h +++ b/MUON/AliMUONTriggerCrateStore.h @@ -22,6 +22,7 @@ class AliMUONLocalTriggerBoard; class AliMUONTriggerCrate; class AliMpExMap; class TExMapIter; +class AliMUONCalibrationData; class AliMUONTriggerCrateStore : public TObject { @@ -40,8 +41,7 @@ public: AliMUONLocalTriggerBoard* NextLocalBoard(); AliMUONLocalTriggerBoard* LocalBoard(Int_t boardNumber) const; - void ReadFromFile(const char* crateFile = ""); - + void ReadFromFile(AliMUONCalibrationData* calibData); protected: /// Not implemented diff --git a/MUON/AliMUONTriggerElectronics.cxx b/MUON/AliMUONTriggerElectronics.cxx index 79f938f34cc..eff5ec42473 100644 --- a/MUON/AliMUONTriggerElectronics.cxx +++ b/MUON/AliMUONTriggerElectronics.cxx @@ -41,6 +41,9 @@ #include "AliMUONTriggerCrate.h" #include "AliMUONTriggerCrateStore.h" #include "AliMUONTriggerElectronics.h" +#include "AliMUONTriggerCrateConfig.h" +#include "AliMUONRegionalTriggerConfig.h" +#include "AliMUONGlobalCrateConfig.h" #include "AliMUONVTriggerStore.h" #include "AliMUONVCalibParam.h" #include "AliMpCathodType.h" @@ -82,8 +85,9 @@ AliMUONTriggerElectronics::AliMUONTriggerElectronics(AliMUONCalibrationData* cal } SetCopyInput(); + Factory(calibData); - LoadMasks(calibData); + LoadMasks(calibData); } //___________________________________________ @@ -99,22 +103,23 @@ AliMUONTriggerElectronics::~AliMUONTriggerElectronics() } } + //___________________________________________ void AliMUONTriggerElectronics::SetCopyInput() { -/// set list of copy input - + /// set list of copy input + for (Int_t iDDL = 0; iDDL < 2; ++iDDL) { - + for(Int_t iReg = 0; iReg < 8; ++iReg){ //reg loop - + AliMpTriggerCrate* crateMapping = AliMpDDLStore::Instance()->GetTriggerCrate(iDDL, iReg); - + for(Int_t iLocal = 0; iLocal < crateMapping->GetNofLocalBoards(); ++iLocal) { - + Int_t localBoardFromId = crateMapping->GetLocalBoardId(iLocal); if (!localBoardFromId) continue; //empty slot, should not happen - + AliMpLocalBoard* localBoardFrom = AliMpDDLStore::Instance()->GetLocalBoard(localBoardFromId); Int_t localBoardToId; if ((localBoardToId = localBoardFrom->GetInputXto())) { @@ -123,25 +128,25 @@ void AliMUONTriggerElectronics::SetCopyInput() Int_t slotFrom = localBoardFrom->GetSlot(); TString crateTo = localBoardTo->GetCrate(); Int_t slotTo = localBoardTo->GetSlot(); - + fCopyXInput[0]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateFrom), slotFrom)); fCopyXInput[1]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateTo), slotTo)); AliDebug(3, Form("copy xInputs from local %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, crateTo.Data(), slotTo)); } - + if ((localBoardToId = localBoardFrom->GetInputYto())) { AliMpLocalBoard* localBoardTo = AliMpDDLStore::Instance()->GetLocalBoard(localBoardToId); TString crateFrom = localBoardFrom->GetCrate(); Int_t slotFrom = localBoardFrom->GetSlot(); TString crateTo = localBoardTo->GetCrate(); Int_t slotTo = localBoardTo->GetSlot(); - + fCopyYInput[0]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateFrom), slotFrom)); fCopyYInput[1]->Add(new AliMpIntPair(AliMpExMap::GetIndex(crateTo), slotTo)); AliDebug(3, Form("copy yInputs from local %s_%d to %s_%d\n", crateFrom.Data(), slotFrom, crateTo.Data(), slotTo)); - + } } @@ -155,31 +160,7 @@ void AliMUONTriggerElectronics::Factory(AliMUONCalibrationData* calibData) /// BUILD ALL ELECTRONICS /// -// get coinc44 from AliMUON (added 12/09/06) - AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); - Int_t coinc44 = pMUON->GetTriggerCoinc44(); - if (coinc44 != 0 && coinc44 != 1) { - AliFatal("Coinc 44 should be equal to 0 or 1"); - return; - } - - fCrates->ReadFromFile(); - - if ( !calibData ) return; - - AliMUONTriggerLut* lut = calibData->TriggerLut(); - - if (!lut) return; - - AliMUONLocalTriggerBoard* localBoard; - - fCrates->FirstLocalBoard(); - - while ( (localBoard=fCrates->NextLocalBoard()) ) - { - localBoard->SetLUT(lut); - localBoard->SetCoinc44(coinc44); - } + fCrates->ReadFromFile(calibData); } //___________________________________________ @@ -428,13 +409,18 @@ void AliMUONTriggerElectronics::Reset() } } + //_______________________________________________________________________ void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData) { - /// LOAD MASKS FROM CDB + /// Load mask from config in CDB + // Set mask + + AliMUONRegionalTriggerConfig* regionalConfig = calibData->RegionalTriggerConfig(); + if (!regionalConfig) + AliWarning("No valid regional trigger configuration in CDB"); - // SET MASKS AliMUONTriggerCrate* cr; @@ -446,12 +432,17 @@ void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData) { TObjArray *boards = cr->Boards(); - AliMUONRegionalTriggerBoard *regb = - (AliMUONRegionalTriggerBoard*)boards->At(0); + AliMUONRegionalTriggerBoard *regb = (AliMUONRegionalTriggerBoard*)boards->At(0); - AliMUONVCalibParam* regionalBoardMasks = calibData->RegionalTriggerBoardMasks(irb); + AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(cr->GetName()); + + if (!crateConfig) + { + AliError(Form("Crate %s not present in configuration !!!", cr->GetName())); + return; + } - UShort_t rmask = static_cast(regionalBoardMasks->ValueAsInt(0) & 0xFFFF); + UShort_t rmask= crateConfig->GetMask(); regb->Mask(rmask); @@ -474,14 +465,17 @@ void AliMUONTriggerElectronics::LoadMasks(AliMUONCalibrationData* calibData) ++irb; } - AliMUONVCalibParam* globalBoardMasks = calibData->GlobalTriggerBoardMasks(); - for ( Int_t i = 0; i < globalBoardMasks->Size(); ++i ) - { - UShort_t gmask = static_cast(globalBoardMasks->ValueAsInt(i) & 0xFF); - fGlobalTriggerBoard->Mask(i,gmask); - } -} + AliMUONGlobalCrateConfig * globalConfig = calibData->GlobalTriggerCrateConfig(); + if (!globalConfig) + AliWarning("No valid trigger crate configuration in CDB"); + UShort_t gmask = 0; + gmask = globalConfig->GetFirstDarcDisable(); + fGlobalTriggerBoard->Mask(0,gmask); + + gmask = globalConfig->GetSecondDarcDisable(); + fGlobalTriggerBoard->Mask(1,gmask); +} //___________________________________________ void AliMUONTriggerElectronics::LocalResponse() diff --git a/MUON/AliMUONTriggerGUI.cxx b/MUON/AliMUONTriggerGUI.cxx index 2584a57f31c..bad8db0cf30 100644 --- a/MUON/AliMUONTriggerGUI.cxx +++ b/MUON/AliMUONTriggerGUI.cxx @@ -1028,7 +1028,7 @@ void AliMUONTriggerGUI::InitBoards() fBoardsInit = kTRUE; AliMUONTriggerCrateStore* crateManager = new AliMUONTriggerCrateStore(); - crateManager->ReadFromFile(); + crateManager->ReadFromFile(0x0); Int_t nPixelX = 700; Int_t nPixelY = 676; diff --git a/MUON/AliMUONTriggerGUIbdmap.cxx b/MUON/AliMUONTriggerGUIbdmap.cxx index bc6e9901af7..17fc2fd89e2 100644 --- a/MUON/AliMUONTriggerGUIbdmap.cxx +++ b/MUON/AliMUONTriggerGUIbdmap.cxx @@ -275,7 +275,7 @@ void AliMUONTriggerGUIbdmap::LocalTriggerInfo() /// print the local trigger AliMUONTriggerCrateStore* crateManager = new AliMUONTriggerCrateStore(); - crateManager->ReadFromFile(); + crateManager->ReadFromFile(0x0); TGText txt; Char_t buffer[20]; diff --git a/MUON/AliMUONTriggerIO.cxx b/MUON/AliMUONTriggerIO.cxx index 549b15c74b2..343b1c54e5f 100644 --- a/MUON/AliMUONTriggerIO.cxx +++ b/MUON/AliMUONTriggerIO.cxx @@ -28,6 +28,9 @@ #include "AliMpDDLStore.h" #include "AliMpLocalBoard.h" #include "AliMpTriggerCrate.h" +#include "AliMUONGlobalCrateConfig.h" +#include "AliMUONRegionalTriggerConfig.h" +#include "AliMUONTriggerCrateConfig.h" #include "AliLog.h" @@ -46,6 +49,9 @@ ClassImp(AliMUONTriggerIO) /// \endcond + +const UInt_t AliMUONTriggerIO::fgkLocalLutSize = 1 << 14; // 16384 + //_____________________________________________________________________________ AliMUONTriggerIO::AliMUONTriggerIO() : TObject(), @@ -62,7 +68,7 @@ AliMUONTriggerIO::AliMUONTriggerIO(const char* regionalFileToRead) fGlobalCrate() { /// ctor - ReadRegional(regionalFileToRead,0); + ReadRegionalConfig(regionalFileToRead,0); } //_____________________________________________________________________________ @@ -256,7 +262,7 @@ AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut, UShort_t address; - UChar_t buffer[16384]; // 32768 hpt/lpt addresses divided by two + UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two UChar_t mask1 = 0xF0; UChar_t mask2 = 0x0F; UChar_t maskHpt = 0x0C; @@ -275,10 +281,10 @@ AliMUONTriggerIO::ReadLocalLUT(AliMUONTriggerLut& lut, Bool_t trigx = kFALSE; // read two lut addresses at once, 32768/2=16384 times - fread(buffer,16384,1,flut); + fread(buffer,fgkLocalLutSize,1,flut); // create the 32767 addresses for the 4-bits lpt and hpt half-bytes - for (UShort_t ilut = 0; ilut < 32768; ilut += 2) + for (UShort_t ilut = 0; ilut < fgkLocalLutSize*2; ilut += 2) { // 1st 4-bits half-byte @@ -375,13 +381,12 @@ AliMUONTriggerIO::ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut) //_____________________________________________________________________________ Bool_t -AliMUONTriggerIO::ReadMasks(const char* localFile, +AliMUONTriggerIO::ReadConfig(const char* localFile, const char* regionalFile, const char* globalFile, AliMUONVStore* localMasks, - AliMUONVStore* regionalMasks, - AliMUONVCalibParam* globalMasks, - Bool_t warn) + AliMUONRegionalTriggerConfig* regionalConfig, + AliMUONGlobalCrateConfig* globalConfig) { /// Fill the various masks store from files @@ -391,7 +396,7 @@ AliMUONTriggerIO::ReadMasks(const char* localFile, return kFALSE; } - Int_t nCrates = ReadRegional(regionalFile,regionalMasks, warn); + Int_t nCrates = ReadRegionalConfig(regionalFile, regionalConfig); if (!nCrates) return kFALSE; @@ -401,7 +406,7 @@ AliMUONTriggerIO::ReadMasks(const char* localFile, AliDebug(1,Form("Read masks for %d local boards",nLocal)); } - Int_t nDarc = ReadGlobal(globalFile, globalMasks); + Int_t nDarc = ReadGlobalConfig(globalFile, globalConfig); AliDebug(1,Form("Read disable for %d DARC boards",nDarc)); if (!nDarc) return kFALSE; @@ -409,73 +414,37 @@ AliMUONTriggerIO::ReadMasks(const char* localFile, return kTRUE; } + + //_____________________________________________________________________________ Int_t - AliMUONTriggerIO::ReadGlobal(const char* globalFile, AliMUONVCalibParam* globalMasks) + AliMUONTriggerIO::ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) { - /// read the global crate file and file corresponding mask + /// read the global crate file /// the masks are disable bit for each crate, 8 per darc board /// bit value 0 means enable, 1 means disable * Int_t nDarc = 0; - if ( ! fGlobalCrate.ReadData(globalFile) ) return 0; - - UChar_t mask = fGlobalCrate.GetFirstDarcDisable(); - ULong_t vmeAddr = fGlobalCrate.GetFirstDarcVmeAddr(); - if (vmeAddr) nDarc++; - globalMasks->SetValueAsInt(0,0,mask); - - mask = fGlobalCrate.GetSecondDarcDisable(); - vmeAddr = fGlobalCrate.GetSecondDarcVmeAddr(); - if (vmeAddr) nDarc++; - globalMasks->SetValueAsInt(1,0,mask); + if ( !(nDarc = globalConfig->ReadData(globalFile)) ) return 0; return nDarc; } //_____________________________________________________________________________ Int_t -AliMUONTriggerIO::ReadRegional(const char* regionalFile, AliMUONVStore* regionalMasks, Bool_t warn) +AliMUONTriggerIO::ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) { - /// Read regional file to fill the regional mask store *AND* - /// determine the order in which local boards will appear in local - /// and lut files. - - if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0; + /// Read regional file to fill + Int_t nCrates = 0; + if ( !(nCrates = regionalConfig->ReadData(regionalFile)) ) return 0; - Int_t nCrates(0); - - for (Int_t iCrate = 0; iCrate < fRegionalTrigger.GetNofTriggerCrates(); ++iCrate) - { + // read the mapping file also + if ( ! fRegionalTrigger.ReadData(regionalFile) ) return 0; - AliMpTriggerCrate* crate = fRegionalTrigger.GetTriggerCrateFast(iCrate); - - if (warn) - { - AliMpTriggerCrate* triggerCrate = AliMpDDLStore::Instance()->GetTriggerCrate(crate->GetName()); - - if (!triggerCrate) - { - AliError(Form("Mapping error : could not get crate %s", crate->GetName())); - return 0; - } - } - nCrates++; - - UShort_t masks = 0; - if (regionalMasks != 0x0) - { - masks = crate->GetMask(); - - AliMUONVCalibParam* regionalBoard = new AliMUONCalibParamNI(1, 1, crate->GetId(), 0, 0); - regionalBoard->SetValueAsInt(0, 0, masks); - regionalMasks->Add(regionalBoard); - } - } - return nCrates; } + //_____________________________________________________________________________ Bool_t AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut, @@ -506,30 +475,34 @@ AliMUONTriggerIO::WriteLUT(const AliMUONTriggerLut& lut, return kTRUE; } + //_____________________________________________________________________________ -Bool_t -AliMUONTriggerIO::WriteMasks(const char* localFile, +Bool_t +AliMUONTriggerIO::WriteConfig(const char* localFile, const char* regionalFile, const char* globalFile, AliMUONVStore* localMasks, - AliMUONVStore* regionalMasks, - AliMUONVCalibParam* globalMasks) const + AliMUONRegionalTriggerConfig* regionalConfig, + AliMUONGlobalCrateConfig* globalConfig) const { - /// write mask files +/// write config files + Bool_t ok; - ok = WriteLocalMasks(localFile, *localMasks); - ok &= WriteRegional(regionalFile, regionalMasks); - ok &= WriteGlobal(globalFile, globalMasks); + ok = WriteLocalMasks(localFile, *localMasks, regionalConfig); + ok &= WriteRegionalConfig(regionalFile, regionalConfig); + ok &= WriteGlobalConfig(globalFile, globalConfig); return ok; + + } + //_____________________________________________________________________________ Bool_t -AliMUONTriggerIO::WriteGlobal(const char* globalFile, AliMUONVCalibParam* globalMasks) const +AliMUONTriggerIO::WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const { - /// write global file - /// if no global masks defined take the one of configuration + /// write global config ofstream out; Int_t disable = 0; @@ -537,73 +510,71 @@ AliMUONTriggerIO::WriteGlobal(const char* globalFile, AliMUONVCalibParam* global out.open(globalFile); if (!out.good()) { - AliError(Form("Could not create output regional file %s", globalFile)); + AliError(Form("Could not create output global file %s", globalFile)); return kFALSE; } - out << fGlobalCrate.GetName() << endl; - + out << globalConfig->GetName() << endl; + out << globalConfig->GetGlobalCrateEnable() << endl; + // Jtag - out << fGlobalCrate.GetJtagName() << endl; - out << Form("0x%08x", fGlobalCrate.GetJtagVmeAddr()) << endl; - out << Form("%d %d %d", fGlobalCrate.GetJtagClockDiv(), - fGlobalCrate.GetJtagRxPhase(), fGlobalCrate.GetJtagRdDelay()) << endl; + out << globalConfig->GetJtagName() << endl; + out << Form("0x%08x", globalConfig->GetJtagVmeAddr()) << endl; + out << Form("%d %d %d", globalConfig->GetJtagClockDiv(), + globalConfig->GetJtagRxPhase(), globalConfig->GetJtagRdDelay()) << endl; - for (Int_t i = 0; i < fGlobalCrate.GetJtagNofLines(); ++i) - out << Form("%d ", fGlobalCrate.GetEnableJtag(i)); + for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i) + out << Form("%d ", globalConfig->GetEnableJtag(i)); out << endl; - for (Int_t i = 0; i < fGlobalCrate.GetJtagNofLines(); ++i) + for (Int_t i = 0; i < globalConfig->GetJtagNofLines(); ++i) { out << i << endl; - for (Int_t j = 0; j < fGlobalCrate.GetJtagNofLines(); ++j) - out << Form(" %s", fGlobalCrate.GetJtagCrateName(i,j).Data()) << endl; + for (Int_t j = 0; j < globalConfig->GetJtagNofLines(); ++j) + out << Form(" %s", globalConfig->GetJtagCrateName(i,j).Data()) << endl; } // first darc board - out << fGlobalCrate.GetFirstDarcName() << endl; - out << Form("0x%08x", fGlobalCrate.GetFirstDarcVmeAddr()) << endl; - out << fGlobalCrate.GetFirstDarcType() << endl; - if (globalMasks != 0x0) - disable = globalMasks->ValueAsInt(0); - else - disable = fGlobalCrate.GetFirstDarcDisable(); + out << globalConfig->GetFirstDarcName() << endl; + out << Form("0x%08x", globalConfig->GetFirstDarcVmeAddr()) << endl; + out << globalConfig->GetFirstDarcType() << endl; + disable = globalConfig->GetFirstDarcDisable(); out << Form("0x%02x", disable) << endl; - out << Form("0x%x", fGlobalCrate.GetFirstDarcL0Delay()) << endl; - out << Form("0x%x", fGlobalCrate.GetFirstDarcL1TimeOut()) << endl; + out << Form("0x%x", globalConfig->GetFirstDarcL0Delay()) << endl; + out << Form("0x%x", globalConfig->GetFirstDarcL1TimeOut()) << endl; + out << Form("0x%x", globalConfig->GetFirstDarcGlobalL0()) << endl; + out << Form("0x%x", globalConfig->GetFirstDarcConfig()) << endl; // second darc board - out << fGlobalCrate.GetSecondDarcName() << endl; - out << Form("0x%08x", fGlobalCrate.GetSecondDarcVmeAddr()) << endl; - out << fGlobalCrate.GetSecondDarcType() << endl; - if (globalMasks != 0x0) - disable = globalMasks->ValueAsInt(1); - else - disable = fGlobalCrate.GetSecondDarcDisable(); + out << globalConfig->GetSecondDarcName() << endl; + out << Form("0x%08x", globalConfig->GetSecondDarcVmeAddr()) << endl; + out << globalConfig->GetSecondDarcType() << endl; + disable = globalConfig->GetSecondDarcDisable(); out << Form("0x%02x", disable) << endl; - out << Form("0x%x", fGlobalCrate.GetSecondDarcL0Delay()) << endl; - out << Form("0x%x", fGlobalCrate.GetSecondDarcL1TimeOut()) << endl; + out << Form("0x%x", globalConfig->GetSecondDarcL0Delay()) << endl; + out << Form("0x%x", globalConfig->GetSecondDarcL1TimeOut()) << endl; + out << Form("0x%x", globalConfig->GetSecondDarcGlobalL0()) << endl; + out << Form("0x%x", globalConfig->GetSecondDarcConfig()) << endl; // global board - out << fGlobalCrate.GetGlobalName() << endl; - out << Form("0x%08x", fGlobalCrate.GetGlobalVmeAddr()) << endl; - for (Int_t i = 0; i < fGlobalCrate.GetGlobalNofRegisters(); ++i) - out << Form("0x%x", fGlobalCrate.GetGlobalRegister(i)) << endl; + out << globalConfig->GetGlobalName() << endl; + out << Form("0x%08x", globalConfig->GetGlobalVmeAddr()) << endl; + for (Int_t i = 0; i < globalConfig->GetGlobalNofRegisters(); ++i) + out << Form("0x%x", globalConfig->GetGlobalRegister(i)) << endl; // Fet board - out << fGlobalCrate.GetFetName() << endl; - out << Form("0x%08x", fGlobalCrate.GetFetVmeAddr()) << endl; - for (Int_t i = 0; i < fGlobalCrate.GetFetNofRegisters(); ++i) - out << Form("0x%x", fGlobalCrate.GetFetRegister(i)) << endl; + out << globalConfig->GetFetName() << endl; + out << Form("0x%08x", globalConfig->GetFetVmeAddr()) << endl; + for (Int_t i = 0; i < globalConfig->GetFetNofRegisters(); ++i) + out << Form("0x%x", globalConfig->GetFetRegister(i)) << endl; return kTRUE; } - //_____________________________________________________________________________ Bool_t -AliMUONTriggerIO::WriteRegional(const char* regionalFile, AliMUONVStore* regionalMasks) const +AliMUONTriggerIO::WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const { /// write regional mask with the current configuration @@ -618,35 +589,37 @@ AliMUONTriggerIO::WriteRegional(const char* regionalFile, AliMUONVStore* regiona return kFALSE; } - for (Int_t iCrate = 0; iCrate < fRegionalTrigger.GetNofTriggerCrates(); ++iCrate) + Int_t nCrate = fRegionalTrigger.GetNofTriggerCrates(); + if (!nCrate) { - AliMpTriggerCrate* crate = fRegionalTrigger.GetTriggerCrateFast(iCrate); + AliError("Could not write regional no configuration in memory"); + return kFALSE; + } - out << crate->GetName() << endl; - out << Form("%02x", crate->GetId()) << endl; - out << crate->GetMode() << endl; - out << crate->GetCoinc() << endl; - UShort_t masks = 0; - if (regionalMasks != 0x0) + for (Int_t iCrate = 0; iCrate < nCrate; ++iCrate) { - AliMUONVCalibParam* maskParam = - static_cast(regionalMasks->FindObject(crate->GetId())); - masks = maskParam->ValueAsInt(0,0); - } - else - { - masks = crate->GetMask(); - } - - out << Form("%04x", masks) << endl; + AliMpTriggerCrate* crate = fRegionalTrigger.GetTriggerCrateFast(iCrate); + AliMUONTriggerCrateConfig* crateConfig = regionalConfig->FindTriggerCrate(crate->GetName()); + if (!crateConfig) + { + AliError(Form("Cannot find crate %s in CDB", crate->GetName())); + return kFALSE; + } + + out << crate->GetName() << endl; + out << Form("%02x", crate->GetId()) << endl; + out << crateConfig->GetMode() << endl; + out << crateConfig->GetCoinc() << endl; + out << Form("%04x", crateConfig->GetMask()) << endl; + for (Int_t iLocal = 0; iLocal < crate->GetNofLocalBoards(); ++iLocal) { Int_t localBoardId = crate->GetLocalBoardId(iLocal); - + AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId); - + out << Form("%02d ", board->GetSlot()) << board->GetName() << Form(" %03d ", localBoardId) @@ -658,7 +631,7 @@ AliMUONTriggerIO::WriteRegional(const char* regionalFile, AliMUONVStore* regiona out << Form("%4d ", board->GetDEId(i)); out << endl; - // print copy card numbers + // print copy card numbers & TC out << Form(" %4d %4d", board->GetInputXfrom(), board->GetInputXto()); out << Form(" %4d %4d", board->GetInputYfrom(), board->GetInputYto()); out << Form(" %4d", board->GetTC()) << endl; @@ -669,9 +642,10 @@ AliMUONTriggerIO::WriteRegional(const char* regionalFile, AliMUONVStore* regiona return kTRUE; } + //_____________________________________________________________________________ Bool_t -AliMUONTriggerIO::WriteLocalMasks(const char* localFile, AliMUONVStore& localMasks) const +AliMUONTriggerIO::WriteLocalMasks(const char* localFile, AliMUONVStore& localMasks, AliMUONRegionalTriggerConfig* regionalConfig) const { /// write local mask /// removing/adding enable for a local board need a update of the configuration @@ -687,9 +661,9 @@ AliMUONTriggerIO::WriteLocalMasks(const char* localFile, AliMUONVStore& localMas UShort_t maskBuffer[8]; - for (Int_t iCrate = 0; iCrate < fRegionalTrigger.GetNofTriggerCrates(); ++iCrate) + for (Int_t iCrate = 0; iCrate < regionalConfig->GetNofTriggerCrates(); ++iCrate) { - AliMpTriggerCrate* crate = fRegionalTrigger.GetTriggerCrateFast(iCrate); + AliMUONTriggerCrateConfig* crate = regionalConfig->GetTriggerCrateFast(iCrate); UShort_t mask = crate->GetMask(); // getting mask from current config @@ -732,10 +706,10 @@ AliMUONTriggerIO::WriteLocalLUT(const AliMUONTriggerLut& lut, const Int_t kMaskXdev = 0x1F; const Int_t kMaskXpos = 0x1F; - UChar_t buffer[16384]; // 32768 hpt/lpt addresses divided by two + UChar_t buffer[fgkLocalLutSize]; // 32768 hpt/lpt addresses divided by two Int_t bc = 0; - for (Int_t i = 0; i < 32768; ++i) + for (UInt_t i = 0; i < fgkLocalLutSize*2; ++i) { Int_t lutLpt[2] = { 0 }; Int_t lutHpt[2] = { 0 }; @@ -821,74 +795,3 @@ AliMUONTriggerIO::LocalBoardId(Int_t index) const return board->GetId(); } -//_____________________________________________________________________________ -void -AliMUONTriggerIO::UpdateMapping(Bool_t writeFile) const -{ -/// check if mapping in database different from current Mtg configuration -/// Update mapping in databse and read regional crate file in repository (ext .out -/// to avoid overwriting). This case has a low probability to happen. - - // Assuming that crates do not change - - if (!AliMpDDLStore::Instance(kFALSE)) - { - AliMpCDB::LoadDDLStore(); - } - - Bool_t modified = false; - - TExMapIter itr = AliMpDDLStore::Instance()->GetLocalBoardItr(); - - Long_t key, value; - - while(itr.Next(key, value)) - { - AliMpLocalBoard* boardMapping = reinterpret_cast(value); - - Int_t localBoardId = boardMapping->GetId(); - AliMpLocalBoard* board = fRegionalTrigger.FindLocalBoard(localBoardId); - if ( ! board ) { - AliFatal("Board found in mapping but not in regional trigger"); - return; - } - - if ( board->GetCrate().CompareTo(boardMapping->GetCrate()) != 0 ) - { - AliWarning(Form("Crate Name different for board %d (%s %s)", localBoardId, boardMapping->GetCrate().Data(), - board->GetCrate().Data())); - boardMapping->SetCrate( board->GetCrate() ); - modified = true; - } - - if ((board->GetSlot()) != boardMapping->GetSlot()) - { - AliWarning(Form("Slot different for board %d (%d %d)", localBoardId, boardMapping->GetSlot(), board->GetSlot()+1)); - boardMapping->SetSlot(board->GetSlot()); - modified = true; - } - - if (boardMapping->GetSwitch() != board->GetSwitch()) { - AliWarning(Form("Switch different for board %d (0x%x 0x%x)", localBoardId, - boardMapping->GetSwitch(), board->GetSwitch())); - boardMapping->SetSwitch(board->GetSwitch()); - modified = true; - } - } - - if (modified) - { - AliMpDDLStore::Instance()->SetRegionalTrigger(fRegionalTrigger); - AliMpCDB::WriteDDLStore(false); - AliWarning("Wrote new version of mapping in databse"); - if (writeFile) - { - TString file = AliMpFiles::LocalTriggerBoardMapping(); - file += ".out"; - WriteRegional(file.Data(), 0x0); - AliWarning(Form("Wrote regional file %s", file.Data())); - - } - } - -} diff --git a/MUON/AliMUONTriggerIO.h b/MUON/AliMUONTriggerIO.h index fd755b7a33b..d05c16c8efd 100644 --- a/MUON/AliMUONTriggerIO.h +++ b/MUON/AliMUONTriggerIO.h @@ -20,17 +20,21 @@ #include "AliMpGlobalCrate.h" #include "AliMpRegionalTrigger.h" + + #ifndef ROOT_TArrayI # include #endif class AliMUONTriggerLut; -class AliMUONVCalibParam; class AliMUONVStore; class AliMpExMap; class AliMpDDL; class AliMpTriggerCrate; class AliMpLocalBoard; +class AliMUONGlobalCrateConfig; +class AliMUONRegionalTriggerConfig; + class AliMUONTriggerIO : public TObject { @@ -39,29 +43,46 @@ public: AliMUONTriggerIO(const char* regionalFileToRead); virtual ~AliMUONTriggerIO(); - Bool_t ReadMasks(const char* localFile, + + Bool_t ReadConfig(const char* localFile, const char* regionalFile, const char* globalFile, AliMUONVStore* localMasks, - AliMUONVStore* regionalMasks, - AliMUONVCalibParam* globalMasks, - Bool_t warn = true); - + AliMUONRegionalTriggerConfig* regionalConfig, + AliMUONGlobalCrateConfig* globalConfig); + Bool_t ReadLUT(const char* lutFileToRead, AliMUONTriggerLut& lut); Bool_t WriteLUT(const AliMUONTriggerLut& lut, const char* lutFileToWrite); - Bool_t WriteMasks(const char* localFile, + Bool_t WriteConfig(const char* localFile, const char* regionalFile, const char* globalFile, AliMUONVStore* localMasks, - AliMUONVStore* regionalMasks, - AliMUONVCalibParam* globalMasks) const; + AliMUONRegionalTriggerConfig* regionalConfig, + AliMUONGlobalCrateConfig* globalConfig) const; + + + Int_t ReadGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig); + + Bool_t WriteGlobalConfig(const char* globalFile, AliMUONGlobalCrateConfig* globalConfig) const; + + Int_t ReadRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig); + + Bool_t WriteRegionalConfig(const char* regionalFile, AliMUONRegionalTriggerConfig* regionalConfig) const; + + Int_t ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const; + + Bool_t WriteLocalMasks(const char* localFile, AliMUONVStore& localMasks, AliMUONRegionalTriggerConfig* regionalConfig) const; + + void ReadLocalLUT(AliMUONTriggerLut& lut, Int_t localBoardId, FILE* flut); + void WriteLocalLUT(const AliMUONTriggerLut& lut, Int_t localBoardId, + FILE* flut); + Int_t LocalBoardId(Int_t index) const; - void UpdateMapping(Bool_t writeFile = true) const; private: @@ -76,29 +97,16 @@ private: /// Return number of local boards Int_t NofLocalBoards() const { return fRegionalTrigger.GetNofLocalBoards(); } - Int_t ReadGlobal(const char* globalFile, AliMUONVCalibParam* globalMasks); - - Bool_t WriteGlobal(const char* globalFile, AliMUONVCalibParam* globalMasks) const; - - Int_t ReadRegional(const char* regionalFile, AliMUONVStore* regionalMasks, Bool_t warn = true); - - Bool_t WriteRegional(const char* regionalFile, AliMUONVStore* regionalMasks) const; - - Int_t ReadLocalMasks(const char* localFile, AliMUONVStore& localMasks) const; - Bool_t WriteLocalMasks(const char* localFile, AliMUONVStore& localMasks) const; - - void ReadLocalLUT(AliMUONTriggerLut& lut, Int_t localBoardId, FILE* flut); - - void WriteLocalLUT(const AliMUONTriggerLut& lut, Int_t localBoardId, - FILE* flut); - private: AliMpRegionalTrigger fRegionalTrigger; //!< Regional trigger AliMpGlobalCrate fGlobalCrate; //!< Global crate object - ClassDef(AliMUONTriggerIO,0) // Read/Write trigger masks and LUT to/from online files + static const UInt_t fgkLocalLutSize; ///< length of the lut for one local board + + + ClassDef(AliMUONTriggerIO,2) // Read/Write trigger masks and LUT to/from online files }; #endif diff --git a/MUON/AliMUONTriggerSubprocessor.cxx b/MUON/AliMUONTriggerSubprocessor.cxx index d52799fcd05..4207e82c1dc 100644 --- a/MUON/AliMUONTriggerSubprocessor.cxx +++ b/MUON/AliMUONTriggerSubprocessor.cxx @@ -20,6 +20,8 @@ #include "AliCDBMetaData.h" #include "AliLog.h" #include "AliMUON1DArray.h" +#include "AliMUONGlobalCrateConfig.h" +#include "AliMUONRegionalTriggerConfig.h" #include "AliMUONCalibParamNI.h" #include "AliMUONPreprocessor.h" #include "AliMUONTriggerIO.h" @@ -47,9 +49,9 @@ AliMUONTriggerSubprocessor::AliMUONTriggerSubprocessor(AliMUONPreprocessor* mast : AliMUONVSubprocessor(master, "Triggers", "Upload MUON Trigger masks and LUT to OCDB"), -fRegionalMasks(0x0), +fRegionalConfig(0x0), fLocalMasks(0x0), -fGlobalMasks(0x0), +fGlobalConfig(0x0), fLUT(0x0) { /// default ctor @@ -59,9 +61,9 @@ fLUT(0x0) AliMUONTriggerSubprocessor::~AliMUONTriggerSubprocessor() { /// dtor - delete fRegionalMasks; + delete fRegionalConfig; delete fLocalMasks; - delete fGlobalMasks; + delete fGlobalConfig; delete fLUT; } @@ -126,9 +128,9 @@ AliMUONTriggerSubprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTi WhichFilesToRead(GetFileName("EXPORTED").Data(), globalFile,regionalFile,localFile,lutFile); - delete fRegionalMasks; fRegionalMasks = 0x0; + delete fRegionalConfig; fRegionalConfig = 0x0; delete fLocalMasks; fLocalMasks = 0x0; - delete fGlobalMasks; fGlobalMasks = 0x0; + delete fGlobalConfig; fGlobalConfig = 0x0; delete fLUT; fLUT = 0x0; Master()->Log(Form("Reading trigger masks for Run %d startTime %ld endTime %ld", @@ -147,26 +149,26 @@ AliMUONTriggerSubprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTi return; } - if ( regionalFile ) fRegionalMasks = new AliMUON1DArray(16); + if ( regionalFile ) fRegionalConfig = new AliMUONRegionalTriggerConfig(); if ( localFile ) fLocalMasks = new AliMUON1DArray(AliMpConstants::TotalNofLocalBoards()+1); - if ( globalFile ) fGlobalMasks = new AliMUONCalibParamNI(1,16,1,0,0); + if ( globalFile ) fGlobalConfig = new AliMUONGlobalCrateConfig(); AliMUONTriggerIO tio; - Bool_t ok = tio.ReadMasks(GetFileName("LOCAL").Data(), + Bool_t ok = tio.ReadConfig(GetFileName("LOCAL").Data(), GetFileName("REGIONAL").Data(), GetFileName("GLOBAL").Data(), - fLocalMasks,fRegionalMasks,fGlobalMasks); + fLocalMasks,fRegionalConfig,fGlobalConfig); if (!ok) { Master()->Log("ERROR : ReadMasks failed"); delete fLocalMasks; - delete fRegionalMasks; - delete fGlobalMasks; + delete fRegionalConfig; + delete fGlobalConfig; fLocalMasks = 0x0; - fRegionalMasks = 0x0; - fGlobalMasks = 0x0; + fRegionalConfig = 0x0; + fGlobalConfig = 0x0; } if ( lutFile ) @@ -193,15 +195,15 @@ AliMUONTriggerSubprocessor::Process(TMap* /*dcsAliasMap*/) { /// Store the trigger masks into the CDB - if ( !fGlobalMasks && !fRegionalMasks && !fLocalMasks && !fLUT ) + if ( !fGlobalConfig && !fRegionalConfig && !fLocalMasks && !fLUT ) { // nothing to do return 0; } Master()->Log(Form("N global = %d N regional = %d N local %d N lut %d", - (fGlobalMasks ? 1 : 0 ), - (fRegionalMasks ? fRegionalMasks->GetSize() : 0 ), + (fGlobalConfig ? 1 : 0 ), + (fRegionalConfig ? fRegionalConfig->GetNofTriggerCrates() : 0 ), (fLocalMasks ? fLocalMasks->GetSize() : 0 ), (fLUT ? 1 : 0))); @@ -217,15 +219,15 @@ AliMUONTriggerSubprocessor::Process(TMap* /*dcsAliasMap*/) Bool_t result3(kTRUE); Bool_t result4(kTRUE); - if ( fGlobalMasks ) + if ( fGlobalConfig ) { - result1 = Master()->Store("Calib", "GlobalTriggerBoardMasks", fGlobalMasks, + result1 = Master()->Store("Calib", "GlobalTriggerBoardMasks", fGlobalConfig, &metaData, 0, validToInfinity); } - if ( fRegionalMasks && fRegionalMasks->GetSize() > 0 ) + if ( fRegionalConfig && fRegionalConfig->GetNofTriggerCrates() > 0 ) { - result2 = Master()->Store("Calib", "RegionalTriggerBoardMasks", fRegionalMasks, + result2 = Master()->Store("Calib", "RegionalTriggerBoardMasks", fRegionalConfig, &metaData, 0, validToInfinity); } diff --git a/MUON/AliMUONTriggerSubprocessor.h b/MUON/AliMUONTriggerSubprocessor.h index 1069c9f9c0a..5a12de2c29d 100644 --- a/MUON/AliMUONTriggerSubprocessor.h +++ b/MUON/AliMUONTriggerSubprocessor.h @@ -17,8 +17,10 @@ #endif class AliMUONTriggerLut; -class AliMUONVStore; +class AliMUONRegionalTriggerConfig; +class AliMUONGlobalCrateConfig; class AliMUONVCalibParam; +class AliMUONVStore; class TString; class AliMUONTriggerSubprocessor : public AliMUONVSubprocessor @@ -48,12 +50,12 @@ private: Bool_t& lutFile) const; private: - AliMUONVStore* fRegionalMasks; //!< regional masks + AliMUONRegionalTriggerConfig* fRegionalConfig; //!< regional config AliMUONVStore* fLocalMasks; //!< local masks - AliMUONVCalibParam* fGlobalMasks; //!< global masks + AliMUONGlobalCrateConfig* fGlobalConfig; //!< global config AliMUONTriggerLut* fLUT; //!< look-up table(s) - ClassDef(AliMUONTriggerSubprocessor,1) // A shuttle preprocessor for MUON TRK masks + ClassDef(AliMUONTriggerSubprocessor,2) // A shuttle preprocessor for MUON TRK masks }; #endif diff --git a/MUON/Calib/DDLStore/Run0_999999999_v0_s0.root b/MUON/Calib/DDLStore/Run0_999999999_v0_s0.root index e46e62571280d0b5714a5d2259ec7214c872b27c..7e070917af4048839bba8a3520cfbec0404850d5 100644 GIT binary patch literal 58421 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 diff --git a/MUON/Calib/GlobalTriggerCrateConfig/Run0_999999999_v0_s0.root b/MUON/Calib/GlobalTriggerCrateConfig/Run0_999999999_v0_s0.root new file mode 100644 index 0000000000000000000000000000000000000000..01b67ab8f06b749136e5d8e30bbbcfb16a0e7fcd GIT binary patch literal 3448 zcmcInc{G%58-IqVkTNJ+Y3!1He-$xVCX9Vcc4M6}V~m}U7Y&jvvX@@6OoXfAc_p1`L{w%4FKnrDX%c&oxz-JqM;zlX-MM+<@A49ATV&^C{@;WUI_?1^-PHd z05rxLu1JK1xClkM_NX@>Ur=^2^9 zwbh`>>I&%#K$(_7vcWBp3=xNX+_z79;={C=Dl*950a!=+q1g0O1RhhPr_tLP#U+*BXfta4>CQ`<6< zRQ`E1tcFNbMU6Kc)!9UNq_S6}+KpMUMLl~O-HBs+5FGTz410!yaW(R^8Fx;aaWe0KBaN|+s~3*J2!}=3p%7S@hZ7on7wv72 z^uLaD^>9ZxQZ_Ffr8B?I0g+cJo%v|4jT~!dKl(T%T|VbbEm)QT8yJSatrUGFI?(1_ zFkVT`p2$xy#c~N6)M#VXGqg)!CD&YMJRS*XMawPme}3t5QIw9@=Ri#~pZl&Ib}c}- z&#ROs;6@)YBd20Of8d4_hZ1!+!{@8p2S*F!3W2Pkm`In8j8BGDngA5e%{4NGng52V!fz;PxhjHV#xFeH}fXF`uo$H_z6cy;%Y0mVt_U$LVOR z%HhiH%kAwvL;BT(7l10Z7h7A_G!F6Q@-D9OJl{pO=1CCEz)Sd$wfyWo=ihB-y-8Kc zs>kVvYb?rq88VK zjE;G(Z+H*3kp#lY@v2U^cwax2@4R;h)~S5Sh@PMjKQb$+31dYL5!n$9BpY0zG=s;tQRjy%=S#u6bu z9f&R66&xM!I-z2IZvjrag=d)}=Dv@TE)|)gk29#;w zkuH=>(jj)fv1QNw&g_mQCic`TfmYXql2h4#a=dc9_ulixgPoxFcIv;|>gqb^|5V`E zvq*({O`#ZjnCsxajvD))CyPUP5~me07toMfXXkw*U&l@!aAj8wJhP5*!pY8C|ISrV zjZ|6eq;HO78sTp;0XM#{AJCohAOm;{D>1c*kbu?KeseUL9zlJG>k1>Xi6d&~RT88%jhW-^L#F%HM^J;R99U=aq zgC%O#@-wSCA_^QxA?)*HOT1(uAKqAbLuUJbBCZoW_K;T5}`kTAq*2?h_y)tU*@XQA9vH&^DU{~UD$F0ZT!<0YP!)ang zQ`U3Evi6}9=;pcL@P!zSIfNy=^1 zk`=8BB$U#4Y;vpfJ%SgL>6b z+aTUaskhnaFB`*NLnR80mHrQ?lv18_Uh=iq9?5)>vtl~yu`DytCK#4Bflpzb{N7G% zXi6~coi)v|WYEhuO@WBWUy-Y*hZU>2j-BZj@W)>}0xRJ9FTT{?P4UWi4Y@aNux!oS z%ICHbx76y|Y*3aPxxJ7do*d{2iGPgY1UNhkq0dq^>cb~U;TQQxL1@Fo~ z4#_JBZu|PM_p5b(;nF_oUap^!WPJ|Q_q6A*n1rcd88pe?kjy**I)5 zU;aRd2{Cr)qo4aU-Q1A7t_^bzj4*&Xdzw3VmfHK51|7YF+Z&oxy9uTsQj3tjYn0d# z7|S%fXFdAP(yIy!`T8cW@m}()MC{#9sb>-c&AR9_huQluZE6A8mb87$yL^|Zc7nqwe;P3b?*%_!*<|2fv;6>a literal 0 HcmV?d00001 diff --git a/MUON/Calib/Mapping/Run0_999999999_v0_s0.root b/MUON/Calib/Mapping/Run0_999999999_v0_s0.root index e273c5e68908d1c040462e969785343404ca0062..08c9b7d8979e54272d34535247b3398eff2e86f7 100644 GIT binary patch delta 480 zcmW;JxlRI66vpv;Swu$x6_s%X6mh|2P;p;CR1g98WuAb_WI}63Y^kU7 zMYOlHHX7r9D1NzLPHuC~SO5NW)bXtOMIic`Q4{x43UT-LRZYjdLi`Dr5aKCW4ri+s z%fmy=nVJl`8~@FMj5wJ*81m7OHV2$=!Hp(((2N!+Xhj>m@WGFEbf6OfbfFtP2tq|K z`p}O73}Of&gb~3oMi9j)Vi?0XCNPOOrZ9~e%tAu~bC|~hl32tNma&3WtYIA+*u)l6 zNMjor>|hsr$RdY*xg_PH~2FT;LK{mLYZJ-9EN;`=P5LJJnu(^oku! Tmi5upO`|V`lJd3GuYUaxDl&>r delta 480 zcmW;JIZpyn6o%n@Swu$xcg7WQ!CeOxcLh{%!+o7UU}rL+HAWL-tW2Ct0ll#@)YDn| zC$zV;HWK4I6i@D#liQs06@R{5MLcOi^SyBYs>W`m6yoOX+e}6MLi`Dj5aKa@QF=CW zwvUJSVrequE&sQ&GU8@(XUGRbI$UtW11~DzLnW%9pc*ysBY+@kQHOdopb<@IMhGfe z(26#+qXV4?qYDvqqX)g{LlpfOz#xV&j1i1t4CBxc!vrQVg*c`$gIUaB9t&8+5|)ub z5-F@;6>CT%gLQ0R6I<9u7CYF*9`)K$4J#VIMDEa{j3!vL5J diff --git a/MUON/Calib/RegionalTriggerConfig/Run0_999999999_v0_s0.root b/MUON/Calib/RegionalTriggerConfig/Run0_999999999_v0_s0.root new file mode 100644 index 0000000000000000000000000000000000000000..10b10c5098daeb00665510f94bd929affd8da4ea GIT binary patch literal 3123 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 1.2 of daqDAlib // env variables have to be set (suppose by ECS ?) // setenv DATE_FES_PATH // setenv DATE_RUN_NUMBER // setenv DATE_ROLE_NAME // setenv DATE_DETECTOR_CODE + // Export files into the database + // setenv DATE_DETECTOR_CODE MTR + // setenv DAQDALIB_PATH $ALICE/daqDAlib + // setenv DATE_DB_MYSQL_USER det_MTR + // setenv DATE_DB_MYSQL_PWD MTR123 + // setenv DATE_DB_MYSQL_HOST aldaqdb.cern.ch + // setenv DATE_DB_MYSQL_DB $DATE_CONFIG + // set PATH=$PATH:${DAQDALIB_PATH} + + // to be sure that env variable is set - gSystem->Setenv("DAQDALIB_PATH", "$DATE_SITE/infoLogger"); - + // gSystem->Setenv("DAQDALIB_PATH", "$DATE_SITE/infoLogger"); + gSystem->Setenv("DAQDALIB_PATH", "$ALICE/daqDAlib"); + gSystem->Setenv("DATE_DETECTOR_CODE", "MTR"); + gSystem->Setenv("DATE_DB_MYSQL_USER", "det_MTR"); + gSystem->Setenv("DATE_DB_MYSQL_PWD", "MTR123"); + gSystem->Setenv("DATE_DB_MYSQL_HOST", "aldaqdb.cern.ch"); + gSystem->Setenv("DATE_DB_MYSQL_DB", "$DATE_CONFIG"); + // update files Int_t status = 0; @@ -298,10 +317,10 @@ Bool_t ExportFiles() if (!out.good()) { printf("Failed to create file: %s\n",file.Data()); return false; - } + } file = gGlobalFileName.Data(); if (gGlobalFileLastVersion != gGlobalFileVersion) { - file = gGlobalFileName.Data(); + status = daqDA_FES_storeFile(file.Data(), file.Data()); if (status) { printf("Failed to export file: %s\n",gGlobalFileName.Data()); @@ -314,11 +333,19 @@ Bool_t ExportFiles() if (gLocalMaskFileLastVersion != gLocalMaskFileVersion) { modified = true; file = gLocalMaskFileName; + // export to FES status = daqDA_FES_storeFile(file.Data(), file.Data()); if (status) { printf("Failed to export file: %s\n",gLocalMaskFileName.Data()); return false; } + // export to DB + status = daqDA_DB_storeFile(file.Data(), file.Data()); + if (status) { + printf("Failed to export file to DB: %s\n",gLocalMaskFileName.Data()); + return false; + } + if(gPrintLevel) printf("Export file: %s\n",gLocalMaskFileName.Data()); out << gLocalMaskFileName.Data() << endl; } @@ -370,8 +397,9 @@ Bool_t ImportFiles() // instead of the database. The usual environment variables are not needed. // to be sure that env variable is set - gSystem->Setenv("DAQDALIB_PATH", "$DATE_SITE/db"); - + // gSystem->Setenv("DAQDALIB_PATH", "$DATE_SITE/db"); + gSystem->Setenv("DAQDALIB_PATH", "$ALICE/daqDAlib"); + Int_t status = 0; status = daqDA_DB_getFile(gCurrentFileName.Data(), gCurrentFileName.Data()); @@ -414,15 +442,15 @@ void ReadMaskFiles() { // read mask files gLocalMasks = new AliMUON1DArray(gkNLocalBoard+9); - gRegionalMasks = new AliMUON1DArray(16); - gGlobalMasks = new AliMUONCalibParamNI(1,2,1,0,0); + gRegionalMasks = new AliMUONRegionalTriggerConfig(); + gGlobalMasks = new AliMUONGlobalCrateConfig(); TString localFile = gLocalMaskFileName; TString regionalFile = gRegionalFileName; TString globalFile = gGlobalFileName; - gTriggerIO.ReadMasks(localFile.Data(), regionalFile.Data(), globalFile.Data(), - gLocalMasks, gRegionalMasks, gGlobalMasks, false); + gTriggerIO.ReadConfig(localFile.Data(), regionalFile.Data(), globalFile.Data(), + gLocalMasks, gRegionalMasks, gGlobalMasks); } //__________ void MakePattern(Int_t localBoardId, TArrayS& xPattern, TArrayS& yPattern) @@ -578,7 +606,7 @@ void MakePatternStore(Bool_t pedestal = true) // write last current file WriteLastCurrentFile(); - gTriggerIO.WriteMasks(gLocalMaskFileName, gRegionalFileName, gGlobalFileName, gLocalMasks, gRegionalMasks, gGlobalMasks); + gTriggerIO.WriteConfig(gLocalMaskFileName, gRegionalFileName, gGlobalFileName, gLocalMasks, gRegionalMasks, gGlobalMasks); } } @@ -595,6 +623,7 @@ int main(Int_t argc, Char_t **argv) Int_t skipEvents = 0; Int_t maxEvents = 1000000; Char_t inputFile[256]; + strcpy(inputFile, ""); TString flatOutputFile; // option handler @@ -805,18 +834,17 @@ int main(Int_t argc, Char_t **argv) MakePatternStore(); if (gCommand.Contains("cal")) - printf("Options %s disabled", gCommand.Data()); - // MakePatternStore(false); + MakePatternStore(false); if (!ExportFiles()) return -1; timers.Stop(); - cout << "MUONTRKda : Run number : " << gRunNumber << endl; - cout << "MUONTRKda : Histo file generated : " << gHistoFileName << endl; - cout << "MUONTRKda : Nb of DATE events = " << nDateEvents << endl; - cout << "MUONTRKda : Nb of events used = " << gNEvents << endl; + cout << "MUONTRGda : Run number : " << gRunNumber << endl; + cout << "MUONTRGda : Histo file generated : " << gHistoFileName << endl; + cout << "MUONTRGda : Nb of DATE events = " << nDateEvents << endl; + cout << "MUONTRGda : Nb of events used = " << gNEvents << endl; printf("Execution time : R:%7.2fs C:%7.2fs\n", timers.RealTime(), timers.CpuTime()); @@ -827,3 +855,4 @@ int main(Int_t argc, Char_t **argv) return status; } + diff --git a/MUON/MUONcalibLinkDef.h b/MUON/MUONcalibLinkDef.h index ba8f67619c7..33dcb9b85f5 100644 --- a/MUON/MUONcalibLinkDef.h +++ b/MUON/MUONcalibLinkDef.h @@ -18,6 +18,10 @@ #pragma link C++ class AliMUONCalibParamNI+; #pragma link C++ class AliMUONTriggerEfficiencyCells+; #pragma link C++ class AliMUONTriggerLut+; +#pragma link C++ class AliMUONRegionalTriggerConfig+; +#pragma link C++ class AliMUONTriggerCrateConfig+; +#pragma link C++ class AliMUONGlobalCrateConfig+; + #pragma link C++ class AliMUON2DStoreValidator+; #pragma link C++ class AliMUONTriggerIO+; #pragma link C++ class AliMUONTrackerIO+; diff --git a/MUON/libMUONcalib.pkg b/MUON/libMUONcalib.pkg index fc249d8a5d0..7e28cf1a9e7 100644 --- a/MUON/libMUONcalib.pkg +++ b/MUON/libMUONcalib.pkg @@ -10,6 +10,9 @@ SRCS:= AliMUONTriggerLut.cxx \ AliMUON2DStoreValidator.cxx \ AliMUONTriggerIO.cxx \ AliMUONTrackerIO.cxx \ + AliMUONRegionalTriggerConfig.cxx \ + AliMUONTriggerCrateConfig.cxx \ + AliMUONGlobalCrateConfig.cxx \ AliMUONVTrackerData.cxx \ AliMUONSparseHisto.cxx \ AliMUONTrackerData.cxx diff --git a/MUON/mapping/AliMpDDLStore.cxx b/MUON/mapping/AliMpDDLStore.cxx index c9835e91b81..4b84bed0c37 100644 --- a/MUON/mapping/AliMpDDLStore.cxx +++ b/MUON/mapping/AliMpDDLStore.cxx @@ -108,7 +108,6 @@ AliMpDDLStore::AliMpDDLStore() fBusPatches(true), fManuList12(), fManuBridge2(), - fGlobalCrate(), fRegionalTrigger() { /// Standard constructor @@ -137,7 +136,6 @@ AliMpDDLStore::AliMpDDLStore(TRootIOCtor* ioCtor) : TObject(), fDDLs(), fBusPatches(), - fGlobalCrate(ioCtor), fRegionalTrigger(ioCtor) { /// Constructor for I0 @@ -296,8 +294,6 @@ Bool_t AliMpDDLStore::ReadTrigger() { /// create trigger DDL object and Global crate object - if ( ! fGlobalCrate.ReadData() ) return false; - if ( ! fRegionalTrigger.ReadData() ) return false; return true; @@ -890,7 +886,7 @@ void AliMpDDLStore::SetRegionalTrigger(const AliMpRegionalTrigger& regionalTrigg fRegionalTrigger = regionalTrigger; - // Remove the existing trigger DDLs + // Remove the existing trigger DDLsf fDDLs.RemoveAt(fgkNofDDLs+1); fDDLs.RemoveAt(fgkNofDDLs); diff --git a/MUON/mapping/AliMpDDLStore.h b/MUON/mapping/AliMpDDLStore.h index 42468dd7c7b..92156ba7a2d 100644 --- a/MUON/mapping/AliMpDDLStore.h +++ b/MUON/mapping/AliMpDDLStore.h @@ -19,7 +19,6 @@ #include "AliMpExMap.h" #include "AliMpIntPair.h" -#include "AliMpGlobalCrate.h" #include "AliMpRegionalTrigger.h" #include #include @@ -54,8 +53,6 @@ class AliMpDDLStore : public TObject { /// Return regional trigger object const AliMpRegionalTrigger* GetRegionalTrigger() const { return &fRegionalTrigger; } - /// Return global crate object - const AliMpGlobalCrate* GetGlobalCrate() const { return &fGlobalCrate; } Int_t GetDEfromBus(Int_t busPatchId) const; Int_t GetDEfromLocalBoard(Int_t localBoardId, Int_t chamberId) const; @@ -115,10 +112,9 @@ class AliMpDDLStore : public TObject { AliMpExMap fBusPatches; ///< The map of bus patches per their IDs TArrayI fManuList12[16]; ///< Arrays of 1st manu in bus TArrayI fManuBridge2[16]; ///< Arrays of manu number before the bridge in buspatch - AliMpGlobalCrate fGlobalCrate; ///< Global Crate Object AliMpRegionalTrigger fRegionalTrigger; ///< Regional trigger - ClassDef(AliMpDDLStore,4) // The manager class for definition of detection element types + ClassDef(AliMpDDLStore,5) // The manager class for definition of detection element types }; #endif //ALI_MP_DDL_STORE_H diff --git a/MUON/mapping/AliMpRegionalTrigger.cxx b/MUON/mapping/AliMpRegionalTrigger.cxx index 0dcab2a687a..9a6804b6fc4 100644 --- a/MUON/mapping/AliMpRegionalTrigger.cxx +++ b/MUON/mapping/AliMpRegionalTrigger.cxx @@ -131,7 +131,6 @@ Bool_t AliMpRegionalTrigger::ReadData(const TString& fileName) Int_t localBoardId = 0; TArrayI list; UShort_t crateId, mask; - Int_t mode, coincidence; char line[80]; @@ -144,12 +143,13 @@ Bool_t AliMpRegionalTrigger::ReadData(const TString& fileName) in.getline(line,80); sscanf(line,"%hx",&crateId); + // skip mode in.getline(line,80); - sscanf(line,"%d",&mode); + // skip coincidence in.getline(line,80); - sscanf(line,"%d",&coincidence); + // skip mask in.getline(line,80); sscanf(line,"%hx",&mask); @@ -157,7 +157,7 @@ Bool_t AliMpRegionalTrigger::ReadData(const TString& fileName) if (!crate) { // cout << "Creating crate: " << crateName.Data() << endl; - crate = new AliMpTriggerCrate(crateName.Data(), crateId, mask, mode, coincidence); + crate = new AliMpTriggerCrate(crateName.Data(), crateId); fTriggerCrates.Add(crateName.Data(), crate); } diff --git a/MUON/mapping/AliMpTriggerCrate.cxx b/MUON/mapping/AliMpTriggerCrate.cxx index 7d49096b7ec..ebc752735d6 100644 --- a/MUON/mapping/AliMpTriggerCrate.cxx +++ b/MUON/mapping/AliMpTriggerCrate.cxx @@ -67,24 +67,18 @@ AliMpTriggerCrate::AliMpTriggerCrate(const Char_t* name, Int_t ddlId) : TNamed(name, "mapping trigger crate"), fId(0), fDdlId(ddlId), - fLocalBoard(false), - fMask(0), - fMode(0), - fCoinc(0) + fLocalBoard(false) { /// Standard constructor } //______________________________________________________________________________ -AliMpTriggerCrate::AliMpTriggerCrate(const Char_t* name, UShort_t id, UShort_t mask, UShort_t mode, UShort_t coinc) +AliMpTriggerCrate::AliMpTriggerCrate(const Char_t* name, UShort_t id) : TNamed(name, "mapping trigger crate"), fId(id), fDdlId(0), - fLocalBoard(false), - fMask(mask), - fMode(mode), - fCoinc(coinc) + fLocalBoard(false) { /// Standard constructor for Shuttle + DA @@ -95,10 +89,7 @@ AliMpTriggerCrate::AliMpTriggerCrate(TRootIOCtor* /*ioCtor*/) : TNamed(), fId(), fDdlId(), - fLocalBoard(), - fMask(), - fMode(), - fCoinc() + fLocalBoard() { /// Root IO constructor } diff --git a/MUON/mapping/AliMpTriggerCrate.h b/MUON/mapping/AliMpTriggerCrate.h index 1b611ef65ec..9a2bda86c0c 100644 --- a/MUON/mapping/AliMpTriggerCrate.h +++ b/MUON/mapping/AliMpTriggerCrate.h @@ -21,7 +21,7 @@ class AliMpTriggerCrate : public TNamed { public: AliMpTriggerCrate(const Char_t* name, Int_t ddlId); - AliMpTriggerCrate(const Char_t* name, UShort_t Id, UShort_t mask, UShort_t mode, UShort_t coinc); + AliMpTriggerCrate(const Char_t* name, UShort_t Id); AliMpTriggerCrate(TRootIOCtor* /*ioCtor*/); virtual ~AliMpTriggerCrate(); @@ -33,9 +33,6 @@ class AliMpTriggerCrate : public TNamed { /// get methods Int_t GetDdlId() const; UShort_t GetId() const; - UShort_t GetMask() const; - UShort_t GetMode() const; - UShort_t GetCoinc() const; Int_t GetNofLocalBoards() const; Int_t GetLocalBoardId(Int_t index) const; Bool_t HasLocalBoard(Int_t localBoardId) const; @@ -55,11 +52,8 @@ class AliMpTriggerCrate : public TNamed { UShort_t fId; ///< crate number Int_t fDdlId; ///< DDL to which this bus patch is connected AliMpArrayI fLocalBoard; ///< local board connected to this crate - UShort_t fMask; ///< regional mask - UShort_t fMode; ///< mode operating for crate - UShort_t fCoinc; ///< coincidence mode for crate - ClassDef(AliMpTriggerCrate,2) // The class collectiong electronics properties of DDL + ClassDef(AliMpTriggerCrate,3) // The class collectiong electronics properties of DDL }; // inline functions @@ -73,17 +67,6 @@ inline Int_t AliMpTriggerCrate::GetDdlId() const inline UShort_t AliMpTriggerCrate::GetId() const { return fId; } -/// Return mask -inline UShort_t AliMpTriggerCrate::GetMask() const -{ return fMask; } - -/// Return Mode -inline UShort_t AliMpTriggerCrate::GetMode() const -{ return fMode; } - -/// Return coinc -inline UShort_t AliMpTriggerCrate::GetCoinc() const -{ return fCoinc; } #endif //ALI_MP_TRIGGER__CRATE_H diff --git a/MUON/mapping/data/stationTrigger/GlobalCrate.dat b/MUON/mapping/data/stationTrigger/GlobalCrate.dat index 47cfa5680e2..a37e88666e0 100644 --- a/MUON/mapping/data/stationTrigger/GlobalCrate.dat +++ b/MUON/mapping/data/stationTrigger/GlobalCrate.dat @@ -1,4 +1,5 @@ GlobalCrate +0x1f JtagBoard 0x03000000 3 0 1 @@ -26,15 +27,19 @@ JtagBoard LeftDarcBoard 0x01000000 0 -0xfe +0x00 0xc 0xf0 +0x20 +0x2 RightDarcBoard 0x02000000 1 0x00 0xc 0xf0 +0x20 +0x2 GlobalBoard 0x00400000 0x0 -- 2.43.0