X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONPadStatusMaker.cxx;h=67acc13782a69b28eba9779e0c1620c22128cd9a;hb=7d6298844d815257941b991f031d2075ca375dc2;hp=f68035991cee9cfbfc2a2002a87dcbbf675e0948;hpb=78649106ec7f71baeb897efa54274a4011675b87;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONPadStatusMaker.cxx b/MUON/AliMUONPadStatusMaker.cxx index f68035991ce..67acc13782a 100644 --- a/MUON/AliMUONPadStatusMaker.cxx +++ b/MUON/AliMUONPadStatusMaker.cxx @@ -15,51 +15,53 @@ // $Id$ +//----------------------------------------------------------------------------- /// \class AliMUONPadStatusMaker /// /// Make a 2DStore of pad statuses, using different sources of information, /// like pedestal values, gain values, and HV values. /// /// \author Laurent Aphecetche +//----------------------------------------------------------------------------- #include "AliMUONPadStatusMaker.h" #include "AliMUON2DMap.h" -#include "AliMUONCalibParam1I.h" +#include "AliMUON2DStoreValidator.h" +#include "AliMUONCalibParamNI.h" #include "AliMUONCalibrationData.h" -#include "AliMUONHVNamer.h" -#include "AliMUONObjectPair.h" +#include "AliMUONLogger.h" +#include "AliMUONRecoParam.h" +#include "AliMUONStringIntMap.h" +#include "AliMUONTrackerData.h" #include "AliMUONVCalibParam.h" -#include "AliMUONVDataIterator.h" #include "AliMpArea.h" -#include "AliMpDEIterator.h" +#include "AliMpArrayI.h" +#include "AliMpCDB.h" +#include "AliMpConstants.h" +#include "AliMpDDLStore.h" #include "AliMpDEManager.h" -#include "AliMpIntPair.h" -#include "AliMpManuList.h" -#include "AliMpMotifMap.h" -#include "AliMpMotifPosition.h" -#include "AliMpPCB.h" -#include "AliMpPad.h" -#include "AliMpSector.h" -#include "AliMpSectorSegmentation.h" -#include "AliMpSegmentation.h" -#include "AliMpSlat.h" -#include "AliMpSlatSegmentation.h" -#include "AliMpStationType.h" -#include "AliMpVPadIterator.h" -#include "AliMUON2DStoreValidator.h" -#include "AliCDBManager.h" +#include "AliMpDetElement.h" +#include "AliMpDCSNamer.h" +#include "AliMpManuIterator.h" +#include "AliMpManuUID.h" + #include "AliCDBEntry.h" +#include "AliCDBManager.h" +#include "AliCodeTimer.h" #include "AliDCSValue.h" #include "AliLog.h" -#include "Riostream.h" -#include "TMap.h" -#include "TStopwatch.h" -#include "TString.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /// \cond CLASSIMP ClassImp(AliMUONPadStatusMaker) @@ -67,103 +69,149 @@ ClassImp(AliMUONPadStatusMaker) //_____________________________________________________________________________ AliMUONPadStatusMaker::AliMUONPadStatusMaker(const AliMUONCalibrationData& calibData) -: fCalibrationData(calibData), - fPedMeanLimits(0,4095), - fPedSigmaLimits(0,4095), - fHVSt12Limits(0,5000), - fHVSt345Limits(0,5000) +: fkCalibrationData(calibData), +fGainA1Limits(0,1E30), +fGainA2Limits(-1E-30,1E30), +fGainThresLimits(0,4095), +fPedMeanLimits(0,4095), +fPedSigmaLimits(0,4095), +fManuOccupancyLimits(0,1.0), +fBuspatchOccupancyLimits(0,1.0), +fDEOccupancyLimits(0,1.0), +fStatus(new AliMUON2DMap(true)), +fHV(0x0), +fPedestals(calibData.Pedestals()), +fGains(calibData.Gains()), +fTrackerData(0x0) { - // ctor + /// ctor + if ( calibData.OccupancyMap() ) + { + /// create a tracker data from the occupancy map + fTrackerData = new AliMUONTrackerData("OCC","OCC",*(calibData.OccupancyMap())); + } + if ( calibData.HV() ) + { + /// Only create the fHV internal store if there are some HV values available + fHV = new TExMap; + } + + SetHVLimit(-1,0.0); } //_____________________________________________________________________________ AliMUONPadStatusMaker::~AliMUONPadStatusMaker() { - // dtor. + /// dtor. + + delete fStatus; + delete fHV; + delete fTrackerData; } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::Combine(const AliMUONV2DStore& store1, - const AliMUONV2DStore& store2, - Int_t binShift) const +TString +AliMUONPadStatusMaker::AsString(Int_t status) { - /// Combine two status containers into one, shifting store2 status bits - /// to the left by binShift before making an OR with store1. + /// return a human readable version of the integer status - TStopwatch timer; - timer.Start(kTRUE); + if ( status == 0 ) + { + return "Brave New World"; + } - AliMUONV2DStore* combined = static_cast(store1.Clone()); + Int_t pedStatus; + Int_t gainStatus; + Int_t hvStatus; + Int_t occStatus; + + DecodeStatus(status,pedStatus,hvStatus,gainStatus,occStatus); + + TString s; + + if ( pedStatus & kPedMeanZero ) s += "& Ped Mean is Zero "; + if ( pedStatus & kPedMeanTooLow ) s += "& Ped Mean Too Low "; + if ( pedStatus & kPedMeanTooHigh ) s += "& Ped Mean Too High "; + if ( pedStatus & kPedSigmaTooLow ) s += "& Ped Sigma Too Low "; + if ( pedStatus & kPedSigmaTooHigh ) s += "& Ped Sigma Too High "; + if ( pedStatus & kPedMissing ) s += "& Ped is missing "; + + if ( gainStatus & kGainA1TooLow ) s+="& Gain A1 is Too Low "; + if ( gainStatus & kGainA1TooHigh ) s+="& Gain A1 is Too High "; + if ( gainStatus & kGainA2TooLow ) s+="& Gain A2 is Too Low "; + if ( gainStatus & kGainA2TooHigh ) s+="& Gain A2 is Too High "; + if ( gainStatus & kGainThresTooLow ) s+="& Gain Thres is Too Low "; + if ( gainStatus & kGainThresTooHigh ) s+="& Gain Thres is Too High "; + if ( gainStatus & kGainMissing ) s+="& Gain is missing "; + + if ( hvStatus & kHVError ) s+="& HV is on error "; + if ( hvStatus & kHVTooLow ) s+="& HV is Too Low "; + if ( hvStatus & kHVTooHigh ) s+="& HV is Too High "; + if ( hvStatus & kHVChannelOFF ) s+="& HV has channel OFF "; + if ( hvStatus & kHVSwitchOFF ) s+="& HV has switch OFF "; + if ( hvStatus & kHVMissing ) s+="& HV is missing "; + + if ( occStatus & kManuOccupancyTooHigh ) s+="& manu occupancy too high "; + if ( occStatus & kManuOccupancyTooLow ) s+="& manu occupancy too low "; + if ( occStatus & kBusPatchOccupancyTooHigh ) s+="& bus patch occupancy too high "; + if ( occStatus & kBusPatchOccupancyTooLow ) s+="& bus patch occupancy too low "; + if ( occStatus & kDEOccupancyTooHigh ) s+="& DE occupancy too high "; + if ( occStatus & kDEOccupancyTooLow ) s+="& DE occupancy too low "; - AliMUONVDataIterator* it = store1.Iterator(); - AliMUONObjectPair* pair; + if ( s[0] == '&' ) s[0] = ' '; - while ( ( pair = static_cast(it->Next()) ) ) - { - AliMpIntPair* ip = static_cast(pair->First()); - Int_t detElemId = ip->GetFirst(); - Int_t manuId = ip->GetSecond(); - AliMUONVCalibParam* param1 = static_cast(store1.Get(detElemId,manuId)); - AliMUONVCalibParam* param2 = static_cast(store2.Get(detElemId,manuId)); - if (!param2) - { - AliWarning(Form("Could not get statuses for store2 for DE %d ManuId %d. Marking as missing.", - detElemId,manuId)); - param2 = static_cast(param1->Clone()); - for ( Int_t manuChannel = 0; manuChannel < param2->Size(); ++manuChannel ) - { - param2->SetValueAsInt(manuChannel,0,kMissing); - } - } - AliMUONVCalibParam* paramCombined = static_cast(combined->Get(detElemId,manuId)); - if (!paramCombined) - { - paramCombined = static_cast(param2->Clone()); - combined->Set(detElemId,manuId,paramCombined,kFALSE); - } - - for ( Int_t manuChannel = 0; manuChannel < param1->Size(); ++manuChannel ) - { - if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) ) - { - Int_t status1(param1->ValueAsInt(manuChannel)); - Int_t status2(param2->ValueAsInt(manuChannel)); - - Int_t status = status1 | (status2 << binShift); - - paramCombined->SetValueAsInt(manuChannel,0,status); - } - } - } + return s; +} + +//_____________________________________________________________________________ +TString +AliMUONPadStatusMaker::AsCondition(Int_t mask) +{ + /// return a human readable version of the mask's equivalent condition - delete it; + TString s(AsString(mask)); - AliInfo("Timer:"); - StdoutToAliInfo(timer.Print();); + s.ReplaceAll("&","|"); - return combined; + return s; } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::GeneratePadStatus(Int_t value) +Int_t +AliMUONPadStatusMaker::BuildStatus(Int_t pedStatus, + Int_t hvStatus, + Int_t gainStatus, + Int_t occStatus) { - /// Generate a "fake" store, with all (detElemId,manuId) present, - /// and containing all the same value + /// Build a complete status from specific parts (ped,hv,gain) - AliMUONCalibParam1I param(64,value); + return ( hvStatus & 0xFF ) | ( ( pedStatus & 0xFF ) << 8 ) | + ( ( gainStatus & 0xFF ) << 16 ) | + ( ( occStatus & 0xFF ) << 24 ) ; +} + +//_____________________________________________________________________________ +void +AliMUONPadStatusMaker::DecodeStatus(Int_t status, + Int_t& pedStatus, + Int_t& hvStatus, + Int_t& gainStatus, + Int_t& occStatus) +{ + /// Decode complete status into specific parts (ped,hv,gain) - return AliMUON2DMap::Generate(param); + occStatus = ( status & 0xFF000000 ) >> 24; + gainStatus = ( status & 0xFF0000 ) >> 16; + pedStatus = ( status & 0xFF00 ) >> 8; + hvStatus = (status & 0xFF); } //_____________________________________________________________________________ Bool_t -AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap, - Int_t detElemId, Int_t sector, - Bool_t& hvChannelTooLow, - Bool_t& hvChannelTooHigh, - Bool_t& hvChannelON) const +AliMUONPadStatusMaker::HVSt12Status(Int_t detElemId, Int_t sector, + Bool_t& hvChannelTooLow, + Bool_t& hvChannelTooHigh, + Bool_t& hvChannelON) const { /// Get HV status for one HV sector of St12 @@ -171,16 +219,23 @@ AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap, /// and the switch). /// Returns false if hv switch changed during the run. + AliCodeTimerAuto("",0) + + if (!fHV) return kFALSE; + Bool_t error = kFALSE; hvChannelTooLow = kFALSE; hvChannelTooHigh = kFALSE; hvChannelON = kTRUE; + + Int_t chamberId = AliMpDEManager::GetChamberId(detElemId); - AliMUONHVNamer hvNamer; + AliMpDCSNamer hvNamer("TRACKER"); - TString hvChannel(hvNamer.DCSHVChannelName(detElemId,sector)); + TString hvChannel(hvNamer.DCSChannelName(detElemId,sector)); - TPair* hvPair = static_cast(hvMap.FindObject(hvChannel.Data())); + TMap* hvMap = fkCalibrationData.HV(); + TPair* hvPair = static_cast(hvMap->FindObject(hvChannel.Data())); if (!hvPair) { AliError(Form("Did not find expected alias (%s) for DE %d", @@ -197,9 +252,8 @@ AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap, } else { - // find out min and max value, and makes a cut + // find out min value, and makes a cut Float_t hvMin(1E9); - Float_t hvMax(0); TIter next(values); AliDCSValue* val; @@ -207,46 +261,93 @@ AliMUONPadStatusMaker::GetSt12Status(const TMap& hvMap, { Float_t hv = val->GetFloat(); hvMin = TMath::Min(hv,hvMin); - hvMax = TMath::Max(hv,hvMax); } - float lowThreshold = fHVSt12Limits.X(); - float highThreshold = fHVSt12Limits.Y(); + float lowThreshold = HVLimit(chamberId); if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE; - if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE; - if ( hvMin < 1 ) hvChannelON = kFALSE; + if ( hvMin < hvNamer.TrackerHVOFF() ) hvChannelON = kFALSE; } } return error; } +//_____________________________________________________________________________ +Float_t +AliMUONPadStatusMaker::SwitchValue(const TObjArray& dcsArray) +{ + /// Loop over the dcs value for a single switch to decide whether + /// we should consider it on or off + + // we'll count the number of ON/OFF for this pad, to insure + // consistency (i.e. if status changed during the run, we should + // at least notify this fact ;-) and hope it's not the norm) + Int_t nTrue(0); + Int_t nFalse(0); + TIter next(&dcsArray); + AliDCSValue* val; + + while ( ( val = static_cast(next()) ) ) + { + if ( val->GetBool() ) + { + ++nTrue; + } + else + { + ++nFalse; + } + } + + if ( (nTrue>0 && nFalse>0) ) + { + // change of state during the run, consider it off + return 0.0; + } + + if ( nFalse ) + { + /// switch = FALSE means the HV was flowding up to the PCB. + /// i.e. switch = FALSE = ON + return 1.0; + } + + return 0.0; +} + //_____________________________________________________________________________ Bool_t -AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap, - Int_t detElemId, Int_t pcbIndex, - Bool_t& hvChannelTooLow, - Bool_t& hvChannelTooHigh, - Bool_t& hvChannelON, - Bool_t& hvSwitchON) const +AliMUONPadStatusMaker::HVSt345Status(Int_t detElemId, Int_t pcbIndex, + Bool_t& hvChannelTooLow, + Bool_t& hvChannelTooHigh, + Bool_t& hvChannelON, + Bool_t& hvSwitchON) const { /// For a given PCB in a given DE, get the HV status (both the channel /// and the switch). /// Returns false if something goes wrong (in particular if /// hv switch changed during the run). + AliCodeTimerAuto("",0) + + if (!fHV) return kFALSE; + Bool_t error = kFALSE; hvChannelTooLow = kFALSE; hvChannelTooHigh = kFALSE; hvSwitchON = kTRUE; hvChannelON = kTRUE; - AliMUONHVNamer hvNamer; + AliMpDCSNamer hvNamer("TRACKER"); + + Int_t chamberId = AliMpDEManager::GetChamberId(detElemId); - TString hvChannel(hvNamer.DCSHVChannelName(detElemId)); + TString hvChannel(hvNamer.DCSChannelName(detElemId)); - TPair* hvPair = static_cast(hvMap.FindObject(hvChannel.Data())); + TMap* hvMap = fkCalibrationData.HV(); + + TPair* hvPair = static_cast(hvMap->FindObject(hvChannel.Data())); if (!hvPair) { AliError(Form("Did not find expected alias (%s) for DE %d", @@ -263,9 +364,8 @@ AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap, } else { - // find out min and max value, and makes a cut + // find out min value, and makes a cut Float_t hvMin(1E9); - Float_t hvMax(0); TIter next(values); AliDCSValue* val; @@ -273,20 +373,17 @@ AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap, { Float_t hv = val->GetFloat(); hvMin = TMath::Min(hv,hvMin); - hvMax = TMath::Max(hv,hvMax); } - float lowThreshold = fHVSt345Limits.X(); - float highThreshold = fHVSt345Limits.Y(); + float lowThreshold = HVLimit(chamberId); if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE; - if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE; - if ( hvMin < 1 ) hvChannelON = kFALSE; + if ( hvMin < hvNamer.TrackerHVOFF() ) hvChannelON = kFALSE; } } - TString hvSwitch(hvNamer.DCSHVSwitchName(detElemId,pcbIndex)); - TPair* switchPair = static_cast(hvMap.FindObject(hvSwitch.Data())); + TString hvSwitch(hvNamer.DCSSwitchName(detElemId,pcbIndex)); + TPair* switchPair = static_cast(hvMap->FindObject(hvSwitch.Data())); if (!switchPair) { AliError(Form("Did not find expected alias (%s) for DE %d PCB %d", @@ -303,342 +400,374 @@ AliMUONPadStatusMaker::GetSt345Status(const TMap& hvMap, } else { - // we'll count the number of ON/OFF for this pad, to insure - // consistency (i.e. if status changed during the run, we should - // at least notify this fact ;-) and hope it's not the norm) - Int_t nTrue(0); - Int_t nFalse(0); - TIter next(values); - AliDCSValue* val; - - while ( ( val = static_cast(next()) ) ) + Float_t sv = SwitchValue(*values); + if ( sv < 0.99 ) hvSwitchON = kFALSE; + } + } + return error; +} + +//_____________________________________________________________________________ +Int_t +AliMUONPadStatusMaker::HVStatus(Int_t detElemId, Int_t manuId) const +{ + /// Get HV status of one manu + + AliCodeTimerAuto("",0) + + if ( !fHV ) return kMissing; + + Long_t lint = fHV->GetValue(AliMpManuUID::BuildUniqueID(detElemId,manuId)); + + if ( lint ) + { + return (Int_t)(lint - 1); + } + + Int_t status(0); + + AliMpDCSNamer hvNamer("TRACKER"); + + switch ( AliMpDEManager::GetStationType(detElemId) ) + { + case AliMp::kStation12: + { + int sector = hvNamer.ManuId2Sector(detElemId,manuId); + if ( sector >= 0 ) { - if ( val->GetBool() ) - { - ++nTrue; - } - else - { - ++nFalse; - } + Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON; + Bool_t error = HVSt12Status(detElemId,sector, + hvChannelTooLow, + hvChannelTooHigh, + hvChannelON); + if ( error ) status |= kHVError; + if ( hvChannelTooLow ) status |= kHVTooLow; + if ( hvChannelTooHigh ) status |= kHVTooHigh; + if ( !hvChannelON ) status |= kHVChannelOFF; + // assign this status to all the other manus handled by the same HV channel + SetHVStatus(detElemId,sector,status); } - - if ( (nTrue>0 && nFalse>0) ) + } + break; + case AliMp::kStation345: + { + int pcbIndex = hvNamer.ManuId2PCBIndex(detElemId,manuId); + if ( pcbIndex >= 0 ) { - AliWarning(Form("Status of HV Switch %s changed during this run nTrue=%d nFalse=%d! Will consider it OFF", - hvSwitch.Data(),nTrue,nFalse)); - error = kTRUE; + Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON; + Bool_t error = HVSt345Status(detElemId,pcbIndex, + hvChannelTooLow,hvChannelTooHigh, + hvChannelON,hvSwitchON); + if ( error ) status |= kHVError; + if ( hvChannelTooLow ) status |= kHVTooLow; + if ( hvChannelTooHigh ) status |= kHVTooHigh; + if ( !hvSwitchON ) status |= kHVSwitchOFF; + if ( !hvChannelON) status |= kHVChannelOFF; + // assign this status to all the other manus handled by the same HV channel + SetHVStatus(detElemId,pcbIndex,status); } - - if ( nFalse ) hvSwitchON = kFALSE; } + break; + default: + break; } - return error; + + return status; } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::MakeGainStatus(const AliMUONV2DStore& /*gainValues*/) const +AliMUONVCalibParam* +AliMUONPadStatusMaker::Neighbours(Int_t detElemId, Int_t manuId) const { - /// FIXME: to be implemented - AliWarning("Not implemented yet"); - return 0x0; + /// Get the neighbours parameters for a given manu + AliMUONVStore* neighbourStore = fkCalibrationData.Neighbours(); + return static_cast(neighbourStore->FindObject(detElemId,manuId)); } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::MakeHVStatus(const TMap& hvValues) const +AliMUONVStore* +AliMUONPadStatusMaker::NeighboursStore() const { - /// Scrutinize HV values and deduce an HV status for each pad - - TStopwatch timerSt12; - TStopwatch timerSt345; + /// Return the store containing all the neighbours + return fkCalibrationData.Neighbours(); +} + +//_____________________________________________________________________________ +AliMUONVCalibParam* +AliMUONPadStatusMaker::ComputeStatus(Int_t detElemId, Int_t manuId) const +{ + /// Compute the status of a given manu, using all available information, + /// i.e. pedestals, gains, and HV - timerSt12.Start(kTRUE); - timerSt12.Stop(); - timerSt345.Start(kTRUE); - timerSt345.Stop(); + AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,-1); + fStatus->Add(param); + + AliMUONVCalibParam* pedestals = static_cast(fPedestals->FindObject(detElemId,manuId)); + + AliMUONVCalibParam* gains = static_cast(fGains->FindObject(detElemId,manuId)); - AliMUONHVNamer hvNamer; + Int_t hvStatus = HVStatus(detElemId,manuId); + + Int_t occStatus = OccupancyStatus(detElemId,manuId); - AliMpDEIterator deIt; + for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel ) + { + Int_t pedStatus(0); + + if (pedestals) + { + Float_t pedMean = pedestals->ValueAsFloatFast(manuChannel,0); + Float_t pedSigma = pedestals->ValueAsFloatFast(manuChannel,1); + if ( pedMean < fPedMeanLimits.X() ) pedStatus |= kPedMeanTooLow; + else if ( pedMean > fPedMeanLimits.Y() ) pedStatus |= kPedMeanTooHigh; + if ( pedSigma < fPedSigmaLimits.X() ) pedStatus |= kPedSigmaTooLow; + else if ( pedSigma > fPedSigmaLimits.Y() ) pedStatus |= kPedSigmaTooHigh; + if ( pedMean == 0 ) pedStatus |= kPedMeanZero; + } + else + { + pedStatus = kPedMissing; + } + + Int_t gainStatus(0); - deIt.First(); + if ( gains ) + { + Float_t a0 = gains->ValueAsFloatFast(manuChannel,0); + Float_t a1 = gains->ValueAsFloatFast(manuChannel,1); + Float_t thres = gains->ValueAsFloatFast(manuChannel,2); + + if ( a0 < fGainA1Limits.X() ) gainStatus |= kGainA1TooLow; + else if ( a0 > fGainA1Limits.Y() ) gainStatus |= kGainA1TooHigh; + if ( a1 < fGainA2Limits.X() ) gainStatus |= kGainA2TooLow; + else if ( a1 > fGainA2Limits.Y() ) gainStatus |= kGainA2TooHigh; + if ( thres < fGainThresLimits.X() ) gainStatus |= kGainThresTooLow; + else if ( thres > fGainThresLimits.Y() ) gainStatus |= kGainThresTooHigh; + } + else + { + gainStatus = kGainMissing; + } + + Int_t status = BuildStatus(pedStatus,hvStatus,gainStatus,occStatus); + + param->SetValueAsIntFast(manuChannel,0,status); + } - AliMUONV2DStore* hv = new AliMUON2DMap(kTRUE); + return param; +} + +//_____________________________________________________________________________ +Int_t +AliMUONPadStatusMaker::OccupancyStatus(Int_t detElemId, Int_t manuId) const +{ + /// Get the "other" status for a given manu + + Int_t rv(0); - while ( !deIt.IsDone() ) + if ( fTrackerData ) { - Int_t detElemId = deIt.CurrentDEId(); + const Int_t occIndex = 2; - switch ( AliMpDEManager::GetStationType(detElemId) ) + Double_t occ = fTrackerData->DetectionElement(detElemId,occIndex); + + if ( occ <= fDEOccupancyLimits.X() ) { - case AliMp::kStation1: - case AliMp::kStation2: - timerSt12.Start(kFALSE); - for ( int sector = 0; sector < 3; ++sector) - { - AliDebug(1,Form("detElemId %5d sector %d",detElemId,sector)); - - Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON; - Bool_t error = GetSt12Status(hvValues, - detElemId,sector, - hvChannelTooLow,hvChannelTooHigh, - hvChannelON); - Int_t status = 0; - if ( error ) status |= kHVError; - if ( hvChannelTooLow ) status |= kHVTooLow; - if ( hvChannelTooHigh ) status |= kHVTooHigh; - if ( !hvChannelON ) status |= kHVChannelOFF; - SetStatusSt12(*hv,detElemId,sector,status); - - } - timerSt12.Stop(); - break; - case AliMp::kStation345: - { - timerSt345.Start(kFALSE); - for ( Int_t pcbIndex = 0; pcbIndex < hvNamer.NumberOfPCBs(detElemId); ++pcbIndex) - { - AliDebug(1,Form("detElemId %5d pcbIndex %d",detElemId,pcbIndex)); - Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON; - Bool_t error = GetSt345Status(hvValues, - detElemId,pcbIndex, - hvChannelTooLow,hvChannelTooHigh, - hvChannelON,hvSwitchON); - Int_t status = 0; - if ( error ) status |= kHVError; - if ( hvChannelTooLow ) status |= kHVTooLow; - if ( hvChannelTooHigh ) status |= kHVTooHigh; - if ( !hvSwitchON ) status |= kHVSwitchOFF; - if ( !hvChannelON) status |= kHVChannelOFF; - SetStatusSt345(*hv,detElemId,pcbIndex,status); - } - timerSt345.Stop(); - } - break; - default: - break; + rv |= kDEOccupancyTooLow; + } + else if ( occ > fDEOccupancyLimits.Y() ) + { + rv |= kDEOccupancyTooHigh; + } + + Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId); + + occ = fTrackerData->BusPatch(busPatchId,occIndex); + + if ( occ <= fBuspatchOccupancyLimits.X() ) + { + rv |= kBusPatchOccupancyTooLow; + } + else if ( occ > fBuspatchOccupancyLimits.Y() ) + { + rv |= kBusPatchOccupancyTooHigh; + } + + occ = fTrackerData->Manu(detElemId,manuId,occIndex); + + if ( occ <= fManuOccupancyLimits.X() ) + { + rv |= kManuOccupancyTooLow; + } + else if ( occ > fManuOccupancyLimits.Y() ) + { + rv |= kManuOccupancyTooHigh; } - deIt.Next(); } + return rv; +} + +//_____________________________________________________________________________ +AliMUONVCalibParam* +AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId) const +{ + /// Get the status container for a given manu - AliInfo("St12 timer:"); - StdoutToAliInfo(timerSt12.Print();); - AliInfo("St345 timer:"); - StdoutToAliInfo(timerSt345.Print();); - - return hv; + AliMUONVCalibParam* param = static_cast(fStatus->FindObject(detElemId,manuId)); + if (!param) + { + // not already there, so compute it now + AliCodeTimerAuto("ComputeStatus",0); + param = ComputeStatus(detElemId,manuId); + } + return param; } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::MakePedestalStatus(const AliMUONV2DStore& pedValues) const +Int_t +AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId, Int_t manuChannel) const { - /// Assign a pedestal status to each pad + /// Get the status for a given channel - TStopwatch timer; + AliMUONVCalibParam* param = static_cast(fStatus->FindObject(detElemId,manuId)); + if (!param) + { + // not already there, so compute it now + param = ComputeStatus(detElemId,manuId); + } + return param->ValueAsInt(manuChannel,0); +} + +//_____________________________________________________________________________ +void +AliMUONPadStatusMaker::SetHVStatus(Int_t detElemId, Int_t index, Int_t status) const +{ + /// Assign status to all manus in a given HV "zone" (defined by index, meaning + /// is different thing from St12 and St345) - timer.Start(kTRUE); + AliCodeTimerAuto("",0) - AliMUONV2DStore* pedStatuses = new AliMUON2DMap(kTRUE); + AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId); - AliMUONVDataIterator* it = pedValues.Iterator(); - AliMUONObjectPair* pair; - Int_t nofManus(0); + const AliMpArrayI* manus = de->ManusForHV(index); - while ( ( pair = static_cast(it->Next() ) ) ) + for ( Int_t i = 0; i < manus->GetSize(); ++ i ) { - AliMpIntPair* ip = static_cast(pair->First()); - Int_t detElemId = ip->GetFirst(); - Int_t manuId = ip->GetSecond(); - AliMUONVCalibParam* pedestals = static_cast(pair->Second()); - ++nofManus; - for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel ) - { - Int_t status(0); - if ( AliMpManuList::DoesChannelExist(detElemId, manuId, manuChannel) ) - { - Float_t pedMean = pedestals->ValueAsFloat(manuChannel,0); - Float_t pedSigma = pedestals->ValueAsFloat(manuChannel,1); - if ( pedMean < fPedMeanLimits.X() ) status |= kPedMeanTooLow; - if ( pedMean > fPedMeanLimits.Y() ) status |= kPedMeanTooHigh; - if ( pedSigma < fPedSigmaLimits.X() ) status |= kPedSigmaTooLow; - if ( pedSigma > fPedSigmaLimits.Y() ) status |= kPedSigmaTooHigh; - if ( pedMean == 0 ) status |= kPedMeanZero; - - AliMUONVCalibParam* vStatus = - static_cast(pedStatuses->Get(detElemId,manuId)); - if ( !vStatus ) - { - vStatus = new AliMUONCalibParam1I(64,0); - pedStatuses->Set(detElemId,manuId,vStatus,false); - } - vStatus->SetValueAsInt(manuChannel,0,status); - } - } + Int_t manuId = manus->GetValue(i); + fHV->Add(AliMpManuUID::BuildUniqueID(detElemId,manuId),status + 1); } - - AliInfo(Form("%d manus checked in :",nofManus)); - StdoutToAliInfo(timer.Print();); - return pedStatuses; } //_____________________________________________________________________________ -AliMUONV2DStore* -AliMUONPadStatusMaker::MakeStatus() const +Double_t +AliMUONPadStatusMaker::HVLimit(Int_t chamberId) const { - /// Read ped, gains and hv values from CDB, apply some Q&A and produces - /// a combined status for each pad. + /// Get HV limit for a given chamber + if ( chamberId >=0 && chamberId < 10 ) + { + return fHVLimit[chamberId]; + } + return 0.0; +} - TMap* hvValues = fCalibrationData.HV(); - AliMUONV2DStore* hvStatus(0x0); +//_____________________________________________________________________________ +void +AliMUONPadStatusMaker::SetHVLimit(Int_t chamberId, Double_t hv) +{ + /// Set hv limit for a given chamber (or all if chamberId==-1) - if (!hvValues) + if ( chamberId == -1 ) { - AliError("Could not get HV values from CDB. Will create dummy ones and mark those as missing"); - AliMUONCalibParam1I param(64,kHVMissing); - hvStatus = AliMUON2DMap::Generate(param); + for ( Int_t i = 0; i < 10; ++i ) + { + fHVLimit[i] = hv; + } } - else + else if ( chamberId >= 0 && chamberId < 10 ) { - hvStatus = MakeHVStatus(*hvValues); - } - - AliMUONV2DStore* pedValues = fCalibrationData.Pedestals(); - AliMUONV2DStore* pedStatus(0x0); - - if (!pedValues) - { - AliError("Could not get pedestals values from CDB. Will create dummy ones and mark those as missing"); - AliMUONCalibParam1I param(64,kPedMissing); - pedStatus = AliMUON2DMap::Generate(param); + fHVLimit[chamberId]=hv; } else { - pedStatus = MakePedestalStatus(*pedValues); + AliError(Form("chamberId=%d is invalid",chamberId)); } +} + +//_____________________________________________________________________________ +void +AliMUONPadStatusMaker::SetLimits(const AliMUONRecoParam& recoParams) +{ + /// Set the limits from the recoparam - // FIXME: should do the same for gains as for hv and ped. - - AliMUONV2DStore* status = Combine(*hvStatus,*pedStatus,8); + for ( int i = 0; i < 10; ++i ) + { + SetHVLimit(i,recoParams.HVLimit(i)); + } - delete hvStatus; - delete pedStatus; + SetPedMeanLimits(recoParams.PedMeanLowLimit(),recoParams.PedMeanHighLimit()); + SetPedSigmaLimits(recoParams.PedSigmaLowLimit(),recoParams.PedSigmaHighLimit()); - // Insure we get all channels there (some or even all can be bad, but they - // must be there somehow). + SetGainA1Limits(recoParams.GainA1LowLimit(),recoParams.GainA1HighLimit()); + SetGainA2Limits(recoParams.GainA2LowLimit(),recoParams.GainA2HighLimit()); + SetGainThresLimits(recoParams.GainThresLowLimit(),recoParams.GainThresHighLimit()); - AliMUON2DStoreValidator validator; - - TObjArray* a = validator.Validate(*status); - - if (a) - { - // this should not happen. - AliError("Status store not complete. Crash to follow soon..."); - StdoutToAliError(a->Print();); - AliFatal("this should not happen at all!"); - delete status; - status = 0x0; - } - - return status; + SetManuOccupancyLimits(recoParams.ManuOccupancyLowLimit(),recoParams.ManuOccupancyHighLimit()); + SetBuspatchOccupancyLimits(recoParams.BuspatchOccupancyLowLimit(),recoParams.BuspatchOccupancyHighLimit()); + SetDEOccupancyLimits(recoParams.DEOccupancyLowLimit(),recoParams.DEOccupancyHighLimit()); } //_____________________________________________________________________________ -void -AliMUONPadStatusMaker::SetStatusSt12(AliMUONV2DStore& hvStatus, - Int_t detElemId, - Int_t isector, - Int_t status) const +void +AliMUONPadStatusMaker::Report(UInt_t mask) { - /// Flag all pads of detElemId (for St12) as bad. + /// Report the number of bad pads, according to the mask, + /// and the various reasons why they are bad (with occurence rates) - // FIXME: need a way to iterator on pads over a given HV sector for St12... - // we currently suppose that one sector is about a third of the chamber... - // FIXME !! This has to be checked very carefully... + AliInfo(""); + AliCodeTimerAuto("",0); + + AliMUONLogger log(1064008); - const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 }; + Int_t nBadPads(0); + Int_t nPads(0); - for ( Int_t icathode = 0; icathode < 2; ++icathode ) + AliMpManuIterator it; + + Int_t detElemId, manuId; + + while ( it.Next(detElemId,manuId) ) { - const AliMpSectorSegmentation* seg = - static_cast(AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,kCathodes[icathode])); - const AliMpSector* sector = seg->GetSector(); - AliMpMotifMap* mMap = sector->GetMotifMap(); - TArrayI a; - - mMap->GetAllMotifPositionsIDs(a); + AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId); - TVector2 dim = seg->Dimensions(); - Double_t x = dim.X()*2; - Double_t xmin = isector*x/3.0; - Double_t xmax = xmin + x/3.0; - - for ( Int_t i = 0; i < a.GetSize(); ++i ) + for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) { - AliMpMotifPosition* pos = mMap->FindMotifPosition(a[i]); - Int_t manuId = pos->GetID(); - TVector2 position = pos->Position(); - if ( position.X() >= xmin && position.X() <= xmax) + if ( de->IsConnectedChannel(manuId,i) ) { - AliMUONVCalibParam* dead = - static_cast(hvStatus.Get(detElemId,manuId)); - if (!dead) - { - dead = new AliMUONCalibParam1I(64,status); - hvStatus.Set(detElemId,manuId,dead,false); - } - else + ++nPads; + + Int_t status = PadStatus(detElemId,manuId,i); + + if ( mask && ( status & mask) ) // note that if mask == 0, all pads are good... { - // FIXME: this should really not happen, if we'd know really the - // relationship between manuId and HV sector... - // For the time being, let's leave it like that, for testing - // purposes only. For production, this will have to be fixed. - AliWarning("Please fixme."); + ++nBadPads; + log.Log(AsString(status)); } } } - } -} - -//_____________________________________________________________________________ -void -AliMUONPadStatusMaker::SetStatusSt345(AliMUONV2DStore& hvStatus, - Int_t detElemId, Int_t pcbIndex, - Int_t status) const -{ - /// Flag all pads of pcbIndex-th PCB of detElemId (for St345) as bad. + } + + TString msg; + Int_t ntimes; - const AliMp::CathodType kCathodes[] = { AliMp::kCath0, AliMp::kCath1 }; + cout << Form("According to mask %x (human readable form below) %6d pads are bad (over a total of %6d, i.e. %7.2f %%)", + mask,nBadPads,nPads,nPads ? nBadPads*100.0/nPads : 0.0) << endl; + cout << AliMUONPadStatusMaker::AsCondition(mask) << endl; + cout << "--------" << endl; - for ( Int_t icathode = 0; icathode < 2; ++icathode ) + while ( log.Next(msg,ntimes) ) { - const AliMpSlatSegmentation* seg = static_cast - (AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,kCathodes[icathode])); - const AliMpSlat* slat = seg->Slat(); - const AliMpPCB* pcb = slat->GetPCB(pcbIndex); - - for ( Int_t i = 0; i < pcb->GetSize(); ++i ) - { - AliMpMotifPosition* pos = pcb->GetMotifPosition(i); - Int_t manuId = pos->GetID(); - AliMUONVCalibParam* dead = - static_cast(hvStatus.Get(detElemId,manuId)); - if (dead) - { - AliError(Form("dead is not null as expected from DE %d manuId %d", - detElemId,manuId)); - } - if (!dead) - { - dead = new AliMUONCalibParam1I(64,status); - hvStatus.Set(detElemId,manuId,dead,false); - } - } + cout << Form("The message (%120s) occured %15d times (%7.4f %%)",msg.Data(),ntimes,ntimes*100.0/nPads) << endl; } + } - -