1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONPadStatusMaker
21 /// Make a 2DStore of pad statuses, using different sources of information,
22 /// like pedestal values, gain values, and HV values.
24 /// \author Laurent Aphecetche
25 //-----------------------------------------------------------------------------
27 #include "AliMUONPadStatusMaker.h"
29 #include "AliCDBEntry.h"
30 #include "AliCDBManager.h"
31 #include "AliCodeTimer.h"
32 #include "AliDCSValue.h"
34 #include "AliMUON2DMap.h"
35 #include "AliMUON2DStoreValidator.h"
36 #include "AliMUONCalibParamNI.h"
37 #include "AliMUONCalibrationData.h"
38 #include "AliMUONStringIntMap.h"
39 #include "AliMUONVCalibParam.h"
40 #include "AliMpArea.h"
41 #include "AliMpArrayI.h"
42 #include "AliMpConstants.h"
43 #include "AliMpDDLStore.h"
44 #include "AliMpDEIterator.h"
45 #include "AliMpDEManager.h"
46 #include "AliMpDetElement.h"
47 #include "AliMpExMap.h"
48 #include "AliMpHVNamer.h"
49 #include "AliMpIntPair.h"
50 #include "AliMpManuUID.h"
51 #include "AliMpMotifMap.h"
52 #include "AliMpMotifPosition.h"
55 #include "AliMpSegmentation.h"
56 #include "AliMpSlat.h"
57 #include "AliMpSlatSegmentation.h"
58 #include "AliMpStationType.h"
59 #include "AliMpVPadIterator.h"
60 #include "AliMpVSegmentation.h"
61 #include <Riostream.h>
68 ClassImp(AliMUONPadStatusMaker)
71 //_____________________________________________________________________________
72 AliMUONPadStatusMaker::AliMUONPadStatusMaker(const AliMUONCalibrationData& calibData)
73 : fCalibrationData(calibData),
74 fGainA0Limits(0,1E30),
75 fGainA1Limits(-1E-30,1E30),
76 fGainThresLimits(0,4095),
77 fHVSt12Limits(0,5000),
78 fHVSt345Limits(0,5000),
79 fPedMeanLimits(0,4095),
80 fPedSigmaLimits(0,4095),
81 fStatus(new AliMUON2DMap(true)),
83 fPedestals(calibData.Pedestals()),
84 fGains(calibData.Gains())
87 AliInfo(Form("ped store %s gain store %s",
88 fPedestals->ClassName(),
89 fGains->ClassName()));
92 //_____________________________________________________________________________
93 AliMUONPadStatusMaker::~AliMUONPadStatusMaker()
100 //_____________________________________________________________________________
102 AliMUONPadStatusMaker::AsString(Int_t status)
104 /// return a human readable version of the integer status
109 DecodeStatus(status,pedStatus,hvStatus,gainStatus);
115 // kGainA0TooLow = (1<<1),
116 // kGainA0TooHigh = (1<<2),
117 // kGainA1TooLow = (1<<3),
118 // kGainA1TooHigh = (1<<4),
119 // kGainThresTooLow = (1<<5),
120 // kGainThresTooHigh = (1<<6),
122 // kGainMissing = kMissing // please always use last bit for meaning "missing"
125 // /// Pedestal status
126 // enum EPedestalStatus
129 // kPedMeanZero = (1<<1),
130 // kPedMeanTooLow = (1<<2),
131 // kPedMeanTooHigh = (1<<3),
132 // kPedSigmaTooLow = (1<<4),
133 // kPedSigmaTooHigh = (1<<5),
135 // kPedMissing = kMissing // please always use last bit for meaning "missing"
140 if ( pedStatus == 0 ) s+= " OK";
141 if ( pedStatus & kPedMeanZero ) s += " Mean is Zero. ";
142 if ( pedStatus & kPedMeanTooLow ) s += " Mean Too Low. ";
143 if ( pedStatus & kPedMeanTooHigh ) s += " Mean Too High. ";
144 if ( pedStatus & kPedSigmaTooLow ) s += " Sigma Too Low. ";
145 if ( pedStatus & kPedSigmaTooHigh ) s += " Sigma Too High. ";
146 if ( pedStatus & kPedMissing ) s += " is missing.";
152 // kHVError = (1<<0),
153 // kHVTooLow = (1<<1),
154 // kHVTooHigh = (1<<2),
155 // kHVChannelOFF = (1<<3),
156 // kHVSwitchOFF = (1<<4),
158 // kHVMissing = kMissing // please always use last bit for meaning "missing"
164 //_____________________________________________________________________________
166 AliMUONPadStatusMaker::BuildStatus(Int_t pedStatus,
170 /// Build a complete status from specific parts (ped,hv,gain)
172 return ( hvStatus & 0xFF ) | ( ( pedStatus & 0xFF ) << 8 ) |
173 ( ( gainStatus & 0xFF ) << 16 );
176 //_____________________________________________________________________________
178 AliMUONPadStatusMaker::DecodeStatus(Int_t status,
183 /// Decode complete status into specific parts (ped,hv,gain)
185 gainStatus = ( status & 0xFF0000 ) >> 16;
186 pedStatus = ( status & 0xFF00 ) >> 8;
187 hvStatus = (status & 0xFF);
190 //_____________________________________________________________________________
192 AliMUONPadStatusMaker::HVSt12Status(Int_t detElemId, Int_t sector,
193 Bool_t& hvChannelTooLow,
194 Bool_t& hvChannelTooHigh,
195 Bool_t& hvChannelON) const
197 /// Get HV status for one HV sector of St12
199 /// For a given PCB in a given DE, get the HV status (both the channel
201 /// Returns false if hv switch changed during the run.
205 Bool_t error = kFALSE;
206 hvChannelTooLow = kFALSE;
207 hvChannelTooHigh = kFALSE;
210 AliMpHVNamer hvNamer;
212 TString hvChannel(hvNamer.DCSHVChannelName(detElemId,sector));
214 TMap* hvMap = fCalibrationData.HV();
215 TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(hvChannel.Data()));
218 AliError(Form("Did not find expected alias (%s) for DE %d",
219 hvChannel.Data(),detElemId));
224 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
227 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
232 // find out min and max value, and makes a cut
238 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
240 Float_t hv = val->GetFloat();
241 hvMin = TMath::Min(hv,hvMin);
242 hvMax = TMath::Max(hv,hvMax);
245 float lowThreshold = fHVSt12Limits.X();
246 float highThreshold = fHVSt12Limits.Y();
248 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
249 if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
250 if ( hvMin < 1 ) hvChannelON = kFALSE;
257 //_____________________________________________________________________________
259 AliMUONPadStatusMaker::HVSt345Status(Int_t detElemId, Int_t pcbIndex,
260 Bool_t& hvChannelTooLow,
261 Bool_t& hvChannelTooHigh,
263 Bool_t& hvSwitchON) const
265 /// For a given PCB in a given DE, get the HV status (both the channel
267 /// Returns false if something goes wrong (in particular if
268 /// hv switch changed during the run).
272 Bool_t error = kFALSE;
273 hvChannelTooLow = kFALSE;
274 hvChannelTooHigh = kFALSE;
278 AliMpHVNamer hvNamer;
280 TString hvChannel(hvNamer.DCSHVChannelName(detElemId));
282 TMap* hvMap = fCalibrationData.HV();
284 TPair* hvPair = static_cast<TPair*>(hvMap->FindObject(hvChannel.Data()));
287 AliError(Form("Did not find expected alias (%s) for DE %d",
288 hvChannel.Data(),detElemId));
293 TObjArray* values = static_cast<TObjArray*>(hvPair->Value());
296 AliError(Form("Could not get values for alias %s",hvChannel.Data()));
301 // find out min and max value, and makes a cut
307 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
309 Float_t hv = val->GetFloat();
310 hvMin = TMath::Min(hv,hvMin);
311 hvMax = TMath::Max(hv,hvMax);
314 float lowThreshold = fHVSt345Limits.X();
315 float highThreshold = fHVSt345Limits.Y();
317 if ( hvMin < lowThreshold ) hvChannelTooLow = kTRUE;
318 else if ( hvMax > highThreshold ) hvChannelTooHigh = kTRUE;
319 if ( hvMin < 1 ) hvChannelON = kFALSE;
323 TString hvSwitch(hvNamer.DCSHVSwitchName(detElemId,pcbIndex));
324 TPair* switchPair = static_cast<TPair*>(hvMap->FindObject(hvSwitch.Data()));
327 AliError(Form("Did not find expected alias (%s) for DE %d PCB %d",
328 hvSwitch.Data(),detElemId,pcbIndex));
333 TObjArray* values = static_cast<TObjArray*>(switchPair->Value());
336 AliError(Form("Could not get values for alias %s",hvSwitch.Data()));
341 // we'll count the number of ON/OFF for this pad, to insure
342 // consistency (i.e. if status changed during the run, we should
343 // at least notify this fact ;-) and hope it's not the norm)
349 while ( ( val = static_cast<AliDCSValue*>(next()) ) )
351 if ( val->GetBool() )
361 if ( (nTrue>0 && nFalse>0) )
363 AliWarning(Form("Status of HV Switch %s changed during this run nTrue=%d nFalse=%d! Will consider it OFF",
364 hvSwitch.Data(),nTrue,nFalse));
368 if ( nFalse ) hvSwitchON = kFALSE;
374 //_____________________________________________________________________________
376 AliMUONPadStatusMaker::HVStatus(Int_t detElemId, Int_t manuId) const
378 /// Get HV status of one manu
382 if ( !fCalibrationData.HV() ) return kMissing;
384 Long_t lint = fHV->GetValue(AliMpManuUID::BuildUniqueID(detElemId,manuId));
388 return (Int_t)(lint - 1);
393 AliMpHVNamer hvNamer;
395 switch ( AliMpDEManager::GetStationType(detElemId) )
397 case AliMp::kStation1:
398 case AliMp::kStation2:
400 int sector = hvNamer.ManuId2Sector(detElemId,manuId);
403 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON;
404 Bool_t error = HVSt12Status(detElemId,sector,
408 if ( error ) status |= kHVError;
409 if ( hvChannelTooLow ) status |= kHVTooLow;
410 if ( hvChannelTooHigh ) status |= kHVTooHigh;
411 if ( !hvChannelON ) status |= kHVChannelOFF;
412 // assign this status to all the other manus handled by the same HV channel
413 SetHVStatus(detElemId,sector,status);
417 case AliMp::kStation345:
419 int pcbIndex = hvNamer.ManuId2PCBIndex(detElemId,manuId);
422 Bool_t hvChannelTooLow, hvChannelTooHigh, hvChannelON,hvSwitchON;
423 Bool_t error = HVSt345Status(detElemId,pcbIndex,
424 hvChannelTooLow,hvChannelTooHigh,
425 hvChannelON,hvSwitchON);
426 if ( error ) status |= kHVError;
427 if ( hvChannelTooLow ) status |= kHVTooLow;
428 if ( hvChannelTooHigh ) status |= kHVTooHigh;
429 if ( !hvSwitchON ) status |= kHVSwitchOFF;
430 if ( !hvChannelON) status |= kHVChannelOFF;
431 // assign this status to all the other manus handled by the same HV channel
432 SetHVStatus(detElemId,pcbIndex,status);
443 //_____________________________________________________________________________
445 AliMUONPadStatusMaker::Neighbours(Int_t detElemId, Int_t manuId) const
447 /// Get the neighbours parameters for a given manu
448 AliMUONVStore* neighbourStore = fCalibrationData.Neighbours();
449 return static_cast<AliMUONVCalibParam*>(neighbourStore->FindObject(detElemId,manuId));
452 //_____________________________________________________________________________
454 AliMUONPadStatusMaker::NeighboursStore() const
456 /// Return the store containing all the neighbours
457 return fCalibrationData.Neighbours();
460 //_____________________________________________________________________________
462 AliMUONPadStatusMaker::ComputeStatus(Int_t detElemId, Int_t manuId) const
464 /// Compute the status of a given manu, using all available information,
465 /// i.e. pedestals, gains, and HV
467 // AliCodeTimerAuto("")
469 // AliCodeTimerStart("Param creation");
470 AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,-1);
472 // AliCodeTimerStop("Param creation");
474 // AliCodeTimerStart("FindObject");
475 AliMUONVCalibParam* pedestals = static_cast<AliMUONVCalibParam*>(fPedestals->FindObject(detElemId,manuId));
477 AliMUONVCalibParam* gains = static_cast<AliMUONVCalibParam*>(fGains->FindObject(detElemId,manuId));
478 // AliCodeTimerStop("FindObject");
480 Int_t hvStatus = HVStatus(detElemId,manuId);
482 // AliCodeTimerStart("Loop");
484 for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel )
490 Float_t pedMean = pedestals->ValueAsFloatFast(manuChannel,0);
491 Float_t pedSigma = pedestals->ValueAsFloatFast(manuChannel,1);
492 if ( pedMean < fPedMeanLimits.X() ) pedStatus |= kPedMeanTooLow;
493 else if ( pedMean > fPedMeanLimits.Y() ) pedStatus |= kPedMeanTooHigh;
494 if ( pedSigma < fPedSigmaLimits.X() ) pedStatus |= kPedSigmaTooLow;
495 else if ( pedSigma > fPedSigmaLimits.Y() ) pedStatus |= kPedSigmaTooHigh;
496 if ( pedMean == 0 ) pedStatus |= kPedMeanZero;
500 pedStatus = kPedMissing;
507 Float_t a0 = gains->ValueAsFloatFast(manuChannel,0);
508 Float_t a1 = gains->ValueAsFloatFast(manuChannel,1);
509 Float_t thres = gains->ValueAsFloatFast(manuChannel,2);
511 if ( a0 < fGainA0Limits.X() ) gainStatus |= kGainA0TooLow;
512 else if ( a0 > fGainA0Limits.Y() ) gainStatus |= kGainA0TooHigh;
513 if ( a1 < fGainA1Limits.X() ) gainStatus |= kGainA1TooLow;
514 else if ( a1 > fGainA1Limits.Y() ) gainStatus |= kGainA1TooHigh;
515 if ( thres < fGainThresLimits.X() ) gainStatus |= kGainThresTooLow;
516 else if ( thres > fGainThresLimits.Y() ) gainStatus |= kGainThresTooHigh;
520 gainStatus = kGainMissing;
523 Int_t status = BuildStatus(pedStatus,hvStatus,gainStatus);
525 param->SetValueAsIntFast(manuChannel,0,status);
528 // AliCodeTimerStop("Loop");
533 //_____________________________________________________________________________
535 AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId) const
537 /// Get the status for a given channel
539 AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->FindObject(detElemId,manuId));
542 // not already there, so compute it now
543 AliCodeTimerAuto("ComputeStatus");
544 param = ComputeStatus(detElemId,manuId);
549 //_____________________________________________________________________________
551 AliMUONPadStatusMaker::PadStatus(Int_t detElemId, Int_t manuId, Int_t manuChannel) const
553 /// Get the status for a given channel
555 AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->FindObject(detElemId,manuId));
558 // not already there, so compute it now
559 param = ComputeStatus(detElemId,manuId);
561 return param->ValueAsInt(manuChannel,0);
564 //_____________________________________________________________________________
566 AliMUONPadStatusMaker::SetHVStatus(Int_t detElemId, Int_t index, Int_t status) const
568 /// Assign status to all manus in a given HV "zone" (defined by index, meaning
569 /// is different thing from St12 and St345)
573 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
575 const AliMpArrayI* manus = de->ManusForHV(index);
577 for ( Int_t i = 0; i < manus->GetSize(); ++ i )
579 Int_t manuId = manus->GetValue(i);
580 fHV->Add(AliMpManuUID::BuildUniqueID(detElemId,manuId),status + 1);