first version of new classes for time-dependent corrections; not yet used in Preproce...
authordsilverm <dsilverm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 10 Jul 2009 21:26:21 +0000 (21:26 +0000)
committerdsilverm <dsilverm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 10 Jul 2009 21:26:21 +0000 (21:26 +0000)
12 files changed:
EMCAL/AliEMCALBiasAPD.cxx [new file with mode: 0644]
EMCAL/AliEMCALBiasAPD.h [new file with mode: 0644]
EMCAL/AliEMCALCalibAbs.cxx [new file with mode: 0644]
EMCAL/AliEMCALCalibAbs.h [new file with mode: 0644]
EMCAL/AliEMCALCalibMapAPD.cxx [new file with mode: 0644]
EMCAL/AliEMCALCalibMapAPD.h [new file with mode: 0644]
EMCAL/AliEMCALCalibTimeDep.cxx
EMCAL/AliEMCALCalibTimeDep.h
EMCAL/AliEMCALCalibTimeDepCorrection.cxx [new file with mode: 0644]
EMCAL/AliEMCALCalibTimeDepCorrection.h [new file with mode: 0644]
EMCAL/SMcalib/WriteOCDBCalibMapAPD.C [new file with mode: 0644]
EMCAL/libEMCALbase.pkg

diff --git a/EMCAL/AliEMCALBiasAPD.cxx b/EMCAL/AliEMCALBiasAPD.cxx
new file mode 100644 (file)
index 0000000..7480984
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************
+ * 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: $ */
+
+// Objects of this class contain info on APD bias settings/voltages
+//
+
+#include <fstream>
+#include <TString.h>
+
+#include "AliEMCALBiasAPD.h"
+
+using namespace std;
+
+ClassImp(AliEMCALBiasAPD)
+
+//____________________________________________________________________________
+AliEMCALBiasAPD::AliEMCALBiasAPD() : 
+  fNSuperModule(0),
+  fSuperModuleData(0)
+{
+  //Default constructor.
+}
+
+//____________________________________________________________________________
+void AliEMCALBiasAPD::ReadBiasAPDInfo(Int_t nSM, const TString &txtFileName,
+                                     Bool_t swapSides)
+{
+  //Read data from txt file. ; coordinates given on SuperModule basis
+
+  std::ifstream inputFile(txtFileName.Data());
+  if (!inputFile) {
+    printf("AliEMCALBiasAPD::ReadBiasAPDInfo - Cannot open the APD info file %s\n", txtFileName.Data());
+    return;
+  }
+
+  fNSuperModule = nSM;
+  if (fSuperModuleData) delete [] fSuperModuleData;
+  fSuperModuleData = new AliEMCALSuperModuleBiasAPD[fNSuperModule];
+
+  Int_t iSM = 0; // SuperModule index
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t iElecId = 0;
+  Int_t iDAC = 0;
+  Float_t voltage = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleBiasAPD &t = fSuperModuleData[i];
+    if (!inputFile) {
+      printf("AliEMCALBiasAPD::ReadBiasAPDInfo - Error while reading input file; likely EOF..");
+      return;
+    }
+    inputFile >> iSM;
+    t.fSuperModuleNum = iSM;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      inputFile >> iCol >> iRow >> iElecId >> iDAC >> voltage;
+
+      // assume that this info is already swapped and done for this basis?
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      t.fElecId[iCol][iRow] = iElecId;
+      t.fDAC[iCol][iRow] = iDAC;
+      t.fVoltage[iCol][iRow] = voltage;
+    }
+
+  } // i, SuperModule
+
+  inputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+void AliEMCALBiasAPD::WriteBiasAPDInfo(const TString &txtFileName,
+                                      Bool_t swapSides)
+{
+  // write data to txt file. ; coordinates given on SuperModule basis
+
+  std::ofstream outputFile(txtFileName.Data());
+  if (!outputFile) {
+    printf("AliEMCALBiasAPD::WriteBiasAPDInfo - Cannot open the APD output file %s\n", txtFileName.Data());
+    return;
+  }
+
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t iElecId = 0;
+  Int_t iDAC = 0;
+  Float_t voltage = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleBiasAPD &t = fSuperModuleData[i];
+    outputFile << t.fSuperModuleNum << endl;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      iCol = j / AliEMCALGeoParams::fgkEMCALRows;
+      iRow = j % AliEMCALGeoParams::fgkEMCALRows;
+
+      iElecId = t.fElecId[iCol][iRow];
+      iDAC = t.fDAC[iCol][iRow];
+      voltage = t.fVoltage[iCol][iRow];
+
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      outputFile << iCol << " " << iRow << " " 
+                << iElecId << " " << iDAC << " "
+                << voltage << endl;
+    }
+
+  } // i, SuperModule
+
+  outputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+AliEMCALBiasAPD::~AliEMCALBiasAPD()
+{
+  delete [] fSuperModuleData;
+}
+
+//____________________________________________________________________________
+AliEMCALBiasAPD::AliEMCALSuperModuleBiasAPD AliEMCALBiasAPD::GetSuperModuleBiasAPDId(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleBiasAPD t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  return fSuperModuleData[supModIndex];
+}
+
+//____________________________________________________________________________
+AliEMCALBiasAPD::AliEMCALSuperModuleBiasAPD AliEMCALBiasAPD::GetSuperModuleBiasAPDNum(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleBiasAPD t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  for (int i=0; i<fNSuperModule; i++) {
+    if (fSuperModuleData[i].fSuperModuleNum == supModIndex) {
+      return fSuperModuleData[i];
+    }
+  }
+
+  return t;
+}
+
diff --git a/EMCAL/AliEMCALBiasAPD.h b/EMCAL/AliEMCALBiasAPD.h
new file mode 100644 (file)
index 0000000..578a050
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef ALIEMCALBIASAPD_H
+#define ALIEMCALBIASAPD_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: $ */
+
+#include <TObject.h>
+#include "AliEMCALGeoParams.h"
+class TString;
+
+/*
+  Objects of this class read txt file with APD data
+  AliEMCALBiasAPD inherits TObject only to use AliLog "functions".
+*/
+
+class AliEMCALBiasAPD : public TObject {
+public:
+  AliEMCALBiasAPD();
+
+  // Read and Write txt I/O methods are normally not used, but are useful for 
+  // filling the object before it is saved in OCDB 
+  void ReadBiasAPDInfo(Int_t nSM, const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  void WriteBiasAPDInfo(const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  virtual ~AliEMCALBiasAPD();
+
+  struct AliEMCALSuperModuleBiasAPD {
+    Int_t fSuperModuleNum;
+    Int_t fElecId[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; // ElectronicsIndex/Address - we keep this to help ensure that the column/row info matches with electronics indices
+    Int_t fDAC[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; // 0-0x3ff register
+    Float_t fVoltage[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; // 210 to ca 417 V. (function of DAC setting)
+  };
+
+  // pointer to stored info.
+  Int_t GetNSuperModule() const { return fNSuperModule; }; 
+  AliEMCALSuperModuleBiasAPD * GetSuperModuleData() const { return fSuperModuleData; };
+
+  // - via the index in the stored array:
+  virtual AliEMCALSuperModuleBiasAPD GetSuperModuleBiasAPDId(Int_t smIndex) const;
+  // - or via the actual SM number
+  virtual AliEMCALSuperModuleBiasAPD GetSuperModuleBiasAPDNum(Int_t smNum) const;
+
+protected:
+
+  Int_t          fNSuperModule; // Number of supermodules.
+  AliEMCALSuperModuleBiasAPD *fSuperModuleData; // SuperModule data
+
+private:
+
+  AliEMCALBiasAPD(const AliEMCALBiasAPD &);
+  AliEMCALBiasAPD &operator = (const AliEMCALBiasAPD &);
+
+  ClassDef(AliEMCALBiasAPD, 1) //BiasAPD data reader
+};
+
+#endif
diff --git a/EMCAL/AliEMCALCalibAbs.cxx b/EMCAL/AliEMCALCalibAbs.cxx
new file mode 100644 (file)
index 0000000..2d21563
--- /dev/null
@@ -0,0 +1,234 @@
+/**************************************************************************
+ * 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: $ */
+
+// Objects of this class contain basis for absolute calibrations
+//
+
+#include <fstream>
+#include <TString.h>
+
+#include "AliEMCALCalibAbs.h"
+
+using namespace std;
+
+ClassImp(AliEMCALCalibAbs)
+
+//____________________________________________________________________________
+AliEMCALCalibAbs::AliEMCALCalibAbs() : 
+  fNSuperModule(0),
+  fSuperModuleData(0)
+{
+  //Default constructor.
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibAbs::ReadCalibAbsInfo(Int_t nSM, const TString &txtFileName,
+                                     Bool_t swapSides)
+{
+  //Read data from txt file. ; coordinates given on SuperModule basis
+
+  std::ifstream inputFile(txtFileName.Data());
+  if (!inputFile) {
+    printf("AliEMCALCalibAbs::ReadCalibAbsInfo - Cannot open the APD info file %s\n", txtFileName.Data());
+    return;
+  }
+
+  fNSuperModule = nSM;
+  if (fSuperModuleData) delete [] fSuperModuleData;
+  fSuperModuleData = new AliEMCALSuperModuleCalibAbs[fNSuperModule];
+
+  Int_t iSM = 0; // SuperModule index
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t id = 0;
+
+  // list of values to be read
+  // first: overall values for the whole SuperModule
+  Int_t CalibMethod; 
+  Int_t CalibPass; 
+  Int_t CalibTime; 
+  Float_t AbsoluteGain; 
+  // second: additional info for LED Reference and SM temperature
+  Float_t LEDRefAmp;
+  Float_t LEDRefAmpRMS;
+  Float_t LEDRefHighLowRatio;
+  Int_t LEDRefHighLow;
+  Float_t Temperature;
+  Float_t TemperatureRMS;
+  // third: info for each tower
+  Float_t RelativeGain; // (ADC>GeV relative gain/conversion), value around 1
+  Float_t HighLowRatio; // value around 16 or so
+  Int_t HighLow; // 
+  Float_t LEDAmp; // low gain eq. amplitude
+  Float_t LEDAmpRMS; //
+  // end - all values
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibAbs &t = fSuperModuleData[i];
+    if (!inputFile) {
+      printf("AliEMCALCalibAbs::ReadCalibAbsInfo - Error while reading input file; likely EOF..");
+      return;
+    }
+    inputFile >> iSM;
+    t.fSuperModuleNum = iSM;
+
+    // first: overall values for the whole SuperModule
+    inputFile >> CalibMethod >> CalibPass >> CalibTime >> AbsoluteGain;
+    t.fCalibMethod = CalibMethod;
+    t.fCalibPass = CalibPass;
+    t.fCalibTime = CalibTime;
+    t.fAbsoluteGain = AbsoluteGain;
+
+    // second: additional info for LED Reference and SM temperature
+    for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
+      inputFile >> id >> LEDRefAmp >> LEDRefAmpRMS >> LEDRefHighLowRatio >> LEDRefHighLow;
+      t.fLEDRefAmp[id] = LEDRefAmp;
+      t.fLEDRefAmpRMS[id] = LEDRefAmpRMS;
+      t.fLEDRefHighLowRatio[id] = LEDRefHighLowRatio;
+      t.fLEDRefHighLow[id] = LEDRefHighLow;
+    }
+    for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
+      inputFile >> id >> Temperature >> TemperatureRMS;
+      t.fTemperature[id] = Temperature;
+      t.fTemperatureRMS[id] = TemperatureRMS;
+    }
+
+    // third: info for each tower
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      inputFile >> iCol >> iRow 
+               >> RelativeGain >> HighLowRatio >> HighLow >> LEDAmp >> LEDAmpRMS;
+
+      // assume that this info is already swapped and done for this basis?
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      AliEMCALCalibAbsVal &v = t.fAPDVal[iCol][iRow];
+
+      v.fRelativeGain = RelativeGain;
+      v.fHighLowRatio = HighLowRatio;
+      v.fHighLow = HighLow;
+      v.fLEDAmp = LEDAmp;
+      v.fLEDAmpRMS = LEDAmpRMS;
+    }
+
+  } // i, SuperModule
+
+  inputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibAbs::WriteCalibAbsInfo(const TString &txtFileName,
+                                      Bool_t swapSides)
+{
+  // write data to txt file. ; coordinates given on SuperModule basis
+
+  std::ofstream outputFile(txtFileName.Data());
+  if (!outputFile) {
+    printf("AliEMCALCalibAbs::WriteCalibAbsInfo - Cannot open the APD output file %s\n", txtFileName.Data());
+    return;
+  }
+
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibAbs &t = fSuperModuleData[i];
+    // first: overall values for the whole SuperModule
+    outputFile << t.fSuperModuleNum << endl;
+    outputFile << t.fCalibMethod << " " 
+              << t.fCalibPass << " " 
+              << t.fCalibTime << " " 
+              << t.fAbsoluteGain << endl;
+
+    // second: additional info for LED Reference and SM temperature
+    for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
+      outputFile << j << " " << t.fLEDRefAmp[j] << " " << t.fLEDRefAmpRMS[j] 
+                << " " << t.fLEDRefHighLowRatio[j] << " " << t.fLEDRefHighLow[j] 
+                << endl;
+    }
+    for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
+      outputFile << j << " " << t.fTemperature[j] << " " << t.fTemperatureRMS[j] << endl;
+    }
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      iCol = j / AliEMCALGeoParams::fgkEMCALRows;
+      iRow = j % AliEMCALGeoParams::fgkEMCALRows;
+
+      AliEMCALCalibAbsVal &v = t.fAPDVal[iCol][iRow];
+
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      outputFile << iCol << " " << iRow 
+                << " " << v.fRelativeGain
+                << " " << v.fHighLowRatio 
+                << " " << v.fHighLow 
+                << " " << v.fLEDAmp 
+                << " " << v.fLEDAmpRMS << endl;
+    }
+
+  } // i, SuperModule
+
+  outputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibAbs::~AliEMCALCalibAbs()
+{
+  delete [] fSuperModuleData;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibAbs::AliEMCALSuperModuleCalibAbs AliEMCALCalibAbs::GetSuperModuleCalibAbsId(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibAbs t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  return fSuperModuleData[supModIndex];
+}
+
+//____________________________________________________________________________
+AliEMCALCalibAbs::AliEMCALSuperModuleCalibAbs AliEMCALCalibAbs::GetSuperModuleCalibAbsNum(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibAbs t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  for (int i=0; i<fNSuperModule; i++) {
+    if (fSuperModuleData[i].fSuperModuleNum == supModIndex) {
+      return fSuperModuleData[i];
+    }
+  }
+
+  return t;
+}
+
diff --git a/EMCAL/AliEMCALCalibAbs.h b/EMCAL/AliEMCALCalibAbs.h
new file mode 100644 (file)
index 0000000..7ec3ad3
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef ALIEMCALCALIBABS_H
+#define ALIEMCALCALIBABS_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: $ */
+
+#include <TObject.h>
+#include "AliEMCALGeoParams.h"
+class TString;
+
+/*
+  Objects of this class contain basis for absolute calibrations
+  AliEMCALCalibAbs inherits TObject only to use AliLog "functions".
+*/
+
+class AliEMCALCalibAbs : public TObject {
+
+public:
+
+  enum kProblemType {kNoLED=-999};// code in possible problems
+
+  AliEMCALCalibAbs();
+
+  // Read and Write txt I/O methods are normally not used, but are useful for 
+  // debug purposes
+  void ReadCalibAbsInfo(Int_t nSM, const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  void WriteCalibAbsInfo(const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  virtual ~AliEMCALCalibAbs();
+
+  // total calibration factor is a product of
+  // a) overall calibration factor [fAbsoluteGain]
+  // b) individual gain factor per tower [fRelativeGain]
+  // c) time-dependent correction
+  // In this class we store a), b) and the needed static ingredients for c)
+
+  // values per single tower
+  struct AliEMCALCalibAbsVal {
+    Float_t fRelativeGain; // (ADC>GeV relative gain/conversion), value around 1
+    Float_t fHighLowRatio; // value around 16 or so
+    Int_t fHighLow; // 0 (low) or 1 (high) gain, used for LEDAmp info
+    Float_t fLEDAmp; // LED amplitude
+    Float_t fLEDAmpRMS; // RMS
+  };
+
+  // 1 SuperModule's worth of info: info on where the different APDs are
+  struct AliEMCALSuperModuleCalibAbs {
+    // first: overall values for the whole SuperModule
+    Int_t fSuperModuleNum; // which SuperModule is this?
+    Int_t fCalibMethod; // a la 0=cosmics, 1=pi0, 2=electrons,3=using ecore,
+    Int_t fCalibPass; // which analysis iteration is this.. 1,2,..N
+    Int_t fCalibTime; // t0, unix timestamp
+    Float_t fAbsoluteGain; // (ADC>GeV absolute gain/conversion)
+
+    // second: additional info for LED Reference and SM temperature
+    Float_t fLEDRefAmp[AliEMCALGeoParams::fgkEMCALLEDRefs]; // LED amplitude at  t0, low gain equivalent
+    Float_t fLEDRefAmpRMS[AliEMCALGeoParams::fgkEMCALLEDRefs]; // RMS
+    Float_t fLEDRefHighLowRatio[AliEMCALGeoParams::fgkEMCALLEDRefs]; // value around 16 or so
+    Int_t fLEDRefHighLow[AliEMCALGeoParams::fgkEMCALLEDRefs]; // 0 (low) or 1 (high) gain
+
+    Float_t fTemperature[AliEMCALGeoParams::fgkEMCALTempSensors]; // temperature at t0
+    Float_t fTemperatureRMS[AliEMCALGeoParams::fgkEMCALTempSensors]; // RMS
+
+    // third: individual info for each tower
+    AliEMCALCalibAbsVal fAPDVal[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; // at t0
+  };
+
+  // pointer to stored info.
+
+  Int_t GetNSuperModule() const { return fNSuperModule; }; 
+  AliEMCALSuperModuleCalibAbs * GetSuperModuleData() const { return fSuperModuleData; };
+
+  // - via the index in the stored array:
+  virtual AliEMCALSuperModuleCalibAbs GetSuperModuleCalibAbsId(Int_t smIndex) const;
+  // - or via the actual SM number
+  virtual AliEMCALSuperModuleCalibAbs GetSuperModuleCalibAbsNum(Int_t smNum) const;
+
+protected:
+
+  Int_t          fNSuperModule; // Number of supermodules.
+  AliEMCALSuperModuleCalibAbs *fSuperModuleData; // SuperModule data
+
+private:
+
+  AliEMCALCalibAbs(const AliEMCALCalibAbs &);
+  AliEMCALCalibAbs &operator = (const AliEMCALCalibAbs &);
+
+  ClassDef(AliEMCALCalibAbs, 1) //CalibAbs data reader
+};
+
+#endif
diff --git a/EMCAL/AliEMCALCalibMapAPD.cxx b/EMCAL/AliEMCALCalibMapAPD.cxx
new file mode 100644 (file)
index 0000000..8f8573e
--- /dev/null
@@ -0,0 +1,192 @@
+/**************************************************************************
+ * 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: $ */
+
+// Objects of this class contain info on APD calibration and map info
+//
+
+#include <fstream>
+#include <TString.h>
+
+#include "AliEMCALCalibMapAPD.h"
+
+using namespace std;
+
+ClassImp(AliEMCALCalibMapAPD)
+
+//____________________________________________________________________________
+AliEMCALCalibMapAPD::AliEMCALCalibMapAPD() : 
+  fNSuperModule(0),
+  fSuperModuleData(0)
+{
+  //Default constructor.
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibMapAPD::ReadCalibMapAPDInfo(Int_t nSM, const TString &txtFileName,
+                                     Bool_t swapSides)
+{
+  //Read data from txt file. ; coordinates given on SuperModule basis
+
+  std::ifstream inputFile(txtFileName.Data());
+  if (!inputFile) {
+    printf("AliEMCALCalibMapAPD::ReadCalibMapAPDInfo - Cannot open the APD info file %s\n", txtFileName.Data());
+    return;
+  }
+
+  fNSuperModule = nSM;
+  if (fSuperModuleData) delete [] fSuperModuleData;
+  fSuperModuleData = new AliEMCALSuperModuleCalibMapAPD[fNSuperModule];
+
+  Int_t iSM = 0; // SuperModule index
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  // list of values to be read
+  Int_t iHW = 0;
+  Int_t APDNum = 0;
+  Float_t V30 = 0;     
+  Float_t Par[3] = {0};   
+  Float_t ParErr[3] = {0}; 
+  Int_t BreakDown = 0;
+  Float_t DarkCurrent = 0; 
+  // end - all values
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibMapAPD &t = fSuperModuleData[i];
+    if (!inputFile) {
+      printf("AliEMCALCalibMapAPD::ReadCalibMapAPDInfo - Error while reading input file; likely EOF..");
+      return;
+    }
+    inputFile >> iSM;
+    t.fSuperModuleNum = iSM;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      inputFile >> iCol >> iRow >> iHW 
+               >> APDNum >> V30 
+               >> Par[0] >> Par[1] >> Par[2]
+               >> ParErr[0] >> ParErr[1] >> ParErr[2]
+               >> BreakDown >> DarkCurrent;
+
+      // assume that this info is already swapped and done for this basis?
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      AliEMCALCalibMapAPDVal &v = t.fAPDVal[iCol][iRow];
+
+      v.fHardWareId = iHW;
+      v.fAPDNum = APDNum;
+      v.fV30 = V30;
+      v.fPar[0] = Par[0];
+      v.fPar[1] = Par[1];
+      v.fPar[2] = Par[2];
+      v.fParErr[0] = ParErr[0];
+      v.fParErr[1] = ParErr[1];
+      v.fParErr[2] = ParErr[2];
+      v.fBreakDown = BreakDown;
+      v.fDarkCurrent = DarkCurrent;
+    }
+
+  } // i, SuperModule
+
+  inputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibMapAPD::WriteCalibMapAPDInfo(const TString &txtFileName,
+                                      Bool_t swapSides)
+{
+  // write data to txt file. ; coordinates given on SuperModule basis
+
+  std::ofstream outputFile(txtFileName.Data());
+  if (!outputFile) {
+    printf("AliEMCALCalibMapAPD::WriteCalibMapAPDInfo - Cannot open the APD output file %s\n", txtFileName.Data());
+    return;
+  }
+
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibMapAPD &t = fSuperModuleData[i];
+    outputFile << t.fSuperModuleNum << endl;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      iCol = j / AliEMCALGeoParams::fgkEMCALRows;
+      iRow = j % AliEMCALGeoParams::fgkEMCALRows;
+
+      AliEMCALCalibMapAPDVal &v = t.fAPDVal[iCol][iRow];
+
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      outputFile << iCol << " " << iRow << " " << v.fHardWareId 
+                << " " << v.fAPDNum << " " << v.fV30 
+                << " " << v.fPar[0] << " " << v.fPar[1] << " " << v.fPar[2]
+                << " " << v.fParErr[0] << " " << v.fParErr[1] << " " << v.fParErr[2]
+                << " " << v.fBreakDown << " " << v.fDarkCurrent << endl;
+    }
+
+  } // i, SuperModule
+
+  outputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibMapAPD::~AliEMCALCalibMapAPD()
+{
+  delete [] fSuperModuleData;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibMapAPD::AliEMCALSuperModuleCalibMapAPD AliEMCALCalibMapAPD::GetSuperModuleCalibMapAPDId(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibMapAPD t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  return fSuperModuleData[supModIndex];
+}
+
+//____________________________________________________________________________
+AliEMCALCalibMapAPD::AliEMCALSuperModuleCalibMapAPD AliEMCALCalibMapAPD::GetSuperModuleCalibMapAPDNum(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibMapAPD t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  for (int i=0; i<fNSuperModule; i++) {
+    if (fSuperModuleData[i].fSuperModuleNum == supModIndex) {
+      return fSuperModuleData[i];
+    }
+  }
+
+  return t;
+}
+
diff --git a/EMCAL/AliEMCALCalibMapAPD.h b/EMCAL/AliEMCALCalibMapAPD.h
new file mode 100644 (file)
index 0000000..c473034
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef ALIEMCALCALIBMAPAPD_H
+#define ALIEMCALCALIBMAPAPD_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: $ */
+
+#include <TObject.h>
+#include "AliEMCALGeoParams.h"
+#include <cmath>
+class TString;
+
+/*
+  Objects of this class read txt file with APD data
+  AliEMCALCalibMapAPD inherits TObject only to use AliLog "functions".
+*/
+
+class AliEMCALCalibMapAPD : public TObject {
+
+public:
+
+  enum kValType {kCalibTemp=25};// 25 deg C used for all APD calibrations
+
+  AliEMCALCalibMapAPD();
+
+  // Read and Write txt I/O methods are normally not used, but are useful for 
+  // filling the object before it is saved in OCDB 
+  void ReadCalibMapAPDInfo(Int_t nSM, const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  void WriteCalibMapAPDInfo(const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  virtual ~AliEMCALCalibMapAPD();
+
+  // values per single APD
+  struct AliEMCALCalibMapAPDVal {
+
+    Int_t fHardWareId; // HardWareIndex
+    // info from APD calibrations
+    Int_t fAPDNum;    // assigned APD-PA number; Catania 10000-, Houston: 20000-
+    Float_t fV30;      // Catania/Houston Voltage V30 (V) at T = 25 deg C
+    Float_t fPar[3];   // fit parameters, p0,p1,p2 - for ADC vs bias measurement
+    Float_t fParErr[3]; // error on fit parameters     
+
+    Int_t fBreakDown; // Hamamatsu Breakdown Voltage (V)       
+    Float_t fDarkCurrent; // Hamamatsu Dark Current (A)        
+  };
+
+  // 1 SuperModule's worth of info: info on where the different APDs are
+  struct AliEMCALSuperModuleCalibMapAPD {
+    Int_t fSuperModuleNum;
+    AliEMCALCalibMapAPDVal fAPDVal[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows];
+  };
+
+  // pointer to stored info.
+
+  Int_t GetNSuperModule() const { return fNSuperModule; }; 
+  AliEMCALSuperModuleCalibMapAPD * GetSuperModuleData() const { return fSuperModuleData; };
+
+  // - via the index in the stored array:
+  virtual AliEMCALSuperModuleCalibMapAPD GetSuperModuleCalibMapAPDId(Int_t smIndex) const;
+  // - or via the actual SM number
+  virtual AliEMCALSuperModuleCalibMapAPD GetSuperModuleCalibMapAPDNum(Int_t smNum) const;
+
+  // method to calculate gain M from fit parameters, and HV value
+  Float_t GetGain(Float_t fitPar[3], Float_t HV) const 
+    { return (fitPar[0] + fitPar[1] * exp(fitPar[2]*HV)); };
+  Float_t GetGain(Float_t fitPar0, Float_t fitPar1, Float_t fitPar2, Float_t HV) const 
+    { return (fitPar0 + fitPar1 * exp(fitPar2*HV)); };
+
+protected:
+
+  Int_t          fNSuperModule; // Number of supermodules.
+  AliEMCALSuperModuleCalibMapAPD *fSuperModuleData; // SuperModule data
+
+private:
+
+  AliEMCALCalibMapAPD(const AliEMCALCalibMapAPD &);
+  AliEMCALCalibMapAPD &operator = (const AliEMCALCalibMapAPD &);
+
+  ClassDef(AliEMCALCalibMapAPD, 1) //MapAPD data reader
+};
+
+#endif
index 2dce6cf..d8c655a 100644 (file)
 #include "AliCDBEntry.h"
 #include "AliCDBManager.h"
 #include "AliEMCALSensorTempArray.h"
+#include "AliCaloCalibSignal.h"
+#include "AliEMCALBiasAPD.h"
+#include "AliEMCALCalibMapAPD.h"
+#include "AliEMCALCalibAbs.h"
+#include "AliEMCALCalibTimeDepCorrection.h" 
 #include "AliEMCALCalibTimeDep.h"
 
 /* first a bunch of constants.. */
 const double fkSecToHour = 1.0/3600.0; // conversion factor from seconds to hours
 
-// some global variables for APD handling; assume the same for all, at least to start with
-const double fkTempSlope = 0.017; // 1.7% per deg. C, seems about right for all APDs, from studies at Catania, and by Rachid. 
-// Note that this is only valid at gain M~30; i.e. voltages at V30. 
-// At V50, it's more like 2.25%/C, and at V20 about 1.35%/C (also info from Catania)
-const double fkNormTemp = 20; // let's say that 20 degrees C is normal as default
-
+// some global variables for APD handling; values from Catania studies, best fit
+// TempCoeff = p0+p1*M (M=gain), where p0 and and p1 are functions of the dark current
+const double fkTempCoeffP0Const = -0.903; // 
+const double fkTempCoeffP0Factor = -1.381e7; // 
+const double fkTempCoeffP1Const = -0.023; // 
+const double fkTempCoeffP1Factor = -4.966e5; //
 const double fkErrorCode = -999; // to indicate that something went wrong
 
 using namespace std;
@@ -55,8 +61,14 @@ AliEMCALCalibTimeDep::AliEMCALCalibTimeDep() :
   fMaxTemp(0),
   fMinTime(0),
   fMaxTime(0),
-  fRefTemp(fkNormTemp), 
-  fTempArray(NULL)
+  fTemperatureResolution(0.1), // 0.1 deg C is default
+  fTimeBinsPerHour(2), // 2 30-min bins per hour is default
+  fTempArray(NULL),
+  fCalibSignal(NULL),
+  fBiasAPD(NULL),
+  fCalibMapAPD(NULL),
+  fCalibAbs(NULL),
+  fCalibTimeDepCorrection(NULL)
 {
   // Constructor
 }
@@ -71,8 +83,14 @@ AliEMCALCalibTimeDep::AliEMCALCalibTimeDep(const AliEMCALCalibTimeDep& calibt) :
   fMaxTemp(calibt.GetMaxTemp()),
   fMinTime(calibt.GetMinTime()),
   fMaxTime(calibt.GetMaxTime()),
-  fRefTemp(calibt.GetRefTemp()),
-  fTempArray(calibt.GetTempArray())
+  fTemperatureResolution(calibt.GetTemperatureResolution()),
+  fTimeBinsPerHour(calibt.GetTimeBinsPerHour()),
+  fTempArray(calibt.GetTempArray()),
+  fCalibSignal(calibt.GetCalibSignal()),
+  fBiasAPD(calibt.GetBiasAPD()),
+  fCalibMapAPD(calibt.GetCalibMapAPD()),
+  fCalibAbs(calibt.GetCalibAbs()),
+  fCalibTimeDepCorrection(calibt.GetCalibTimeDepCorrection())
 {
   // copy constructor
 }
@@ -105,8 +123,14 @@ void  AliEMCALCalibTimeDep::Reset()
   fMaxTemp = 0;
   fMinTime = 0;
   fMaxTime = 0;
-  fRefTemp = fkNormTemp;
+  fTemperatureResolution = 0.1; // 0.1 deg C is default
+  fTimeBinsPerHour = 2; // 2 30-min bins per hour is default
   fTempArray = NULL;
+  fCalibSignal = NULL;
+  fBiasAPD = NULL;
+  fCalibMapAPD = NULL;
+  fCalibAbs = NULL;
+  fCalibTimeDepCorrection = NULL;
   return;
 }
 
@@ -114,44 +138,43 @@ void  AliEMCALCalibTimeDep::Reset()
 void  AliEMCALCalibTimeDep::PrintInfo() const
 {
   // print some info
-  cout << endl << " AliEMCALCalibTimeDep::Print() " << endl;
+  cout << endl << " AliEMCALCalibTimeDep::PrintInfo() " << endl;
   // basic variables, all 'publicly available' also
   cout << " VARIABLE DUMP: " << endl
        << " GetStartTime() " << GetStartTime() << endl
        << " GetEndTime() " << GetEndTime() << endl
        << " GetMinTemp() " << GetMinTemp() << endl
-       << " GetMaxTemp() " << GetMaxTemp() << endl
-       << " GetRefTemp() " << GetRefTemp() << endl;
+       << " GetMaxTemp() " << GetMaxTemp() << endl;
   // run ranges
   cout << " RUN INFO: " << endl
        << " length (in hours) " << GetLengthOfRunInHours() << endl
        << " range of temperature measurements (in hours) " << GetRangeOfTempMeasureInHours()
        << " (in deg. C) " << GetRangeOfTempMeasureInDegrees()
        << endl;
-  // range in correction values
-  double corrAtMinTemp = GetCorrection( fMinTemp );
-  double corrAtMaxTemp = GetCorrection( fMaxTemp );
-  double corrMaxMinDiff = 100*(corrAtMinTemp - corrAtMaxTemp);
-  cout << " CORRECTION INFO : " << endl
-       << " corrAtMinTemp " << corrAtMinTemp << endl
-       << " corrAtMaxTemp " << corrAtMaxTemp << endl
-       << " corrMaxMinDiff (~%) [=(corrAtMin - corrAtMax)*100] " 
-       << corrMaxMinDiff << endl;
 
   return;
 }
+
 //________________________________________________________________ 
-double AliEMCALCalibTimeDep::GetLengthOfRunInHours() const
+Double_t AliEMCALCalibTimeDep::GetLengthOfRunInHours() const
 {
   return (fEndTime - fStartTime)*fkSecToHour;
 }
+
+//________________________________________________________________ 
+Double_t AliEMCALCalibTimeDep::GetLengthOfRunInBins() const
+{
+  return (fEndTime - fStartTime)*fkSecToHour*fTimeBinsPerHour;
+}
+
 //________________________________________________________________ 
-double AliEMCALCalibTimeDep::GetRangeOfTempMeasureInHours() const
+Double_t AliEMCALCalibTimeDep::GetRangeOfTempMeasureInHours() const
 {
   return (fMaxTime - fMinTime)*fkSecToHour;
 }
+
 //________________________________________________________________ 
-double AliEMCALCalibTimeDep::GetRangeOfTempMeasureInDegrees() const
+Double_t AliEMCALCalibTimeDep::GetRangeOfTempMeasureInDegrees() const
 {
   return (fMaxTemp - fMinTemp);
 }
@@ -168,18 +191,19 @@ void AliEMCALCalibTimeDep::Initialize(Int_t run,
   
   // collect the needed information
   GetTemperatureInfo(); // temperature readings during the run
+  ScanTemperatureInfo(); // see what the boundaries are (Min/Max Time/Temp)
 
   return;
 }
 
 //________________________________________________________________
-double AliEMCALCalibTimeDep::GetTemperature(UInt_t timeStamp) const
+Double_t AliEMCALCalibTimeDep::GetTemperature(UInt_t timeStamp) const
 {// return estimate for all SuperModules and sensors, that had data 
 
   // first convert from seconds to hours..
-  double timeHour = (timeStamp - fStartTime) * fkSecToHour;
+  Double_t timeHour = (timeStamp - fStartTime) * fkSecToHour;
 
-  double average = 0;
+  Double_t average = 0;
   int n = 0;
 
   for (int i=0; i<fTempArray->NumSensors(); i++) {
@@ -191,7 +215,7 @@ double AliEMCALCalibTimeDep::GetTemperature(UInt_t timeStamp) const
       AliSplineFit *f = st->GetFit();
       if (f) { // ok, looks like we have valid data/info
        // let's check what the expected value at the time appears to be
-       double val = f->Eval(timeHour);
+       Double_t val = f->Eval(timeHour);
        average += val;
        n++;
       }
@@ -209,13 +233,13 @@ double AliEMCALCalibTimeDep::GetTemperature(UInt_t timeStamp) const
 }
 
 //________________________________________________________________
-double AliEMCALCalibTimeDep::GetTemperatureSM(int imod, UInt_t timeStamp) const
+Double_t AliEMCALCalibTimeDep::GetTemperatureSM(int imod, UInt_t timeStamp) const
 {// return estimate for this one SuperModule, if it had data 
 
   // first convert from seconds to hours..
-  double timeHour = (timeStamp - fStartTime) * fkSecToHour;
+  Double_t timeHour = (timeStamp - fStartTime) * fkSecToHour;
 
-  double average = 0;
+  Double_t average = 0;
   int n = 0;
 
   for (int i=0; i<fTempArray->NumSensors(); i++) {
@@ -228,7 +252,7 @@ double AliEMCALCalibTimeDep::GetTemperatureSM(int imod, UInt_t timeStamp) const
        AliSplineFit *f = st->GetFit();
        if (f) { // ok, looks like we have valid data/info
          // let's check what the expected value at the time appears to be
-         double val = f->Eval(timeHour);
+         Double_t val = f->Eval(timeHour);
          cout << " i " << i << " val " << val << endl;
          average += val;
          n++;
@@ -249,11 +273,11 @@ double AliEMCALCalibTimeDep::GetTemperatureSM(int imod, UInt_t timeStamp) const
 }
 
 //________________________________________________________________
-double AliEMCALCalibTimeDep::GetTemperatureSMSensor(int imod, int isens, UInt_t timeStamp) const
+Double_t AliEMCALCalibTimeDep::GetTemperatureSMSensor(int imod, int isens, UInt_t timeStamp) const
 {// return estimate for this one SuperModule and sensor, if it had data 
 
   // first convert from seconds to hours..
-  double timeHour = (timeStamp - fStartTime) * fkSecToHour;
+  Double_t timeHour = (timeStamp - fStartTime) * fkSecToHour;
 
   for (int i=0; i<fTempArray->NumSensors(); i++) {
     
@@ -265,7 +289,7 @@ double AliEMCALCalibTimeDep::GetTemperatureSMSensor(int imod, int isens, UInt_t
        AliSplineFit *f = st->GetFit();
        if (f) { // ok, looks like we have valid data/info
          // let's check what the expected value at the time appears to be
-         double val = f->Eval(timeHour);
+         Double_t val = f->Eval(timeHour);
 
          return val; // no point to move further in for loop, we have found the sensor we were looking for
        }
@@ -281,14 +305,49 @@ double AliEMCALCalibTimeDep::GetTemperatureSMSensor(int imod, int isens, UInt_t
 }
 
 //________________________________________________________________
-double AliEMCALCalibTimeDep::GetCorrection(double temperature) const
-{ // gain decreases with increasing temperature
-  double gain = (1.0 - (temperature-fRefTemp)*fkTempSlope);  
-  // i.e. multiplicative correction to ADC increases with increasing temperature
-  return 1.0/gain;
+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
+  // how many SuperModules do we have?
+  Int_t nSM = fCalibAbs->GetNSuperModule();
+  // how many time-bins should we have for this run?
+  Int_t nBins = (Int_t) GetLengthOfRunInBins(); // round-down (from double to int)
+  // set up a reasonable default (correction = 1.0)
+  fCalibTimeDepCorrection->InitCorrection(nSM, nBins, 1.0);
+
+  // 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);
+  }
+
+  return nRemaining;
 }
 
-/* Next comes the method that does the work in picking up all the needed info..*/
+
+//________________________________________________________________
+Double_t AliEMCALCalibTimeDep::GetTempCoeff(Double_t IDark, Double_t M) const
+{ // estimate the Temperature Coefficient, based on the dark current (IDark)
+  // and the gain (M), based on Catania parameterizations
+
+  Double_t P0 = fkTempCoeffP0Const + fkTempCoeffP0Factor * IDark;
+  Double_t P1 = fkTempCoeffP1Const + fkTempCoeffP1Factor * IDark;
+  Double_t TC = P0 + P1*M;
+
+  return TC;
+}
+
+/* Next come the methods that do the work in picking up all the needed info..*/
 //________________________________________________________________
 void AliEMCALCalibTimeDep::GetTemperatureInfo() 
 {
@@ -309,3 +368,507 @@ void AliEMCALCalibTimeDep::GetTemperatureInfo()
   
   return;
 }
+
+//________________________________________________________________
+Int_t AliEMCALCalibTimeDep::ScanTemperatureInfo() 
+{// assign max/min time and temperature values
+
+  fMinTemp = 999; // init to some large value (999 deg C)
+  fMaxTemp = 0;
+  fMinTime = 2147483647; // init to a large value in the far future (0x7fffffff), year 2038 times..
+  fMaxTime = 0;
+
+  Int_t n = 0; // number of valid readings
+
+  for (int i=0; i<fTempArray->NumSensors(); i++) {
+    
+    AliEMCALSensorTemp *st = fTempArray->GetSensor(i);
+
+    // 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(); }
+      n++;
+    }
+  } // loop over fTempArray
+  
+  if (n>0) { // some valid data was found
+    return n;
+  }
+  else { // no good data
+    return (Int_t) fkErrorCode;
+  }
+
+}
+
+//________________________________________________________________
+void AliEMCALCalibTimeDep::GetCalibSignalInfo() 
+{
+  // pick up Preprocessor output, based on fRun (most recent version)
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/LED", fRun);
+  if (entry) {
+    fCalibSignal = (AliCaloCalibSignal *) entry->GetObject();
+  }
+
+  if (fCalibSignal) { 
+    AliInfo( Form("CalibSignal: NEvents %d NAcceptedEvents %d Entries %d AvgEntries LEDRefEntries %d LEDRefAvgEntries %d",
+                 fCalibSignal->GetNEvents(), fCalibSignal->GetNAcceptedEvents(),
+                 fCalibSignal->GetTreeAmpVsTime()->GetEntries(),
+                 fCalibSignal->GetTreeAvgAmpVsTime()->GetEntries(),
+                  fCalibSignal->GetTreeLEDAmpVsTime()->GetEntries(),
+                 fCalibSignal->GetTreeLEDAvgAmpVsTime()->GetEntries() ) );               
+  }
+  else {
+    AliWarning( Form("AliCaloCalibSignal not found!") );
+  }
+  
+  return;
+}
+
+//________________________________________________________________
+void AliEMCALCalibTimeDep::GetBiasAPDInfo() 
+{
+  // pick up Preprocessor output, based on fRun (most recent version)
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/BiasAPD", fRun);
+  if (entry) {
+    fBiasAPD = (AliEMCALBiasAPD *) entry->GetObject();
+  }
+
+  if (fBiasAPD) { 
+    AliInfo( Form("BiasAPD: NSuperModule %d ", fBiasAPD->GetNSuperModule() ) );
+  }
+  else {
+    AliWarning( Form("AliEMCALBiasAPD not found!") );
+  }
+  
+  return;
+}
+
+//________________________________________________________________
+void AliEMCALCalibTimeDep::GetCalibMapAPDInfo() 
+{
+  // pick up Preprocessor output, based on fRun (most recent version)
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/MapAPD", fRun);
+  if (entry) {
+    fCalibMapAPD = (AliEMCALCalibMapAPD *) entry->GetObject();
+  }
+
+  if (fCalibMapAPD) { 
+    AliInfo( Form("CalibMapAPD: NSuperModule %d ", fCalibMapAPD->GetNSuperModule() ) );
+  }
+  else {
+    AliWarning( Form("AliEMCALCalibMapAPD not found!") );
+  }
+  
+  return;
+}
+
+//________________________________________________________________
+void AliEMCALCalibTimeDep::GetCalibAbsInfo() 
+{
+  // pick up Preprocessor output, based on fRun (most recent version)
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("EMCAL/Calib/MapAPD", fRun);
+  if (entry) {
+    fCalibAbs = (AliEMCALCalibAbs *) entry->GetObject();
+  }
+
+  if (fCalibAbs) { 
+    AliInfo( Form("CalibAbs: NSuperModule %d ", fCalibAbs->GetNSuperModule() ) );
+  }
+  else {
+    AliWarning( Form("AliEMCALCalibAbs not found!") );
+  }
+  
+  return;
+}
+
+//________________________________________________________________
+Int_t AliEMCALCalibTimeDep::CalcLEDCorrection(Int_t nSM, Int_t nBins) 
+{// Construct normalized ratios R(t)=LED(t)/LEDRef(t), for current time T and calibration time t0 
+  // The correction factor we keep is c(T) = R(t0)/R(T)
+  // T info from fCalibSignal, t0 info from fCalibAbs
+
+  // NOTE: for now we don't use the RMS info either from fCalibSignal or fCalibAbs
+  // but one could upgrade this in the future
+  Int_t nRemaining = 0; // we count the towers for which we could not get valid data
+
+  // sanity check; same SuperModule indices for corrections as for regular calibrations
+  AliEMCALCalibAbs::AliEMCALSuperModuleCalibAbs * CalibAbsData = fCalibAbs->GetSuperModuleData();
+  AliEMCALCalibTimeDepCorrection::AliEMCALSuperModuleCalibTimeDepCorrection * CalibTimeDepCorrectionData = fCalibTimeDepCorrection->GetSuperModuleData();
+
+  for (int i = 0; i < nSM; i++) {
+    int iSMAbs = CalibAbsData[i].fSuperModuleNum;
+    int iSMCorr = CalibTimeDepCorrectionData[i].fSuperModuleNum;
+    if (iSMAbs != iSMCorr) {
+      AliWarning( Form("AliEMCALCalibTimeDep - SuperModule index mismatch: %d != %d", iSMAbs, iSMCorr) );
+      nRemaining = nSM * AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows * nBins;
+      return nRemaining;
+    }
+  }
+  int iSM = 0;
+  int iCol = 0;
+  int iRow = 0;
+  int iStrip = 0;
+  int iGain = 0;
+
+  // The fCalibSignal info is stored in TTrees
+  // Note that the time-bins for the TTree's may not exactly match with our correction time bins 
+  int timeDiff = fCalibSignal->GetStartTime() - fStartTime; // in seconds
+  // fCalibSignal time info in seconds: Hour/fkSecToHour
+  // corrected for startTime difference: Hour/fkSecToHour + timeDiff
+  // converted into a time-bin we use: (Hour + timeDiff*fkSecToHour) * fTimeBinsPerHour
+
+  // values for R(T), size of TArray = nBins
+  // the [2] dimension below is for the low or high gain 
+  TArrayF ampT[AliEMCALGeoParams::fgkEMCALModules][AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows][2]; 
+  TArrayF nT[AliEMCALGeoParams::fgkEMCALModules][AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows][2]; 
+  TArrayF ampLEDRefT[AliEMCALGeoParams::fgkEMCALModules][AliEMCALGeoParams::fgkEMCALLEDRefs][2]; 
+  TArrayF nLEDRefT[AliEMCALGeoParams::fgkEMCALModules][AliEMCALGeoParams::fgkEMCALLEDRefs][2]; 
+
+  // set up TArray's first
+  for (iSM = 0; iSM < AliEMCALGeoParams::fgkEMCALModules; iSM++) {
+    for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
+      for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+       for (iGain = 0; iGain < 2; iGain++) {
+         // length of arrays
+         ampT[iSM][iCol][iRow][iGain].Set(nBins);
+         nT[iSM][iCol][iRow][iGain].Set(nBins);
+         // content of arrys
+         for (int j = 0; j < nBins; j++) {
+           ampT[iSM][iCol][iRow][iGain].AddAt(0, j);
+           nT[iSM][iCol][iRow][iGain].AddAt(0, j);
+         }
+       }
+      }
+    }//iCol
+    for (iStrip = 0; iStrip < AliEMCALGeoParams::fgkEMCALLEDRefs; iStrip++) {
+      for (iGain = 0; iGain < 2; iGain++) {
+       // length of arrays
+       ampLEDRefT[iSM][iStrip][iGain].Set(nBins);
+       nLEDRefT[iSM][iStrip][iGain].Set(nBins);
+       // content of arrys
+       for (int j = 0; j < nBins; j++) {
+         ampLEDRefT[iSM][iStrip][iGain].AddAt(0, j);
+         nLEDRefT[iSM][iStrip][iGain].AddAt(0, j);
+       }
+      }
+    }//iStrip
+  }
+
+  // OK, now loop over the TTrees and fill the arrays needed for R(T)
+  TTree *TAvg = fCalibSignal->GetTreeAvgAmpVsTime();
+  TTree *TLEDRefAvg = fCalibSignal->GetTreeAvgAmpVsTime();
+
+  int ChannelNum; // for regular towers
+  int RefNum; // for LED
+  double Hour;
+  double AvgAmp;
+
+  TAvg->SetBranchAddress("fChannelNum", &ChannelNum);
+  TAvg->SetBranchAddress("fHour", &Hour);
+  TAvg->SetBranchAddress("fAvgAmp",&AvgAmp);
+
+  int iBin = 0;
+  // counters for how many values were seen per SuperModule
+  int nCount[AliEMCALGeoParams::fgkEMCALModules] = {0};
+  int nCountLEDRef[AliEMCALGeoParams::fgkEMCALModules] = {0};
+
+  for (int ient=0; ient<TAvg->GetEntries(); ient++) {
+    TAvg->GetEntry(ient);
+    // figure out where this info comes from
+    fCalibSignal->DecodeChannelNum(ChannelNum, &iSM, &iCol, &iRow, &iGain);
+    iBin = (int) ( (Hour + timeDiff*fkSecToHour) * fTimeBinsPerHour  ); // CHECK!!!
+    // add value in the arrays
+    ampT[iSM][iCol][iRow][iGain].AddAt( ampT[iSM][iCol][iRow][iGain].At(iBin)+AvgAmp, iBin );
+    nT[iSM][iCol][iRow][iGain].AddAt( nT[iSM][iCol][iRow][iGain].At(iBin)+1, iBin );
+    nCount[iSM]++;
+  }
+
+  TLEDRefAvg->SetBranchAddress("fRefNum", &RefNum);
+  TLEDRefAvg->SetBranchAddress("fHour", &Hour);
+  TLEDRefAvg->SetBranchAddress("fAvgAmp",&AvgAmp);
+
+  for (int ient=0; ient<TLEDRefAvg->GetEntries(); ient++) {
+    TLEDRefAvg->GetEntry(ient);
+    // figure out where this info comes from
+    fCalibSignal->DecodeRefNum(RefNum, &iSM, &iStrip, &iGain);
+    iBin = (int) ( (Hour + timeDiff*fkSecToHour) * fTimeBinsPerHour  ); // CHECK!!!
+    // add value in the arrays
+    ampLEDRefT[iSM][iStrip][iGain].AddAt( ampLEDRefT[iSM][iStrip][iGain].At(iBin)+AvgAmp, iBin );
+    nLEDRefT[iSM][iStrip][iGain].AddAt( nLEDRefT[iSM][iStrip][iGain].At(iBin)+1, iBin );
+    nCountLEDRef[iSM]++;
+  }
+
+  // Normalize TArray values, and calculate average also
+  Float_t norm = 0; // extra var, for readability
+
+  for (iSM = 0; iSM < AliEMCALGeoParams::fgkEMCALModules; iSM++) {
+    if (nCount[iSM]>0 && nCountLEDRef[iSM]>0) { // avoid SuperModules with no data..
+      for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
+       //      iStrip = AliEMCALGeoParams::GetStripModule(iSM, iCol);
+       iStrip = (iSM%2==0) ? iCol/2 : AliEMCALGeoParams::fgkEMCALLEDRefs - 1 - iCol/2; //TMP, FIXME
+       for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+         for (iGain = 0; iGain < 2; iGain++) {
+           // content of arrys
+           for (int j = 0; j < nBins; j++) {
+             if (nT[iSM][iCol][iRow][iGain].At(j) > 0) { 
+               norm = ampT[iSM][iCol][iRow][iGain].At(j) / nT[iSM][iCol][iRow][iGain].At(j); 
+               ampT[iSM][iCol][iRow][iGain].AddAt(norm, j); // AddAt = SetAt
+             } 
+           }
+         }
+       }
+      }//iCol
+      for (iStrip = 0; iStrip < AliEMCALGeoParams::fgkEMCALLEDRefs; iStrip++) {
+       for (iGain = 0; iGain < 2; iGain++) {
+         for (int j = 0; j < nBins; j++) {
+           if (nLEDRefT[iSM][iStrip][iGain].At(j) > 0) {
+             norm = ampLEDRefT[iSM][iStrip][iGain].At(j) / nLEDRefT[iSM][iStrip][iGain].At(j); 
+             ampLEDRefT[iSM][iStrip][iGain].AddAt(norm, j); // AddAt = SetAt
+           }
+         }
+       }
+      }//iStrip
+    }
+  } // iSM
+
+
+  // Calculate correction values, and store them
+  // set fkErrorCode values for those that could not be set
+
+  Float_t Rt0 = 0;
+  Float_t RT = 0;
+  Float_t correction = 0; // c(T) = R(t0)/R(T)
+  Int_t refGain = 0; // typically use low gain for LED reference amplitude (high gain typically well beyond saturation)
+
+  for (int i = 0; i < nSM; i++) {
+    iSM = CalibAbsData[i].fSuperModuleNum;
+    for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
+      //      iStrip = AliEMCALGeoParams::GetStripModule(iSM, iCol);
+      iStrip = (iSM%2==0) ? iCol/2 : AliEMCALGeoParams::fgkEMCALLEDRefs - 1 - iCol/2; //TMP, FIXME
+      for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+
+       // Calc. R(t0):
+       AliEMCALCalibAbs::AliEMCALCalibAbsVal &v = CalibAbsData[i].fAPDVal[iCol][iRow];
+       iGain = v.fHighLow; // gain value used for abs. calibration     
+       refGain = CalibAbsData[i].fLEDRefHighLow[iStrip]; // LED reference gain value used for abs. calibration 
+
+       // valid amplitude values should be larger than 0
+       if (v.fLEDAmp>0 && CalibAbsData[i].fLEDRefAmp[iStrip]>0) {
+         Rt0 =  v.fLEDAmp / CalibAbsData[i].fLEDRefAmp[iStrip];
+       }
+       else {
+         Rt0 = fkErrorCode;
+       }
+
+       // Cal R(T)
+       for (int j = 0; j < nBins; j++) {
+
+         // calculate R(T) also; first try with individual tower:
+         // same gain as for abs. calibration is the default
+         if (ampT[iSM][iCol][iRow][iGain].At(j)>0 && ampLEDRefT[iSM][iStrip][refGain].At(j)>0) {
+           // looks like valid data with the right gain combination
+           RT = ampT[iSM][iCol][iRow][iGain].At(j) / ampLEDRefT[iSM][iStrip][refGain].At(j); 
+
+           // if data appears to be saturated, and we are in high gain, then try with low gain instead
+           if ( (ampT[iSM][iCol][iRow][iGain].At(j)>AliEMCALGeoParams::fgkOverflowCut && iGain==1) ||
+                (ampLEDRefT[iSM][iStrip][refGain].At(j)>AliEMCALGeoParams::fgkOverflowCut && refGain==1) ) { // presumably the gains should then both be changed.. can look into possibly only changing one in the future
+             RT = ampT[iSM][iCol][iRow][0].At(j) / ampLEDRefT[iSM][iStrip][0].At(j); 
+             RT *= v.fHighLowRatio/CalibAbsData[i].fLEDRefHighLowRatio[iStrip]; // compensate for using different gain than in the absolute calibration
+           }
+         }
+         else {
+           RT = fkErrorCode;
+         }
+
+         // Calc. correction factor
+         if (Rt0>0 && RT>0) { 
+           correction = Rt0/RT;
+         }
+         else {
+           correction = fkErrorCode;
+           nRemaining++;
+         }
+
+         // Store the value
+         CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].AddAt(correction, j);
+         /* Check that
+         fTimeDepCorrection->SetCorrection(i, iCol, iRow, j, correction);
+         also works OK */
+       } // nBins
+      }
+    }
+  }
+
+  nRemaining = CalcLEDCorrectionStripBasis(nSM, nBins);
+  return nRemaining;
+}
+
+//________________________________________________________________
+Int_t AliEMCALCalibTimeDep::CalcLEDCorrectionStripBasis(Int_t nSM, Int_t nBins) 
+{ // use averages for each strip if no good values exist for some single tower 
+
+  // go over fTimeDepCorrection info
+  Int_t nRemaining = 0; // we count the towers for which we could not get valid data
+
+  AliEMCALCalibTimeDepCorrection::AliEMCALSuperModuleCalibTimeDepCorrection * CalibTimeDepCorrectionData = fCalibTimeDepCorrection->GetSuperModuleData();
+
+  // for calculating StripAverage info
+  int nValidTower = 0;
+  Float_t StripAverage = 0;
+  Float_t val = 0;
+
+  int iSM = 0;
+  int iCol = 0;
+  int iRow = 0;
+  int iStrip = 0;
+  int firstCol = 0;
+  int lastCol = 0;
+
+  for (int i = 0; i < nSM; i++) {
+    iSM = CalibTimeDepCorrectionData[i].fSuperModuleNum;
+    for (int j = 0; j < nBins; j++) {
+
+      nValidTower = 0;
+      StripAverage = 0;
+
+      for (iStrip = 0; iStrip < AliEMCALGeoParams::fgkEMCALLEDRefs; iStrip++) {
+       firstCol = iStrip*2;
+       if ((iSM%2)==1) { // C side
+         firstCol = (AliEMCALGeoParams::fgkEMCALLEDRefs-1 - iStrip)*2;
+       }
+       lastCol = firstCol+1;
+
+       for (iCol = firstCol; iCol <= lastCol; iCol++) {
+         for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+           val = CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].At(j);
+           if (val>0) { // valid value; error code is negative
+             StripAverage += val;
+             nValidTower++;
+           } 
+         }
+       }
+
+       // calc average over strip
+       if (nValidTower>0) {
+         StripAverage /= nValidTower;
+         for (iCol = firstCol; iCol <= lastCol; iCol++) {
+           for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+             val = CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].At(j);
+             if (val<0) { // invalid value; error code is negative
+               CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].AddAt(val, j);
+             }
+           }
+         }
+       }
+       else { // could not fill in unvalid entries
+         nRemaining += 2*AliEMCALGeoParams::fgkEMCALRows;
+       }
+
+      } // iStrip
+    } // j, bins
+  } // iSM
+
+  return nRemaining;
+}
+
+//________________________________________________________________
+Int_t AliEMCALCalibTimeDep::CalcTemperatureCorrection(Int_t nSM, Int_t nBins) 
+{ // 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
+  // based on that instead.
+  // For this, we'll need the info from 3 classes (+temperature array), and output the values in a 4th class 
+  Int_t nRemaining = 0;
+
+  // info containers
+  AliEMCALBiasAPD::AliEMCALSuperModuleBiasAPD * BiasAPDData = fBiasAPD->GetSuperModuleData();
+  AliEMCALCalibMapAPD::AliEMCALSuperModuleCalibMapAPD * CalibMapAPDData = fCalibMapAPD->GetSuperModuleData();
+  AliEMCALCalibAbs::AliEMCALSuperModuleCalibAbs * CalibAbsData = fCalibAbs->GetSuperModuleData();
+  // correction container
+  AliEMCALCalibTimeDepCorrection::AliEMCALSuperModuleCalibTimeDepCorrection * CalibTimeDepCorrectionData = fCalibTimeDepCorrection->GetSuperModuleData();
+
+  int iSM = 0;
+  int iCol = 0;
+  int iRow = 0;
+
+  Double_t TempCoeff[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows];
+  memset(TempCoeff, 0, sizeof(TempCoeff));
+  Float_t MGain = 0; 
+  Double_t correction = 0;
+  Double_t secondsPerBin = (1/fkSecToHour)*(1/fTimeBinsPerHour);
+
+  for (int i = 0; i < nSM; i++) {
+    iSM = CalibTimeDepCorrectionData[i].fSuperModuleNum;
+    
+    // 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++) {
+       AliEMCALCalibMapAPD::AliEMCALCalibMapAPDVal &mapAPD = CalibMapAPDData[i].fAPDVal[iCol][iRow];
+       MGain =  fCalibMapAPD->GetGain(mapAPD.fPar[0], mapAPD.fPar[1], mapAPD.fPar[2], 
+                                      BiasAPDData[i].fVoltage[iCol][iRow]);
+       TempCoeff[iCol][iRow] = GetTempCoeff(mapAPD.fDarkCurrent, MGain);
+      }
+    }
+    
+    // figure out what the reference temperature is, from fCalibAbs
+    Double_t ReferenceTemperature = 0;
+    int nVal = 0;
+    for (int iSensor = 0; iSensor<AliEMCALGeoParams::fgkEMCALTempSensors ; iSensor++) {
+      if (CalibAbsData[i].fTemperature[iSensor]>0) { // hopefully OK value
+       ReferenceTemperature += CalibAbsData[i].fTemperature[iSensor];
+       nVal++;
+      }
+    }
+    
+    if (nVal>0) {
+      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 SMTemperature = GetTemperatureSM(iSM, timeStamp); 
+
+       Double_t TemperatureDiff = ReferenceTemperature - SMTemperature; // old vs new
+       // if the new temperature is higher than the old/reference one, then the gain has gone down 
+       if (fabs(TemperatureDiff)>fTemperatureResolution) { 
+         // significant enough difference that we need to consider it
+
+         // loop over all towers; effect of temperature change will depend on gain for this tower
+         for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
+           for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+
+             correction = TemperatureDiff * TempCoeff[iCol][iRow];
+             CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].AddAt(correction, j);
+           }
+         }
+
+       } // if noteworthy temperature change
+       else { // just set correction values to 1.0
+         correction = 1;
+         for (iCol = 0; iCol < AliEMCALGeoParams::fgkEMCALCols; iCol++) {
+           for (iRow = 0; iRow < AliEMCALGeoParams::fgkEMCALRows; iRow++) {
+             CalibTimeDepCorrectionData[i].fCorrection[iCol][iRow].AddAt(correction, j);
+           }
+         }
+       } // else
+      } // j, Bins
+
+    } // if reference temperature exist 
+    else { // could not do the needed check.. signal that in the return code
+      nRemaining += AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows * nBins;
+    }
+  } // iSM
+
+  return nRemaining;
+}
+
index 7074515..ed7b0d8 100644 (file)
 #include "TObject.h"
 
 class AliEMCALSensorTempArray;
