fEndTime(0),
fMinTemp(0),
fMaxTemp(0),
+ fMinTempVariation(0),
+ fMaxTempVariation(0),
fMinTime(0),
fMaxTime(0),
fTemperatureResolution(0.1), // 0.1 deg C is default
fBiasAPD(NULL),
fCalibMapAPD(NULL),
fCalibReference(NULL),
- fCalibTimeDepCorrection(NULL)
+ fCalibTimeDepCorrection(NULL),
+ fVerbosity(0)
{
// Constructor
}
fEndTime(calibt.GetEndTime()),
fMinTemp(calibt.GetMinTemp()),
fMaxTemp(calibt.GetMaxTemp()),
+ fMinTempVariation(calibt.GetMinTempVariation()),
+ fMaxTempVariation(calibt.GetMaxTempVariation()),
fMinTime(calibt.GetMinTime()),
fMaxTime(calibt.GetMaxTime()),
fTemperatureResolution(calibt.GetTemperatureResolution()),
fBiasAPD(calibt.GetBiasAPD()),
fCalibMapAPD(calibt.GetCalibMapAPD()),
fCalibReference(calibt.GetCalibReference()),
- fCalibTimeDepCorrection(calibt.GetCalibTimeDepCorrection())
+ fCalibTimeDepCorrection(calibt.GetCalibTimeDepCorrection()),
+ fVerbosity(calibt.GetVerbosity())
{
// copy constructor
}
fEndTime = 0;
fMinTemp = 0;
fMaxTemp = 0;
+ fMinTempVariation = 0;
+ fMaxTempVariation = 0;
fMinTime = 0;
fMaxTime = 0;
fTemperatureResolution = 0.1; // 0.1 deg C is default
fCalibMapAPD = NULL;
fCalibReference = NULL;
fCalibTimeDepCorrection = NULL;
+ fVerbosity = 0;
return;
}
cout << " VARIABLE DUMP: " << endl
<< " GetStartTime() " << GetStartTime() << endl
<< " GetEndTime() " << GetEndTime() << endl
+ << " GetMinTime() " << GetMinTime() << endl
+ << " GetMaxTime() " << GetMaxTime() << endl
<< " GetMinTemp() " << GetMinTemp() << endl
- << " GetMaxTemp() " << GetMaxTemp() << endl;
+ << " GetMaxTemp() " << GetMaxTemp() << endl
+ << " GetMinTempVariation() " << GetMinTempVariation() << endl
+ << " GetMaxTempVariation() " << GetMaxTempVariation() << endl;
// run ranges
cout << " RUN INFO: " << endl
+ << " runnumber " << GetRunNumber() << endl
<< " length (in hours) " << GetLengthOfRunInHours() << endl
<< " range of temperature measurements (in hours) " << GetRangeOfTempMeasureInHours()
<< " (in deg. C) " << GetRangeOfTempMeasureInDegrees()
if (f) { // ok, looks like we have valid data/info
// let's check what the expected value at the time appears to be
Double_t val = f->Eval(timeHour);
- cout << " i " << i << " val " << val << endl;
+ if ( fVerbosity > 0 ) {
+ cout << " sensor i " << i << " val " << val << endl;
+ }
average += val;
n++;
}
Int_t AliEMCALCalibTimeDep::CalcCorrection()
{ // OK, this is where the real action takes place - the heart of this class..
/* The philosophy is as follows:
- 0. Init corrections to 1.0 values
- 1: if we have LED info for the tower, use it
- 2. if not 1, we rely on LED info averaged over strip
- 3. if not 2 either, we try to use temperature info + APD bias and calibration info
+ 0. Init corrections to 1.0 values, and see how many correction bins we need
+ 1. Check how large temperature variations we have through the run - do we really need all the correction bias (otherwise adjust to single bin)
+ 2. try to use temperature info + APD bias and calibration info, to estimate correction.
+ For now (from Dec 2009), we do not use LED info, since we are not taking LED triggers during the run.
*/
// 0: Init
// how many time-bins should we have for this run?
Int_t nBins = (Int_t) GetLengthOfRunInBins(); // round-down (from double to int)
Int_t binSize = (Int_t) (3600/fTimeBinsPerHour); // in seconds
+
+ // 1: get info on how much individual sensors might have changed during
+ // the run (compare max-min for each sensor separately)
+ if (fMaxTempVariation < fTemperatureResolution) {
+ nBins = 1; // just one bin needed..
+ binSize = fEndTime - fStartTime;
+ }
+
// set up a reasonable default (correction = 1.0)
+ fCalibTimeDepCorrection = new AliEMCALCalibTimeDepCorrection(nSM);
fCalibTimeDepCorrection->InitCorrection(nSM, nBins, 1.0);
fCalibTimeDepCorrection->SetStartTime(fStartTime);
fCalibTimeDepCorrection->SetNTimeBins(nBins);
fCalibTimeDepCorrection->SetTimeBinSize(binSize);
- // 1+2: try with LED corrections
- Int_t nRemaining = CalcLEDCorrection(nSM, nBins);
-
- // 3: try with Temperature, if needed
- if (nRemaining>0) {
- nRemaining = CalcTemperatureCorrection(nSM, nBins);
- }
+ // 2: try with Temperature correction
+ Int_t nRemaining = CalcTemperatureCorrection(nSM, nBins, binSize);
return nRemaining;
}
fMinTemp = 999; // init to some large value (999 deg C)
fMaxTemp = 0;
+ fMinTempVariation = 999; // init to some large value (999 deg C)
+ fMaxTempVariation = 0;
fMinTime = 2147483647; // init to a large value in the far future (0x7fffffff), year 2038 times..
fMaxTime = 0;
for (int i=0; i<fTempArray->NumSensors(); i++) {
AliEMCALSensorTemp *st = fTempArray->GetSensor(i);
+ if ( st->GetStartTime() == 0 ) { // no valid data
+ continue;
+ }
// check time ranges
if (fMinTime > st->GetStartTime()) { fMinTime = st->GetStartTime(); }
if (fMaxTime < st->GetEndTime()) { fMaxTime = st->GetEndTime(); }
-
+
// check temperature ranges
- TGraph *g = st->GetGraph();
- if (g) { // ok, looks like we have valid data/info
- // let's check what the expected value at the time appears to be
- if (fMinTemp > g->GetMinimum()) { fMinTemp = g->GetMinimum(); }
- if (fMaxTemp < g->GetMaximum()) { fMaxTemp = g->GetMaximum(); }
+ AliSplineFit *f = st->GetFit();
+
+ if (f) { // ok, looks like we have valid data/info
+ int np = f->GetKnots();
+ Double_t *y0 = f->GetY0();
+ // min and max values within the single sensor
+ Double_t min = 999;
+ Double_t max = 0;
+ for (int ip=0; ip<np; ip++) {
+ if (min > y0[ip]) { min = y0[ip]; }
+ if (max < y0[ip]) { max = y0[ip]; }
+ }
+ if (fMinTemp > min) { fMinTemp = min; }
+ if (fMaxTemp < max) { fMaxTemp = max; }
+ Double_t variation = max - min;
+ if (fMinTempVariation > variation) { fMinTempVariation = variation; }
+ if (fMaxTempVariation < variation) { fMaxTempVariation = variation; }
+
n++;
}
} // loop over fTempArray
void AliEMCALCalibTimeDep::GetCalibReferenceInfo()
{
// pick up Preprocessor output, based on fRun (most recent version)
- AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/MapAPD", fRun);
+ AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/Reference", fRun);
if (entry) {
fCalibReference = (AliEMCALCalibReference *) entry->GetObject();
}
}
//________________________________________________________________
-Int_t AliEMCALCalibTimeDep::CalcTemperatureCorrection(Int_t nSM, Int_t nBins)
+Int_t AliEMCALCalibTimeDep::CalcTemperatureCorrection(Int_t nSM, Int_t nBins, Int_t binSize)
{ // OK, so we didn't have valid LED data that allowed us to do the correction only
// with that info.
// So, instead we'll rely on the temperature info and try to do the correction
memset(dTempCoeff, 0, sizeof(dTempCoeff));
Float_t gainM = 0;
Double_t correction = 0;
- Double_t secondsPerBin = (3600/fTimeBinsPerHour);
+ Double_t secondsPerBin = (Double_t) binSize;
for (int i = 0; i < nSM; i++) {
- AliEMCALSuperModuleCalibTimeDepCorrection * dataCalibTimeDepCorrection = fCalibTimeDepCorrection->GetSuperModuleCalibTimeDepCorrectionNum(iSM);
+ AliEMCALSuperModuleCalibTimeDepCorrection * dataCalibTimeDepCorrection = fCalibTimeDepCorrection->GetSuperModuleCalibTimeDepCorrectionNum(i);
iSM = dataCalibTimeDepCorrection->GetSuperModuleNum();
AliEMCALSuperModuleCalibReference * dataCalibReference = fCalibReference->GetSuperModuleCalibReferenceNum(iSM);
AliEMCALSuperModuleCalibMapAPD * dataCalibMapAPD = fCalibMapAPD->GetSuperModuleCalibMapAPDNum(iSM);
- AliEMCALSuperModuleBiasAPD * dataBiasAPD = fBiasAPD->GetSuperModuleBiasAPDNum(iSM);
-
+ AliEMCALSuperModuleBiasAPD * dataBiasAPD = fBiasAPD->GetSuperModuleBiasAPDNum(iSM);
+
// first calculate the M=Gain values, and TemperatureCoeff, for all towers in this SuperModule, from BiasAPD and CalibMapAPD info
for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
gainM = fCalibMapAPD->GetGain(mapAPD->GetPar(0), mapAPD->GetPar(1), mapAPD->GetPar(2),
dataBiasAPD->GetVoltage(iCol, iRow));
dTempCoeff[iCol][iRow] = GetTempCoeff(mapAPD->GetDarkCurrent(), gainM);
+ if (fVerbosity > 1) {
+ cout << " iSM " << iSM << " iCol " << iCol << " iRow " << iRow
+ << " par0 " << mapAPD->GetPar(0)
+ << " par1 " << mapAPD->GetPar(1)
+ << " par2 " << mapAPD->GetPar(2)
+ << " bias " << dataBiasAPD->GetVoltage(iCol, iRow)
+ << " gainM " << gainM << " dTempCoeff " << dTempCoeff[iCol][iRow] << endl;
+ }
}
}
referenceTemperature /= nVal; // valid values exist, we can look into corrections
for (int j = 0; j < nBins; j++) {
-
// what is the timestamp in the middle of this bin? (0.5 is for middle of bin)
UInt_t timeStamp = fStartTime + (UInt_t)((j+0.5)*secondsPerBin);
// get the temperature at this time; use average over whole SM for now (TO BE CHECKED LATER - if we can do better with finer grained info)
Double_t dSMTemperature = GetTemperatureSM(iSM, timeStamp);
- Double_t temperatureDiff = referenceTemperature - dSMTemperature; // old vs new
+ Double_t temperatureDiff = dSMTemperature - referenceTemperature ; // new - old
+ if (fVerbosity > 0) {
+ cout << " referenceTemperature " << referenceTemperature
+ << " dSMTemperature " << dSMTemperature
+ << " temperatureDiff " << temperatureDiff
+ << endl;
+ }
// if the new temperature is higher than the old/reference one, then the gain has gone down
+ // if the new temperature is lower than the old/reference one, then the gain has gone up
+ // dTempCoeff is a negative number describing how many % (hence 0.01 factor below) the gain
+ // changes with a positive degree change.
+ // i.e. the product temperatureDiff * dTempCoeff increase when the gain goes up
+ // The correction we want to keep is what we should multiply our ADC value with as a function
+ // of time, i.e. the inverse of the gain change..
if (fabs(temperatureDiff)>fTemperatureResolution) {
// significant enough difference that we need to consider it
for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
- correction = temperatureDiff * dTempCoeff[iCol][iRow];
+ // the correction should be inverse of modification in gain: (see discussion above)
+ // modification in gain: 1.0 + (temperatureDiff * dTempCoeff[iCol][iRow])*0.01;
+ // 1/(1+x) ~= 1 - x for small x, i.e. we arrive at:
+ correction = 1.0 - (temperatureDiff * dTempCoeff[iCol][iRow])*0.01;
dataCalibTimeDepCorrection->GetCorrection(iCol,iRow)->AddAt(correction, j);
+ if (fVerbosity > 1) {
+ cout << " iSM " << iSM
+ << " iCol " << iCol
+ << " iRow " << iRow
+ << " j " << j
+ << " correction " << correction
+ << endl;
+ }
}
}
void Initialize(Int_t run, UInt_t startTime, UInt_t endTime);//!
// simple getters
- Int_t GetRunNumber() const { return fRun; } // run number
- Int_t GetStartTime() const { return fStartTime; } // start time
- Int_t GetEndTime() const { return fEndTime; } // end time
- Double_t GetLengthOfRunInHours() const; // length of run
- Double_t GetLengthOfRunInBins() const; // length of run
+ Int_t GetRunNumber() const { return fRun; } //
+ UInt_t GetStartTime() const { return fStartTime; } //
+ UInt_t GetEndTime() const { return fEndTime; } //
+ Double_t GetLengthOfRunInHours() const; //
+ Double_t GetLengthOfRunInBins() const; //
// Temperature Section
// access pointer to the basic temperature object: AliEMCALSensorTempArray
// range of temperature readings/values during the run
Int_t ScanTemperatureInfo(); // go through the temperature info
- Double_t GetMinTemp() const { return fMinTemp; } // min temp
- Double_t GetMaxTemp() const { return fMaxTemp; } // max temp
- UInt_t GetMinTime() const { return fMinTime; } // min time
- UInt_t GetMaxTime() const { return fMaxTime; } // max time
+ Double_t GetMinTemp() const { return fMinTemp; } //
+ Double_t GetMaxTemp() const { return fMaxTemp; } //
+ Double_t GetMinTempVariation() const { return fMinTempVariation; } //
+ Double_t GetMaxTempVariation() const { return fMaxTempVariation; } //
+ UInt_t GetMinTime() const { return fMinTime; } //
+ UInt_t GetMaxTime() const { return fMaxTime; } //
Double_t GetRangeOfTempMeasureInHours() const; //!
Double_t GetRangeOfTempMeasureInDegrees() const; //!
AliEMCALBiasAPD * GetBiasAPD() const { return fBiasAPD; } //
AliEMCALCalibMapAPD * GetCalibMapAPD() const { return fCalibMapAPD; } //
AliEMCALCalibReference * GetCalibReference() const { return fCalibReference; } //
- AliEMCALCalibTimeDepCorrection * GetCalibTimeDepCorrection() const { return fCalibTimeDepCorrection; } //
// storage and access of the correction info
Int_t CalcCorrection(); //
- AliEMCALCalibTimeDepCorrection * GetTimeDepCorrection()
+ AliEMCALCalibTimeDepCorrection * GetCalibTimeDepCorrection()
const { return fCalibTimeDepCorrection; } //
Double_t GetTempCoeff(Double_t IDark, Double_t M) const; //
+ // for local debugging: setters of the main input pointers that are normally from OCDB
+ void SetTempArray(AliEMCALSensorTempArray *arr) { fTempArray = arr; } //
+ void SetCalibSignal(AliCaloCalibSignal *obj) { fCalibSignal = obj; } //
+ void SetBiasAPD(AliEMCALBiasAPD *obj) { fBiasAPD = obj; } //
+ void SetCalibMapAPD(AliEMCALCalibMapAPD *obj) { fCalibMapAPD = obj; } //
+ void SetCalibReference(AliEMCALCalibReference *obj) { fCalibReference = obj; } //
+ // basic setters, also for local debugging
+ void SetRunNumber(Int_t i) { fRun= i; } //
+ void SetStartTime(UInt_t ui) { fStartTime = ui; } //
+ void SetEndTime(UInt_t ui) { fEndTime = ui; } //
+
+ Int_t GetVerbosity() const { return fVerbosity; } // debug flag
+ void SetVerbosity(Int_t i) { fVerbosity= i; } // debug flag
+
private:
void Reset(); //
Int_t CalcLEDCorrection(Int_t nSM, Int_t nBins); // based on LED signals, and reference photodiodes
Int_t CalcLEDCorrectionStripBasis(Int_t nSM, Int_t nBins); // based on LED signals, and reference photodiodes
- Int_t CalcTemperatureCorrection(Int_t nSM, Int_t nBins); // based on temperetare info
+ Int_t CalcTemperatureCorrection(Int_t nSM, Int_t nBins, Int_t binSize); // based on temperature info
//
Int_t fRun; // run number
// temperature stuff
Double_t fMinTemp; // min temp
Double_t fMaxTemp; // max temp
+ Double_t fMinTempVariation; // min temp variation, within a sensor
+ Double_t fMaxTempVariation; // max temp variation, within a sensor
UInt_t fMinTime; // min time
UInt_t fMaxTime; // max time
//
AliEMCALCalibReference *fCalibReference; // reference info
AliEMCALCalibTimeDepCorrection *fCalibTimeDepCorrection; // correction values
+ Int_t fVerbosity; // debug flag
+
//
ClassDef(AliEMCALCalibTimeDep,3) // EMCAL time-dep Calibration data
};