#include "AliMUONDigitCalibrator.h"
#include "AliLog.h"
+#include "AliMpConstants.h"
#include "AliMUONCalibrationData.h"
-#include "AliMUONConstants.h"
-#include "AliMUONData.h"
-#include "AliMUONDigit.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONLogger.h"
+#include "AliMUONPadStatusMaker.h"
+#include "AliMUONPadStatusMapMaker.h"
+#include "AliMUONVStore.h"
#include "AliMUONVCalibParam.h"
-#include "TClonesArray.h"
+//-----------------------------------------------------------------------------
/// \class AliMUONDigitCalibrator
/// Class used to calibrate digits (either real or simulated ones).
///
/// bad digits).
///
/// \author Laurent Aphecetche
+//-----------------------------------------------------------------------------
/// \cond CLASSIMP
/// \endcond
//_____________________________________________________________________________
-AliMUONDigitCalibrator::AliMUONDigitCalibrator(AliMUONData* muonData,
- AliMUONCalibrationData* calib)
-: TTask("AliMUONDigitCalibrator","Subtract pedestal from digit charge"),
- fData(muonData),
- fCalibrationData(calib)
+AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib)
+: TObject(),
+fLogger(new AliMUONLogger(1000)),
+fStatusMaker(0x0),
+fStatusMapMaker(0x0),
+fPedestals(0x0),
+fGains(0x0)
{
- /// ctor. This class need the muonData to get access to the digit,
- /// and the calibrationData to get access to calibration parameters.
+ /// ctor
+ fStatusMaker = new AliMUONPadStatusMaker(calib);
+
+ // this is here that we decide on our "goodness" policy, i.e.
+ // what do we call an invalid pad (a pad maybe bad because its HV
+ // was too low, or its pedestals too high, etc..)
+ // FIXME: find a way not to hard-code the goodness policy (i.e. the limits)
+ // here...
+ fStatusMaker->SetHVSt12Limits(1300,1600);
+ fStatusMaker->SetHVSt345Limits(1500,2000);
+ fStatusMaker->SetPedMeanLimits(50,200);
+ fStatusMaker->SetPedSigmaLimits(0.1,3);
+
+ Int_t mask(0x8080);
+ //FIXME: kind of fake one for the moment, we consider dead only
+ // if ped and/or hv value missing.
+ //WARNING : getting this mask wrong is a very effective way of getting
+ //no digits at all out of this class ;-)
+
+ Bool_t deferredInitialization = kTRUE;
+
+ fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,mask,deferredInitialization);
+
+ fPedestals = calib.Pedestals();
+ fGains = calib.Gains();
}
//_____________________________________________________________________________
AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
{
- /// empty dtor.
+ /// dtor.
+ delete fStatusMaker;
+ delete fStatusMapMaker;
+
+ AliInfo("Summary of messages:");
+ fLogger->Print();
+
+ delete fLogger;
}
//_____________________________________________________________________________
void
-AliMUONDigitCalibrator::Exec(Option_t*)
+AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
{
- /// Main method.
- /// We loop on tracking chambers (i.e. we do nothing for trigger)
- /// and for each digit in that chamber, we calibrate it :
- /// a) if the corresponding channel is known to be bad, we set the signal to 0
- /// (so that digit can be suppressed later on)
- /// b) we then apply pedestal and gain corrections.
+ /// Calibrate the digits contained in digitStore
+ TIter next(digitStore.CreateTrackerIterator());
+ AliMUONVDigit* digit;
+
+ while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
+ {
+ CalibrateDigit(*digit);
+ }
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigitCalibrator::CalibrateDigit(AliMUONVDigit& digit)
+{
+ /// Calibrate one digit
+
+ if ( digit.IsCalibrated() )
+ {
+ fLogger->Log("ERROR : trying to calibrate a digit twice");
+ return;
+ }
+
+ Int_t statusMap = fStatusMapMaker->StatusMap(digit.DetElemId(),
+ digit.ManuId(),
+ digit.ManuChannel());
+
+ digit.SetStatusMap(statusMap);
+ digit.Calibrated(kTRUE);
- for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ++ch )
+ if ( ( statusMap & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 )
+ {
+ // pad itself is bad (not testing its neighbours at this stage)
+ digit.SetCharge(0);
+ fLogger->Log(Form("%s:%d:Channel detElemId %d manuId %d "
+ "manuChannel %d is bad %x",__FILE__,__LINE__,
+ digit.DetElemId(),digit.ManuId(),
+ digit.ManuChannel(),digit.StatusMap()));
+ }
+ else
{
- TClonesArray* digitArray = fData->Digits(ch);
- Int_t nDigits = digitArray->GetEntriesFast();
- for ( Int_t d = 0; d < nDigits; ++d )
+ // If the channel is good, go on with the calibration itself.
+
+ AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
+ (fPedestals->FindObject(digit.DetElemId(),digit.ManuId()));
+
+ AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
+ (fGains->FindObject(digit.DetElemId(),digit.ManuId()));
+
+ if (!pedestal)
{
- AliMUONDigit* digit =
- static_cast<AliMUONDigit*>(digitArray->UncheckedAt(d));
-
- // Very first check is whether this channel is known to be bad,
- // in which case we set the signal to zero.
- AliMUONVCalibParam* dead = static_cast<AliMUONVCalibParam*>
- (fCalibrationData->DeadChannels(digit->DetElemId(),digit->ManuId()));
- if ( dead && dead->ValueAsInt(digit->ManuChannel()) )
- {
- AliWarning(Form("Removing dead channel detElemId %d manuId %d "
- "manuChannel %d",digit->DetElemId(),digit->ManuId(),
- digit->ManuChannel()));
- digit->SetSignal(0);
- continue;
- }
-
- // If the channel is good, go on with the calibration itself.
-
- AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
- (fCalibrationData->Pedestals(digit->DetElemId(),digit->ManuId()));
-
- AliMUONVCalibParam* gain = static_cast<AliMUONVCalibParam*>
- (fCalibrationData->Gains(digit->DetElemId(),digit->ManuId()));
+ AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
+ digit.DetElemId(),digit.ManuId()));
- if (!pedestal)
- {
- AliFatal(Form("Got a null ped object for DE,manu=%d,%d",
- digit->DetElemId(),digit->ManuId()));
-
- }
- if (!gain)
- {
- AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
- digit->DetElemId(),digit->ManuId()));
- }
-
- Int_t manuChannel = digit->ManuChannel();
- Float_t adc = digit->Signal();
- Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
- if ( padc < 3.0*pedestal->ValueAsFloat(manuChannel,1) )
+ }
+ if (!gain)
+ {
+ AliFatal(Form("Got a null gain object for DE,manu=%d,%d",
+ digit.DetElemId(),digit.ManuId()));
+ }
+
+ Int_t manuChannel = digit.ManuChannel();
+ Float_t adc = digit.ADC();
+ Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
+ Float_t charge(0);
+ if ( padc > 3.0*pedestal->ValueAsFloat(manuChannel,1) )
+ {
+ Float_t a0 = gain->ValueAsFloat(manuChannel,0);
+ Float_t a1 = gain->ValueAsFloat(manuChannel,1);
+ Int_t thres = gain->ValueAsInt(manuChannel,2);
+ if ( padc < thres )
{
- padc = 0.0;
+ charge = a0*padc;
}
- Float_t charge = padc*gain->ValueAsFloat(manuChannel,0);
- digit->SetSignal(charge);
- Int_t saturation = gain->ValueAsInt(manuChannel,1);
- if ( charge >= saturation )
+ else
{
- digit->Saturated(kTRUE);
+ charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres);
}
}
+ digit.SetCharge(charge);
+ Int_t saturation = gain->ValueAsInt(manuChannel,4);
+ if ( charge >= saturation )
+ {
+ digit.Saturated(kTRUE);
+ }
}
}