+class AliCaloCalibSignal;
+class AliEMCALBiasAPD;
+class AliEMCALCalibMapAPD;
+class AliEMCALCalibAbs; // absolute = time-independent
+class AliEMCALCalibTimeDepCorrection; 
 
 class AliEMCALCalibTimeDep : public TObject {
 
@@ -25,50 +30,89 @@ class AliEMCALCalibTimeDep : public TObject {
 
   void Initialize(Int_t run, UInt_t startTime, UInt_t endTime);//!
 
+  // simple getters
+  Int_t GetRunNumber() const { return fRun; } //
+  Int_t GetStartTime() const { return fStartTime; } // 
+  Int_t GetEndTime() const { return fEndTime; } // 
+  Double_t GetLengthOfRunInHours() const; // 
+  Double_t GetLengthOfRunInBins() const; // 
+
+  // Temperature Section
   // access pointer to the basic temperature object: AliEMCALSensorTempArray 
   AliEMCALSensorTempArray  * GetTempArray() const { return fTempArray; } //
 
-  // simple getters
-  int GetRunNumber() const { return fRun; } //
-  int GetStartTime() const { return fStartTime; } // 
-  int GetEndTime() const { return fEndTime; } // 
-  double GetLengthOfRunInHours() const; // 
-
   // range of temperature readings/values during the run 
-  double GetMinTemp() const { return fMinTemp; } // 
-  double GetMaxTemp() const { return fMaxTemp; } // 
-  int GetMinTime() const { return fMinTime; } // 
-  int GetMaxTime() const { return fMaxTime; } // 
-  double GetRangeOfTempMeasureInHours() const; // 
-  double GetRangeOfTempMeasureInDegrees() const; // 
-
-  // reference temperature, that we normalize to
-  double GetRefTemp() const { return fRefTemp; } //
-  void SetRefTemp(double refTemp) { fRefTemp = refTemp; } //
+  Int_t ScanTemperatureInfo(); // go through the temperature info
+  Double_t GetMinTemp() const { return fMinTemp; } // 
+  Double_t GetMaxTemp() const { return fMaxTemp; } // 
+  UInt_t GetMinTime() const { return fMinTime; } // 
+  UInt_t GetMaxTime() const { return fMaxTime; } // 
+  Double_t GetRangeOfTempMeasureInHours() const; // 
+  Double_t GetRangeOfTempMeasureInDegrees() const; // 
 
   // basic calibration info
-  double GetTemperature(UInt_t timeStamp) const; // for all sensors, all SuperModules
-  double GetTemperatureSM(int imod, UInt_t timeStamp) const; // for all sensors, in a SuperModule
-  double GetTemperatureSMSensor(int imod, int isens, UInt_t timeStamp) const; // for a sensor, in a SuperModule
-  double GetCorrection(double temperature) const; //
+  Double_t GetTemperature(UInt_t timeStamp) const; // for all sensors, all SuperModules
+  Double_t GetTemperatureSM(int imod, UInt_t timeStamp) const; // for all sensors, in a SuperModule
+  Double_t GetTemperatureSMSensor(int imod, int isens, UInt_t timeStamp) const; // for a sensor, in a SuperModule
+  // End of Temperature Section
+
+  // control parameters
+  void SetTemperatureResolution(Double_t d) { fTemperatureResolution = d; } // value for checking at which level we care about temperature differences
+  void SetTimeBinsPerHour(Int_t i) { fTimeBinsPerHour = i; } // size of the time-bins we use for corrections
+  Double_t GetTemperatureResolution() const { return fTemperatureResolution; } // value for checking at which level we care about temperature differences
+  Int_t GetTimeBinsPerHour() const { return fTimeBinsPerHour; } // size of the time-bins we use foc corrections
+
+  // access to other pointers
+  AliCaloCalibSignal  * GetCalibSignal() const { return fCalibSignal; } //
+  AliEMCALBiasAPD  * GetBiasAPD() const { return fBiasAPD; } //
+  AliEMCALCalibMapAPD  * GetCalibMapAPD() const { return fCalibMapAPD; } //
+  AliEMCALCalibAbs  * GetCalibAbs() const { return fCalibAbs; } //
+  AliEMCALCalibTimeDepCorrection  * GetCalibTimeDepCorrection() const { return fCalibTimeDepCorrection; } //
+
+  // storage and access of the correction info
+  Int_t CalcCorrection(); //
+  AliEMCALCalibTimeDepCorrection  * GetTimeDepCorrection() 
+    const { return fCalibTimeDepCorrection; } //
+
+  Double_t GetTempCoeff(Double_t IDark, Double_t M) const; //
 
  private:
 
-  void Reset();
+  void Reset(); //
+
   void GetTemperatureInfo(); // pick up Preprocessor output
+  void GetCalibSignalInfo(); // pick up Preprocessor output
+  void GetBiasAPDInfo(); // pick up OCDB info
+  void GetCalibMapAPDInfo(); // pick up OCDB info
+  void GetCalibAbsInfo(); // pick up OCDB info
+
+  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 fRun;
-  int fStartTime;
-  int fEndTime;
-  double fMinTemp;
-  double fMaxTemp;
-  int fMinTime;
-  int fMaxTime;
-  double fRefTemp;
+  Int_t fRun;
+  UInt_t fStartTime;
+  UInt_t fEndTime;
+  // temperature stuff
+  Double_t fMinTemp;
+  Double_t fMaxTemp;
+  UInt_t fMinTime;
+  UInt_t fMaxTime;
   //
+  Double_t fTemperatureResolution; // value for checking at which level we care about temperature differences
+  Int_t fTimeBinsPerHour; // size of the time-bins we use for corrections
+
+  // pointers to the different used classes
   AliEMCALSensorTempArray  *fTempArray;     // CDB class for temperature sensors
+  AliCaloCalibSignal *fCalibSignal; //
+  AliEMCALBiasAPD *fBiasAPD; //
+  AliEMCALCalibMapAPD *fCalibMapAPD; //
+  AliEMCALCalibAbs *fCalibAbs; // absolute = time-independent
+  AliEMCALCalibTimeDepCorrection *fCalibTimeDepCorrection; // 
+
   //
-  ClassDef(AliEMCALCalibTimeDep,1)    // EMCAL Calibration data
+  ClassDef(AliEMCALCalibTimeDep,2)    // EMCAL Calibration data
 };
 
 #endif
diff --git a/EMCAL/AliEMCALCalibTimeDepCorrection.cxx b/EMCAL/AliEMCALCalibTimeDepCorrection.cxx
new file mode 100644 (file)
index 0000000..03259ab
--- /dev/null
@@ -0,0 +1,226 @@
+/**************************************************************************
+ * 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: $ */
+
+// Objects of this class contain info on APD bias settings/voltages
+//
+
+#include <fstream>
+#include <TString.h>
+#include <TArrayF.h>
+
+#include "AliEMCALCalibTimeDepCorrection.h"
+
+using namespace std;
+
+ClassImp(AliEMCALCalibTimeDepCorrection)
+
+//____________________________________________________________________________
+AliEMCALCalibTimeDepCorrection::AliEMCALCalibTimeDepCorrection() : 
+  fNSuperModule(0),
+  fSuperModuleData(0)
+{
+  //Default constructor.
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibTimeDepCorrection::InitCorrection(Int_t nSM, Int_t nBins, Float_t val=1.0)
+{
+  // This methods assumes that you are using SuperModules 0..nSM-1
+  fNSuperModule = nSM;
+  if (fSuperModuleData) delete [] fSuperModuleData;
+  fSuperModuleData = new AliEMCALSuperModuleCalibTimeDepCorrection[fNSuperModule];
+
+  Int_t iSM = 0; // SuperModule index
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t nCorr = nBins;
+  Float_t Correction = val;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibTimeDepCorrection &t = fSuperModuleData[i];
+    t.fSuperModuleNum = iSM; // assume SMs are coming in order
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+
+      // set size of TArray
+      t.fCorrection[iCol][iRow].Set(nCorr);
+      for (Int_t k=0; k<nCorr; k++) {
+       // add to TArray
+       t.fCorrection[iCol][iRow].AddAt(Correction, k); // AddAt = SetAt..
+      }
+    }
+
+  } // i, SuperModule
+
+  return;
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibTimeDepCorrection::SetCorrection(Int_t supModIndex, Int_t iCol, Int_t iRow, Int_t iBin, Float_t val)
+{ // if you call for non-existing data, there may be a crash..
+  fSuperModuleData[supModIndex].fCorrection[iCol][iRow].AddAt(val, iBin); // AddAt = SetAt..
+ return; 
+}
+
+//____________________________________________________________________________
+Float_t AliEMCALCalibTimeDepCorrection::GetCorrection(Int_t supModIndex, Int_t iCol, Int_t iRow, Int_t iBin)const
+{ // if you call for non-existing data, there may be a crash..
+  return fSuperModuleData[supModIndex].fCorrection[iCol][iRow].At(iBin);
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibTimeDepCorrection::ReadCalibTimeDepCorrectionInfo(Int_t nSM, const TString &txtFileName,
+                                                                   Bool_t swapSides)
+{
+  //Read data from txt file. ; coordinates given on SuperModule basis
+
+  std::ifstream inputFile(txtFileName.Data());
+  if (!inputFile) {
+    printf("AliEMCALCalibTimeDepCorrection::ReadCalibTimeDepCorrectionInfo - Cannot open the APD info file %s\n", txtFileName.Data());
+    return;
+  }
+
+  fNSuperModule = nSM;
+  if (fSuperModuleData) delete [] fSuperModuleData;
+  fSuperModuleData = new AliEMCALSuperModuleCalibTimeDepCorrection[fNSuperModule];
+
+  Int_t iSM = 0; // SuperModule index
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t nCorr = 0;
+  Float_t Correction = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibTimeDepCorrection &t = fSuperModuleData[i];
+    if (!inputFile) {
+      printf("AliEMCALCalibTimeDepCorrection::ReadCalibTimeDepCorrectionInfo - Error while reading input file; likely EOF..");
+      return;
+    }
+    inputFile >> iSM;
+    t.fSuperModuleNum = iSM;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      inputFile >> iCol >> iRow >> nCorr;
+
+      // assume that this info is already swapped and done for this basis?
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      // set size of TArray
+      t.fCorrection[iCol][iRow].Set(nCorr);
+      for (Int_t k=0; k<nCorr; k++) {
+       inputFile >> Correction;
+       // add to TArray
+       t.fCorrection[iCol][iRow].AddAt(Correction, k);
+      }
+    }
+
+  } // i, SuperModule
+
+  inputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+void AliEMCALCalibTimeDepCorrection::WriteCalibTimeDepCorrectionInfo(const TString &txtFileName,
+                                                                    Bool_t swapSides)
+{
+  // write data to txt file. ; coordinates given on SuperModule basis
+
+  std::ofstream outputFile(txtFileName.Data());
+  if (!outputFile) {
+    printf("AliEMCALCalibTimeDepCorrection::WriteCalibTimeDepCorrectionInfo - Cannot open the APD output file %s\n", txtFileName.Data());
+    return;
+  }
+
+  Int_t iCol = 0;
+  Int_t iRow = 0;
+  Int_t nCorr = 0;
+
+  Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
+
+  for (Int_t i = 0; i < fNSuperModule; i++) {
+    AliEMCALSuperModuleCalibTimeDepCorrection &t = fSuperModuleData[i];
+    outputFile << t.fSuperModuleNum << endl;
+
+    for (Int_t j=0; j<nAPDPerSM; j++) {
+      iCol = j / AliEMCALGeoParams::fgkEMCALRows;
+      iRow = j % AliEMCALGeoParams::fgkEMCALRows;
+
+      nCorr = t.fCorrection[iCol][iRow].GetSize();
+
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
+       iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
+      }
+
+      outputFile << iCol << " " << iRow << " " << nCorr << endl;
+      for (Int_t k=0; k<nCorr; k++) {
+       outputFile << t.fCorrection[iCol][iRow].At(k) << " ";
+      }
+      outputFile << endl;
+
+    }
+
+  } // i, SuperModule
+
+  outputFile.close();
+
+  return;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibTimeDepCorrection::~AliEMCALCalibTimeDepCorrection()
+{
+  delete [] fSuperModuleData;
+}
+
+//____________________________________________________________________________
+AliEMCALCalibTimeDepCorrection::AliEMCALSuperModuleCalibTimeDepCorrection AliEMCALCalibTimeDepCorrection::GetSuperModuleCalibTimeDepCorrectionId(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibTimeDepCorrection t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  return fSuperModuleData[supModIndex];
+}
+
+//____________________________________________________________________________
+AliEMCALCalibTimeDepCorrection::AliEMCALSuperModuleCalibTimeDepCorrection AliEMCALCalibTimeDepCorrection::GetSuperModuleCalibTimeDepCorrectionNum(Int_t supModIndex)const
+{
+  AliEMCALSuperModuleCalibTimeDepCorrection t;  // just to maybe prevent a crash, but we are returning something not-initialized so maybe not better really..
+  if (!fSuperModuleData)
+    return t;
+
+  for (int i=0; i<fNSuperModule; i++) {
+    if (fSuperModuleData[i].fSuperModuleNum == supModIndex) {
+      return fSuperModuleData[i];
+    }
+  }
+
+  return t;
+}
+
diff --git a/EMCAL/AliEMCALCalibTimeDepCorrection.h b/EMCAL/AliEMCALCalibTimeDepCorrection.h
new file mode 100644 (file)
index 0000000..8ffa26a
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef ALIEMCALCALIBTIMEDEPCORRECTION_H
+#define ALIEMCALCALIBTIMEDEPCORRECTION_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: $ */
+
+#include <TObject.h>
+#include "AliEMCALGeoParams.h"
+class TString;
+class TArrayF;
+
+/*
+  Objects of this class read txt file with APD data
+  AliEMCALCalibTimeDepCorrection inherits TObject only to use AliLog "functions".
+*/
+
+class AliEMCALCalibTimeDepCorrection : public TObject {
+public:
+  AliEMCALCalibTimeDepCorrection();
+
+  // interface methods; getting the whole struct should be more efficient though
+  void InitCorrection(Int_t nSM, Int_t nBins, Float_t val); // assign a certain value to all 
+  // use the methods below with caution: take care that your argument ranges are valid
+  void SetCorrection(Int_t smIndex, Int_t iCol, Int_t iRow, Int_t iBin, Float_t val=1.0); // assign a certain value to a given bin
+  Float_t GetCorrection(Int_t smIndex, Int_t iCol, Int_t iRow, Int_t iBin) const; // assign a certain value to a given bin
+
+  // Read and Write txt I/O methods are normally not used, but are useful for 
+  // filling the object before it is saved in OCDB 
+  void ReadCalibTimeDepCorrectionInfo(Int_t nSM, const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  void WriteCalibTimeDepCorrectionInfo(const TString &txtFileName, Bool_t swapSides=kFALSE); // info file is for nSm=1 to 12 SuperModules
+
+  virtual ~AliEMCALCalibTimeDepCorrection();
+
+  struct AliEMCALSuperModuleCalibTimeDepCorrection {
+    Int_t fSuperModuleNum;
+    TArrayF fCorrection[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
+  };
+
+  // pointer to stored info.
+  Int_t GetNSuperModule() const { return fNSuperModule; }; 
+  AliEMCALSuperModuleCalibTimeDepCorrection * GetSuperModuleData() const { return fSuperModuleData; };
+
+  // - via the index in the stored array:
+  virtual AliEMCALSuperModuleCalibTimeDepCorrection GetSuperModuleCalibTimeDepCorrectionId(Int_t smIndex) const;
+  // - or via the actual SM number
+  virtual AliEMCALSuperModuleCalibTimeDepCorrection GetSuperModuleCalibTimeDepCorrectionNum(Int_t smNum) const;
+
+protected:
+
+  Int_t          fNSuperModule; // Number of supermodules.
+  AliEMCALSuperModuleCalibTimeDepCorrection *fSuperModuleData; // SuperModule data
+
+private:
+
+  AliEMCALCalibTimeDepCorrection(const AliEMCALCalibTimeDepCorrection &);
+  AliEMCALCalibTimeDepCorrection &operator = (const AliEMCALCalibTimeDepCorrection &);
+
+  ClassDef(AliEMCALCalibTimeDepCorrection, 1) //
+};
+
+#endif
diff --git a/EMCAL/SMcalib/WriteOCDBCalibMapAPD.C b/EMCAL/SMcalib/WriteOCDBCalibMapAPD.C
new file mode 100644 (file)
index 0000000..6645ca0
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+*/
+// from AliEMCALGeoParams.h
+static const int fgkEMCALRows = 24; // number of rows per module for EMCAL
+static const int fgkEMCALCols = 48; // number of columns per module for EMCAL
+
+//____________________________________________________________________
+void WriteOCDBCalibMapAPD(const char * inputDBName, const char * inputMapName,
+                         const char * outputFileName, const int swapSides) 
+{ 
+
+  gSystem->Load("AliEMCALCalibAPD_cxx");
+  AliEMCALCalibAPD *calibAPD = new AliEMCALCalibAPD();
+
+  calibAPD->ReadCalibAPDInfo(10000, inputDBName);
+  int fNCalibAPD = calibAPD->GetNCalibAPD();
+  AliEMCALCalibAPD::AliEMCALCalibAPDData * fCalib = calibAPD->GetCalibAPDData();
+
+  gSystem->Load("AliEMCALMapAPD_cxx");
+  AliEMCALMapAPD *mapAPD = new AliEMCALMapAPD();
+
+  // assume we do this for one SuperModule at a time; can merge the 
+  // output files with 'cat' or so separately 
+  int nSM = 1;
+  mapAPD->ReadMapAPDInfo(nSM, inputMapName);
+  AliEMCALMapAPD::AliEMCALSuperModuleMapAPD * fMap = mapAPD->GetSuperModuleData();
+
+  // set up ouput file
+  ofstream outputFile(outputFileName);
+
+  // let's loop over the files..
+  int nFound = 0;
+  int nNotFound = 0;
+  int iCol = 0; 
+  int iRow = 0;
+  for (int icol=0; icol<fgkEMCALCols; icol++) {
+    for (int irow=0; irow<fgkEMCALRows; irow++) {
+      iCol = icol;
+      iRow = irow;
+      if (swapSides) {
+       // C side, oriented differently than A side: swap is requested
+       iCol = fgkEMCALCols-1 - iCol;
+       iRow = fgkEMCALRows-1 - iRow;
+      }
+
+      int apdMap = fMap[0].fAPDNum[icol][irow]; // 0 = nSM - 1
+      int i = 0;
+      int apdCalib = -1;
+      while (i<fNCalibAPD && apdMap!=apdCalib) {
+       apdCalib = fCalib[i].fAPDNum;
+       i++;
+      }
+
+      if (apdCalib == apdMap) { // found!
+       i--; // go back to what we found
+
+       // should also calculate the HardWare Id.. note that the functionality
+       // of the Tower2FEEMap and GetHardWareId calls have not been tested here..
+       
+       int ircu, ibranch, card, icsp;
+       Tower2FEEMap(icol, irow, &ircu, &ibranch, &card, &icsp);
+       int iHW = GetCSPAddress(ibranch, card, icsp);
+       iHW |= (ircu << 12); // RCU not part of normal HW addresses, but we add an extra bit for it here, just in case it might be useful
+
+       // print some info..
+       outputFile << iCol << " " << iRow << " " << iHW 
+                  << " " << fCalib[i].fAPDNum << " " << fCalib[i].fV30 
+                  << " " << fCalib[i].fPar[0] << " " << fCalib[i].fPar[1] << " " << fCalib[i].fPar[2]
+                  << " " << fCalib[i].fParErr[0] << " " << fCalib[i].fParErr[1] << " " << fCalib[i].fParErr[2]
+                  << " " << fCalib[i].fBreakDown << " " << fCalib[i].fDarkCurrent << endl;
+       
+       nFound++;
+      }
+      else {
+       cout << " APD " << apdMap << " could not be found! " << endl;
+       // print some dummy info
+       nNotFound++;
+      }
+
+    }
+  }
+
+  cout << " found " << nFound << " matches " << endl;
+  cout << " did not find " << nNotFound << " APDs " << endl;
+
+  // close down
+  outputFile.close();
+}
+
+// from AliEMCALGeoParams.h:
+Int_t GetCSPAddress(Int_t iBranch, Int_t iFEC, Int_t iCSP) const
+{ return ( (iBranch<<11) | (iFEC<<7) | iCSP ); }; // 
+
+// from DCSGenerateAPD.C; the method assumes that the columns and rows
+// are labelled as we have them on the A side (normal case for calibrations
+// before the installation)
+const int NRCU = 2; // per SM
+const int NBranch = 2; // per RCU
+const int NFEC = 9; // per branch, labelled 1..9
+const int NCSP = 32; // per FEC
+
+void Tower2FEEMap(const int icol, const int irow,
+                  int *ircu, int *ibranch, int *card, int *icsp)
+{ /*
+    If you are interested in where these magic numbers come from -
+    See mapping info on
+    http://dsilverm.web.cern.ch/dsilverm/mapping/emcal_mapping.html
+    http://dsilverm.web.cern.ch/dsilverm/mapping/ppt/Coordinates_and_Mapping.pdf   */
+  
+  // each FEC covers a 4x8 tower area
+  int C = irow/8; // Cable bundle
+  int FEC = C*12 + icol/4; // FEC in 0..35 range
+  
+  *ircu = FEC / 18; // 18 FEC per RCU
+  *ibranch = (FEC%18) / 9;
+  *card = FEC % 9;
+  
+  // columns and rows within an FEC area
+  int tCol = icol%4;
+  int tRow = irow%8;
+  
+  // The mapping to CSP is a bit complicated so I also define two more help variables here..
+  // which T-card?
+  int TCard = tCol/2; // 0=Top (even StripModules), 1=Bottom (odd StripModules)
+  int locCol = tCol%2;  // local column inside T-card
+  
+  *icsp = (7 - tRow) + locCol*16 + TCard*8;
+}
index 1db0b8a..d5cd5a8 100644 (file)
@@ -25,6 +25,10 @@ AliEMCALRecParam.cxx \
 AliEMCALQAChecker.cxx \
 AliEMCALSpaceFrame.cxx \
 AliEMCALSTURawStream.cxx \
+AliEMCALBiasAPD.cxx \
+AliEMCALCalibMapAPD.cxx \
+AliEMCALCalibAbs.cxx \
+AliEMCALCalibTimeDepCorrection.cxx \
 SMcalib/AliEMCALCCUSBRawStream.cxx