/**************************************************************************
-* 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. *
-**************************************************************************/
+ * 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$
#include "AliMUONVStore.h"
#include "AliMpBusPatch.h"
#include "AliMpConstants.h"
+#include "AliMpCDB.h"
#include "AliMpDDLStore.h"
#include "AliMpDEIterator.h"
#include "AliMpDetElement.h"
+#include "AliMpManuStore.h"
//-----------------------------------------------------------------------------
/// \class AliMUONDigitCalibrator
const Int_t AliMUONDigitCalibrator::fgkNoGain(0);
const Int_t AliMUONDigitCalibrator::fgkGainConstantCapa(1);
const Int_t AliMUONDigitCalibrator::fgkGain(2);
+const Int_t AliMUONDigitCalibrator::fgkInjectionGain(3);
//_____________________________________________________________________________
AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib,
- const AliMUONRecoParam* recoParams,
+ const AliMUONRecoParam* recoParams,
const char* calibMode)
: TObject(),
fLogger(new AliMUONLogger(20000)),
fApplyGains(0),
fCapacitances(0x0),
fNumberOfBadPads(0),
-fNumberOfPads(0)
+fNumberOfPads(0),
+fChargeSigmaCut(0),
+fMask(0)
{
/// ctor
fApplyGains(0),
fCapacitances(0x0),
fNumberOfBadPads(0),
-fNumberOfPads(0)
+fNumberOfPads(0),
+fChargeSigmaCut(0),
+fMask(0)
{
/// ctor
fApplyGains = fgkGain;
AliInfo("Will apply gain correction, with measured capacitances");
}
+ else if ( cMode == "INJECTIONGAIN")
+ {
+ fApplyGains = fgkInjectionGain;
+ AliInfo("Will apply injection gain correction, with EMELEC factory gains");
+ }
else
{
AliError(Form("Invalid calib mode = %s. Will use NOGAIN instead",calibMode));
fApplyGains = fgkNoGain;
}
-
+
+ // Load mapping manu store
+ if ( ! AliMpCDB::LoadManuStore() ) {
+ AliFatal("Could not access manu store from OCDB !");
+ }
+
fStatusMaker = new AliMUONPadStatusMaker(calib);
- Int_t mask(0x8080);
+ // Set default values, as loose as reasonable
+
+ fChargeSigmaCut = 3.0;
+
+ fMask = 0x8080; // reject pads where ped *or* hv are missing
- // 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..)
if ( recoParams )
{
- fStatusMaker->SetHVSt12Limits(recoParams->HVSt12LowLimit(),recoParams->HVSt12HighLimit());
- fStatusMaker->SetHVSt345Limits(recoParams->HVSt345LowLimit(),recoParams->HVSt345HighLimit());
- fStatusMaker->SetPedMeanLimits(recoParams->PedMeanLowLimit(),recoParams->PedMeanHighLimit());
- fStatusMaker->SetPedSigmaLimits(recoParams->PedSigmaLowLimit(),recoParams->PedSigmaHighLimit());
- fStatusMaker->SetGainA1Limits(recoParams->GainA1LowLimit(),recoParams->GainA1HighLimit());
- fStatusMaker->SetGainA2Limits(recoParams->GainA2LowLimit(),recoParams->GainA2HighLimit());
- fStatusMaker->SetGainThresLimits(recoParams->GainThresLowLimit(),recoParams->GainThresHighLimit());
- mask = recoParams->PadGoodnessMask();
+ // if we have reco params, we use limits and cuts from there :
+
+ fStatusMaker->SetLimits(*recoParams);
+
+ fMask = recoParams->PadGoodnessMask();
//WARNING : getting this mask wrong is a very effective way of getting
//no digits at all out of this class ;-)
+
+ fChargeSigmaCut = recoParams->ChargeSigmaCut();
}
Bool_t deferredInitialization = kTRUE;
- fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,mask,deferredInitialization);
+ fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,fMask,deferredInitialization);
fPedestals = calib.Pedestals();
-
+
fGains = calib.Gains(); // we get gains whatever the calibMode is, in order
// to get the saturation value...
-
- if ( fApplyGains == fgkGain )
+
+ if ( fApplyGains == fgkGain || fApplyGains == fgkInjectionGain )
{
fCapacitances = calib.Capacitances();
}
AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
{
/// dtor.
- delete fStatusMaker;
- delete fStatusMapMaker;
- AliInfo("Summary of messages:");
- fLogger->Print();
+ if ( fNumberOfPads > 0 )
+ {
+ if ( fStatusMaker )
+ {
+ fStatusMaker->Report(fMask);
+ }
+
+ AliInfo("Summary of messages:");
- AliInfo(Form("We have seen %g pads, and rejected %g (%7.2f %%)",
- fNumberOfPads,fNumberOfBadPads,
- ( fNumberOfPads > 0 ) ? fNumberOfBadPads*100.0/fNumberOfPads : 0 ));
-
+ fLogger->Print();
+
+ AliInfo(Form("We have seen %g pads, and rejected %g (%7.2f %%)",
+ fNumberOfPads,fNumberOfBadPads,
+ ( fNumberOfPads > 0 ) ? fNumberOfBadPads*100.0/fNumberOfPads : 0 ));
+ }
+
+ delete fStatusMaker;
+ delete fStatusMapMaker;
delete fLogger;
}
/// Calibrate the digits contained in digitStore
TIter next(digitStore.CreateTrackerIterator());
AliMUONVDigit* digit;
- Int_t detElemId(-1);
- Double_t nsigmas(3.0);
+
+ fStatusMapMaker->RefreshRejectProbabilities(); // this will do something only for simulations
+ // (and only for those simulations where the reject list contain probabilities which are
+ // different from zero or one)
AliDebug(1,Form("# of digits = %d",digitStore.GetSize()));
digit->Calibrated(kTRUE);
- if ( digit->DetElemId() != detElemId )
- {
- // Find out occupancy of that DE
- detElemId = digit->DetElemId();
- AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
- Double_t nchannels = de->NofChannels();
- Double_t occ = digitStore.GetSize(detElemId)/nchannels;
- if ( occ > 0.05 )
- {
- nsigmas = 10.0; // enlarge (a lot) sigma cut if occupancy is high
- // (which probably means zero suppression was not exactly OK).
- fLogger->Log(Form("Will use %5.0f*sigma cut for DE %04d "
- "due to high occupancy",nsigmas,detElemId));
- }
- else
- {
- nsigmas = 3.0;
- }
- }
-
Float_t charge(0.0);
Int_t statusMap;
Bool_t isSaturated(kFALSE);
+ ++fNumberOfPads;
+
Bool_t ok = IsValidDigit(digit->DetElemId(),digit->ManuId(),digit->ManuChannel(),&statusMap);
-
+
digit->SetStatusMap(statusMap);
if (ok)
{
- ++fNumberOfPads;
charge = CalibrateDigit(digit->DetElemId(),digit->ManuId(),digit->ManuChannel(),
- digit->ADC(),nsigmas,&isSaturated);
+ digit->ADC(),fChargeSigmaCut,&isSaturated);
}
else
{
- ++fNumberOfBadPads;
+ ++fNumberOfBadPads;
}
digit->SetCharge(charge);
{
/// Calibrate one digit
-
+ /// Return the digit charge, in fC
AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
(fPedestals->FindObject(detElemId,manuId));
}
Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
- Float_t charge(0);
- Float_t capa(1.0);
- if ( fApplyGains == fgkGainConstantCapa )
- {
- capa = 0.2; // pF
- }
- else if ( fApplyGains == fgkGain )
+ // Gain (mV/fC) = 1/(a0*capa) with a0~1.25 and capa~0.2
+ Float_t charge(0);
+ Float_t capa(0.2); // capa = 0.2 and a0 = 1.25
+ Float_t a0(1.25); // is equivalent to gain = 4 mV/fC
+ Float_t a1(0);
+ Float_t adc2mv(0.61); // 1 ADC channel = 0.61 mV
+ Float_t injGain(4); // By default the gain is set to 4 mV/fC
+ //
+ // Note that the ChargeMax (for one pad) is roughly 4096 * 0.61 mV/channel / 4 mV/fC = 625 fC
+
+ if ( fApplyGains == fgkGain || fApplyGains == fgkInjectionGain )
{
- AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-
- Int_t serialNumber = de->GetManuSerialFromId(manuId);
+ Int_t serialNumber
+ = AliMpManuStore::Instance()->GetManuSerial(detElemId, manuId);
AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fCapacitances->FindObject(serialNumber));
if ( param )
{
- capa = param->ValueAsFloat(manuChannel);
+ capa = param->ValueAsFloat(manuChannel,0);
+ injGain = param->ValueAsFloat(manuChannel,1);
+ if ( injGain < 0 )
+ {
+ fLogger->Log(Form("injGain is %e < 0 for serialNumber=%d",injGain,serialNumber));
+ return 0.0;
+ }
}
else
{
- fLogger->Log(Form("No capa found for serialNumber=%d",serialNumber));
- capa = 0.0;
+ // If capa not found in the OCDB we exit
+ fLogger->Log(Form("No capa (injGain) found for serialNumber=%d",serialNumber));
+ return 0.0;
}
}
if ( padc > nsigmas*pedestal->ValueAsFloat(manuChannel,1) )
{
- if ( fApplyGains != fgkNoGain )
+ if ( fApplyGains == fgkGain || fApplyGains == fgkGainConstantCapa )
{
- Float_t a0 = gain->ValueAsFloat(manuChannel,0);
- Float_t a1 = gain->ValueAsFloat(manuChannel,1);
+ a0 = gain->ValueAsFloat(manuChannel,0);
+ a1 = gain->ValueAsFloat(manuChannel,1);
Int_t thres = gain->ValueAsInt(manuChannel,2);
if ( padc < thres )
{
{
charge = a0*thres + a0*(padc-thres) + a1*(padc-thres)*(padc-thres);
}
+ charge *= capa*adc2mv;
}
- else
+ else if ( fApplyGains == fgkInjectionGain )
{
- charge = padc;
+
+ charge = padc*adc2mv/injGain;
}
+ else
+ {
+ charge = a0*padc*capa*adc2mv;
+ }
}
- charge *= capa;
-
if ( isSaturated )
{
Int_t saturation(3000);
-
- if ( gain )
+
+ if ( gain && ( fApplyGains != fgkNoGain ) )
{
saturation = gain->ValueAsInt(manuChannel,4);
}
-
+
if ( padc >= saturation )
{
*isSaturated = kTRUE;
}
else
{
- isSaturated = kFALSE;
+ *isSaturated = kFALSE;
}
}
- return charge;
+ return ( charge > 0.0 ? charge : 0.0 );
}
//_____________________________________________________________________________