ROOT logo
#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TMath.h>
#include <TH1.h>
#include <TH2.h>
#include <TF1.h>
#include <TProfile.h>
#include <TSpline.h>
#include <TCanvas.h>
#include <TStyle.h>
#include <TFile.h>
#include <TGrid.h>
#include <TGraphErrors.h>
#include <TSystem.h>
#include <TLatex.h>
#include <TMinuit.h>
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBStorage.h"
#include "AliITSsegmentationSDD.h"
#include "AliITSCorrMapSDD.h"
#include "AliITSCorrMap1DSDD.h"
#include "AliITSDriftSpeedArraySDD.h"
#include "AliITSDriftSpeedSDD.h"
#include "AliITSresponseSDD.h"
#endif

Bool_t verbose = kFALSE;

/*
  // master equations
  DeltaX_L = -deltaX + deltaV_L*(T_L - T0_true - deltaT0) - V_Ltrue*deltaT0 - corrMapL
  DeltaX_R =  deltaX + deltaV_R*(T_R - T0_true - deltaT0) - V_Rtrue*deltaT0 - corrMapR
  //
  
  where 
  corrMapL(R) : Vdrift vs X nonuniformity correction maps
  V_L(R)true: true drift speed
  deltaV_L(R) : error in drift speed
  V_Ltrue = V_Lassumed - deltaV_L
  V_Rtrue = V_Rassumed - deltaV_R
  //
  DeltaX :  measured residuals (track extrapolation - measurement) for left (L) 
  and right (R) sides (right side multiplied by -1!!!)
  deltaX : misalignment of module (Xtrue = Xassumed - deltaX)
  T_L(R)    : measured drift time (w/o T0 subtraction)
  T0_true   : real T0 
  deltaT0   : error in T0
*/

//------------------- Details of CDB objects to create ---------------
int firstRun = -1;
int lastRun  = -1;
TString cdbComment = "";
//--------------------------------------------------------------------

const Int_t kSDDMin=240,kSDDMax=499,kNSDD=kSDDMax-kSDDMin+1;
enum {kSXvsX,kSXvsZ,kSTDvsX,kSTDvsZ,kSDXvsXclean,kSVDvsX,kSCorrMapX,kSXvsXCorr,kSXvsZCorr,kSDVvsZ,kSDVvsZOrig,kSGrDxx,kSGrTDx,kSGrTXCorr, kNStore};
const Int_t maxVZOrd    = 4;            // max order of polinomial for VD vs Z correction (normal sensors)
const Double_t chi2BadVZ = 2.9;         // treat as bad module if chi2/ndf is worse
//
enum {kDxX,kDxZ,kTDX,kTDZ,kNQATypes};
// Prefixes for residuals histos prepared by PrepSDDResidMap.C from MP2 output
// For QA histograms the name should be changed to "hpSDDResXvsXD","hpSDDResXvsZ","hpSDDDrTimevsXD","hpSDDDrTimevsZ" respectively
const Char_t* kQAHistoNames[] = {    // 
  "hpSDDResXvsXD",                   // DX vs Xdrift 
  "hpSDDResXvsZ",                    // DX vs local Z
  "hpSDDDrTimevsXD",                 // TDrift-T0 vs Xdrift
  "hpSDDDrTimevsZ"                   // TDrift-T0 vs local Z
};
const Char_t* kLRNames[] = {"0","1"};  // identifiers for left/right sides in histo names
/*
const Char_t* kQAHistoNames[] = {    // 
  "Xdrift_Mod_",                     // DX vs Xdrift 
  "ZAnode_Mod_",                     // DX vs local Z
  "TD_vs_Xdrift_Mod_",               // TDrift-T0 vs Xdrift
  "TD_vs_ZAnode_Mod_"                // TDrift-T0 vs local Z
};
const Char_t* kLRNames[] = {"left","right"};  // identifiers for left/right sides in histo names
*/
//
const double kMaxChi2SimpleMap = 1.0; // if polinomial fit gives chi2 below this value, make map out of it
double minBEntryX = 10;        // min entries in the bin to account (vs Xdrift)
double minBEntryZ = 20;        // min entries in the bin to account (vs Z)
double skipDXEdge = 1000.;     // microns to skip from each side of XDrift when smoothing
double edgeSmearMinErr = 60.;        // minimal error for extrapolation
double edgeSmearMaxErr = 600.;       // maximal error for extrapolation
double wDXEdge    = 5000.;     // width in microns for XDrift edges to average
double wVDEdge    = 2500;      // width in microns for VDrift averaging region on the edges
double threshClean= 0.3;       // clean edge bins with occupancy smaller than in the neighbourhood
int    nVDEdge    = 20;        // min width in n bins for VDrift averaging region on the edges
int    smoothLevel= 5;         // smoothing level
int    minBinsEdge = 5;        // min number of X>0 good bins to fit the edge
Bool_t useSplieForR2V = kFALSE;      // if true, extract Vd profile using Derivateve of spline (may be inadequate for sharp turns)
//

Bool_t userLeftRightFromTASK = kTRUE;   // VERY IMPORTANT: histos produced by AliAnalysisTaskITSAlignQA have inverted left/right side definitions
Bool_t forceT0CorrTo0   = kFALSE;//kTRUE;
Bool_t forceRPhiCorrTo0 = kTRUE;
Bool_t userDummyCorrMap = kFALSE;//kTRUE;
Bool_t userDummyt0Corr  = kFALSE;//kTRUE;
Bool_t userDummyxlCorr  = kFALSE;//kTRUE;
Int_t  userRebinX = 1;
Int_t  userRebinZ = 2;
//
//
AliITSsegmentationSDD sddSeg;
//
//----------------- working variables --------------------------------
Int_t currSDDId=-1,currSDDSide=-1,currMod=-1;
TProfile*  currHDXvsX = 0;                // raw DX vs X histo from QA
TProfile*  currHDXvsZ = 0;                // raw DX vs Z histo from QA
TProfile*  currHTDvsX = 0;                // raw DriftTime-T0 vs X histo from QA
TProfile*  currHTDvsZ = 0;                // raw DriftTime-T0 vs Z histo from QA
TH1*       currHDXvsXclean = 0;           // smoothed DX vs X histo
TH1*       currHVDvsX = 0;                // extracted VDrift vs X profile
TH1*       currHCorrMapX = 0;             // extracted correction map
TH1*       currHDXvsXCorr = 0;            // DX vs X histo after application of the map
TH1*       currHDXvsZCorrMT0 = 0;         // DX vs X histo after application of the map and t0 correction
TH1*       currHDVvsZ = 0;                // correction for the VDrift vs Z
TH1*       currHDVvsZOrig = 0;            // correction for the VDrift vs Z (before error processing)
TGraphErrors* currGrDxx = 0;              // DX final vs XDrift
TGraphErrors* currGrTDx = 0;              // DX final vs TDrift 
TGraphErrors* currGrTXCorr = 0;           // TDrift vs XDritf
TCollection* qaHistos = 0;                // input QA collection
TObjArray procHistos;                     // processed histos buffer
AliITSresponseSDD* sddResp=0;             // SDD response, updated
TObjArray *vdarrayOld = 0;                // olf VDrifts array
TObjArray* vDriftArr=0;                   // VDrifts array, updated
TObjArray* corrMaps=0;                    // holder for correction maps
//
TH1*       resOffsDXraw[2]={0};           // Dx vs X offset at Xdrift=0 raw
TH1*       resOffsDXAMap[2]={0};          // Dx vs X offset (mean) after correction by map
TH1*       resOffsDX[2]={0};              // Dx vs X offset at Xdrift=0 after correction by map (for each side)
TH1*       resVDCorr[2]={0};              // VDrift correction  (for each side)
TH1*       resVDMean[2]={0};              // average VDrift (for each side)
TH1*       resVDCorrZ[2]={0};             // mean VDrift vs Z corrections (for each side)
TH1*       resT0Corr = 0;                 // correction to modules T0
TH1*       resXLocCorr = 0;               // correction to module location
TCanvas*   sddCanv = 0;                   // report canvas
//
Bool_t     sddRespUpdT0OK = kFALSE;       // flag that SDDresponse object T0 was updated
Bool_t     sddRespUpdVDOK = kFALSE;       // flag that SDDresponse object VDrift correction was updated
Bool_t     sddVDriftUpdOK = kFALSE;       // flag that SDD VDrift object was updated
//
TString pathSDDRespOld    = "";
TString pathSDDVDriftOld  = "";
TString pathSDDCorrMapOld = "";
//
//--------------------------------------------------------------------
void      Process(const char* pathSDDResp=0,const char* pathSDDVDrift=0, const char* pathSDDCorrMap=0);
void      Process(TCollection* qa, const char* pathSDDResp=0,const char* pathSDDVDrift=0, const char* pathSDDCorrMap=0);
Bool_t    ProcSDDSideDXvsX();
Bool_t    ProcSDDSideDXvsZ();
TProfile* GetQAHisto(Int_t qaType);
TProfile* H2Profile(TH2* h2);
TH1*      H2ProfileAsTH1(TH2* h2);
TH1*      GetProfHEntries(TProfile* prof);
TH1*      ProfileAsTH1(TProfile* prof, const char* addName);
TH1*      CleanProfile(TProfile* profR);
TH1*      Vdrift2Resid(TH1* vd);
TH1*      Resid2Vdrift(TH1* res);
void      RedoProfileErrors(TH1* profH1,TProfile* prof);
void      SetModuleID(Int_t mdID,Int_t side=-1);
void      PrepareModuleHistos(Int_t mdID, Int_t side, Bool_t vsZ);
void      CheckResultDX();
void      CalcDXCorrections();
double    GetVOld(double z);
Int_t     GetStoreID(int type, int imd=-1,int side=-1);
void      CleanPrev();
void      StoreCurrent();
double    ftVdZ(double *x, double *par);
void      PlotReport(const char* psname="repSDDQA.ps");
TH1*      GetPadBaseHisto(TPad* pad);
Bool_t    PlotHisto(TH1* h, Option_t* opt="", int mrkStyle=20,int mrkCol=kBlack, double mrkSize=1.);
TLatex*   AddPadLabel(const char*txt,float x=0.1,float y=0.9,int color=kBlack,float size=0.04);
void      GetHistoMinMaxInRange(TH1* h, double &mn,double &mx);
double    edgeLow(double* x, double *par);
double    edgeHigh(double* x, double *par);
void      CureEdges(TH1* prof);
void      SafeRebin(TProfile* prof, Int_t factor, Bool_t xprof);
TH1*      FitDXEdges(TProfile* prof);
Bool_t    TestMapFunction(TH1* smap, TF1* fun, double lft, double rgt);
double    ftPolComb(double* x, double *par);
TH1*      SimpleMap(TH1* prof);
//
Bool_t    LoadSDDVDrift(TString& path, TObjArray *&arr);
Bool_t    LoadSDDResponse(TString& path, AliITSresponseSDD *&resp);
Bool_t    LoadSDDCorrMap(TString& path, TObjArray *&maps);
AliCDBEntry* GetCDBEntry(const char* path);
//
void                UpdateSDDResponse(AliITSresponseSDD *resp, Bool_t t0=kTRUE, Bool_t vdrift=kTRUE);
void                UpdateSDDVDrift(AliITSDriftSpeedArraySDD* vdArr, int imd, int side);
TObjArray*          UpdateSDDVDrift();
TObjArray*          CreateCorrMaps();
AliITSresponseSDD*  UpdateSDDResponse(Bool_t t0=kTRUE, Bool_t vdrift=kTRUE);
AliITSCorrMap1DSDD* CreateCorrMap(TH1* mapHisto, int imd, int side, AliITSCorrMap1DSDD* updateMap=0);
void      PrepCDBObj(TObject *obj,const char* path,int firstrun=0,int lastrun=999999999,const char* comment="");

//-------------------------------------------------------------------

//_________________________________________________________________________
void Process(TCollection* qa, const char* pathSDDResp, const char* pathSDDVDrift, const char* pathSDDCorrMap)
{
  // process all
  qaHistos = qa;
  Process(pathSDDResp,pathSDDVDrift,pathSDDCorrMap);
}

//_________________________________________________________________________
void Process(const char* pathSDDResp, const char* pathSDDVDrift, const char* pathSDDCorrMap)
{
  // process all
  procHistos.Clear();
  pathSDDRespOld     = pathSDDResp;
  pathSDDVDriftOld   = pathSDDVDrift;
  pathSDDCorrMapOld  = pathSDDCorrMap;
  sddRespUpdT0OK = sddRespUpdVDOK = sddVDriftUpdOK = kFALSE;
  //
  if (pathSDDVDriftOld.IsNull()) printf("Attention: Old VDrift is missing!\n");
  //
  for (int imd=kSDDMin;imd<=kSDDMax;imd++) {
    for (int ix=0;ix<2;ix++) {
      CleanPrev();            // clean data from previous module
      printf("Processing %d/%d\n",imd,ix);
      PrepareModuleHistos(imd,ix, kTRUE);
      ProcSDDSideDXvsX();     // process DX vs X histos to get corr.maps, deltaT0, deltaX0, deltaV_mean
      StoreCurrent();
    }
    CalcDXCorrections();      // calculate delta's
    //
    for (int ix=0;ix<2;ix++) {
      CleanPrev();            // clean data from previous module
      PrepareModuleHistos(imd,ix, kFALSE);
      ProcSDDSideDXvsZ();     // process deltaV vs anode profile
      StoreCurrent();         
    }
  }
  //
  corrMaps = CreateCorrMaps();   // create correction maps
  PrepCDBObj(corrMaps,"ITS/Calib/MapsTimeSDD",firstRun,lastRun,cdbComment.Data());
  //
  if (!pathSDDVDriftOld.IsNull()) {
    vDriftArr = UpdateSDDVDrift();
    PrepCDBObj(vDriftArr,"ITS/Calib/DriftSpeedSDD",firstRun,lastRun,cdbComment.Data());
  }
  //
  if (!pathSDDRespOld.IsNull()) {
    sddResp = UpdateSDDResponse();
    PrepCDBObj(sddResp,"ITS/Calib/RespSDD",firstRun,lastRun,cdbComment.Data());
  }
  //
  PlotReport();
}

//_________________________________________________________________________
Bool_t ProcSDDSideDXvsX()
{
  // process one side of the SDD module
  currHDXvsXCorr   = ProfileAsTH1(currHDXvsX,"corrCheck");
  RedoProfileErrors(currHDXvsXCorr,currHDXvsX);
  //
  if ( (currHDXvsXclean=CleanProfile(currHDXvsX)) ) {
    //
    delete currHDXvsXCorr;
    currHDXvsXCorr = (TH1*)currHDXvsXclean->Clone( Form("%s_corrCheck",currHDXvsX->GetName()) );
    //
    // try simple solution
    if (!(currHCorrMapX=SimpleMap(currHDXvsXclean))) { 
      currHVDvsX      = Resid2Vdrift(currHDXvsXclean);
      currHCorrMapX   = Vdrift2Resid(currHVDvsX);
    }
    //
    currHDXvsXCorr->Add(currHCorrMapX,-1);
  }
  // check results
  CheckResultDX();
  //
  return kTRUE;
}

//_________________________________________________________________________________
Bool_t ProcSDDSideDXvsZ()
{
  // extract correction for Vdrift vs Z from DXvsZ profile and mean_drift_time vs Z
  //
  static TF1* fitP0 = new TF1("fitP0","pol0",-4000,4000);
  double chi2s[maxVZOrd+1] = {0};
  static TF1* fitVvsZs[maxVZOrd+1] = {0};
  static Bool_t iniDone = kFALSE;
  double zrange = sddSeg.Dz()/2 - 1.;
  if (!iniDone) {
    iniDone = kTRUE;
    for (int iord=0;iord<=maxVZOrd;iord++) {
      fitVvsZs[iord] = new TF1("fitVvsZ",ftVdZ, -zrange, zrange ,iord+2);
      fitVvsZs[iord]->FixParameter(0, iord+0.1);
    }
  }
  //
  int nb = currHDXvsZ->GetNbinsX();  
  if (currHDXvsZ->GetEntries()<minBEntryZ*nb) return kFALSE;
  //
  currHDVvsZ = ProfileAsTH1(currHDXvsZ,"_vzcorr"); 
  currHDVvsZ->Reset();
  //
  currHDXvsZCorrMT0 = ProfileAsTH1(currHDXvsZ,"_zcorrMapT0"); 
  currHDXvsZCorrMT0->Reset();
  //
  int nbUse=0, ib0 = currHDVvsZ->FindBin(-zrange), ib1 = currHDVvsZ->FindBin( zrange);
  double *statZB = new double[nb+1];   // entries per Z bin
  memset(statZB,0,sizeof(double)*(nb+1)); 
  double vmean=0, vmeanE=0, norm=0;
  //
  for (int ib=ib0;ib<=ib1;ib++) {
    double ne = currHTDvsZ->GetBinEntries(ib);
    if (ne<1) continue;
    double dx = currHDXvsZ->GetBinContent(ib);   // raw residual X vs Z
    double dxe= currHDXvsZ->GetBinError(ib);     
    double t  = currHTDvsZ->GetBinContent(ib);   // mean assumed (TDrift - T0)
    double te = currHTDvsZ->GetBinError(ib);
    double vCorr = resVDCorr[currSDDSide]->GetBinContent(currMod+1);
    dx -= vCorr*t;          // subtract mean V correction
    dxe = TMath::Sqrt(dxe*dxe + vCorr*vCorr*te*te);
    currHDXvsZCorrMT0->SetBinContent(ib,dx);
    currHDXvsZCorrMT0->SetBinError(ib,dxe);
  }  
  currHDXvsZCorrMT0->Fit(fitP0,"q0","");
  double pedestal = fitP0->GetParameter(0);
  //
  for (int ib=ib0;ib<=ib1;ib++) {
    double ne = currHTDvsZ->GetBinEntries(ib);
    if (ne<minBEntryZ) continue;
    double dx = currHDXvsZCorrMT0->GetBinContent(ib);   // raw residual X vs Z
    double dxe= currHDXvsZCorrMT0->GetBinError(ib);     
    double t  = currHTDvsZ->GetBinContent(ib);   // mean assumed (TDrift - T0)
    double te = currHTDvsZ->GetBinError(ib);
    if (t<1) continue;
    // corrections
    // account for the corrections leading the mean DX to 0
    dx -= pedestal;
    double v = dx/t;
    double ve = TMath::Sqrt(dxe*dxe + v*v*te*te)/t;
    //
    nbUse++;
    vmeanE += 1./(ve*ve); 
    vmean  += v/(ve*ve); 
    //    printf("%d %f %f | %f %f | -> %f %f\n",ib,dx,dxe,t,te,v,ve);
    int ibDest = currSDDSide==0 ? ib : nb+1-ib;
    statZB[ibDest] = ne;
    currHDVvsZ->SetBinContent(ibDest,v);
    currHDVvsZ->SetBinError(ibDest,ve);
    //
  }
  //
  if (nbUse<maxVZOrd+1) {delete statZB; return kFALSE;}
  if (vmeanE>0) { vmean /= vmeanE; vmeanE = 1./TMath::Sqrt(vmeanE); }
  // fill empty and bad bins by mean value with large error
  vmeanE *= nbUse;
  /*
  for (int ib=ib0;ib<=ib1;ib++) {
    //if (statZB[ib]<minBEntryZ) currHDVvsZ->SetBinContent(ib,vmean);
    if (currHDVvsZ->GetBinError(ib)>vmeanE || statZB[ib]<minBEntryZ) {
      currHDVvsZ->SetBinError(ib,vmeanE*2);
      currHDVvsZ->SetBinContent(ib,vmean);
    }
  }
  */
  // save original
  currHDVvsZOrig = (TH1*) currHDVvsZ->Clone(Form("%s_orig",currHDVvsZ->GetName()));
  // find leftmost good bin
  int bL,bR;
  double errL=0,errR=0, valL=0,valR=0;
  for (bL=ib0;bL<=ib1;bL++) {
    if (/*currHDVvsZ->GetBinError(bL)>vmeanE ||*/ statZB[bL]<minBEntryZ) continue;
    errL = currHDVvsZ->GetBinError(bL);
    valL = currHDVvsZ->GetBinContent(bL);
    break;
  }
  for (bR=ib1;bR>=ib0;bR--) {
    if (/*currHDVvsZ->GetBinError(bR)>vmeanE ||*/ statZB[bR]<minBEntryZ) continue;
    errR = currHDVvsZ->GetBinError(bR);
    valR = currHDVvsZ->GetBinContent(bR);
    break;
  }
  // change bad bins 
  for (int ib=bL-1;ib>=ib0;ib--) {
    double err = errL + (vmeanE-errL)*float(ib-ib0)/(bL-ib0+1);
    double val = vmean + (valL-vmean)*float(ib-ib0)/(bL-ib0+1);
    currHDVvsZ->SetBinError(ib,err);
    currHDVvsZ->SetBinContent(ib,val);//currHDVvsZ->GetBinContent(ib+1));
  }
  for (int ib=bR+1;ib<=ib1;ib++) {
    double err = errR + (vmeanE-errR)*float(ib1-ib)/(ib1-bR+1);
    double val = vmean + (valR-vmean)*float(ib1-ib)/(ib1-bR+1);
    currHDVvsZ->SetBinError(ib,err);
    currHDVvsZ->SetBinContent(ib,val);//currHDVvsZ->GetBinContent(ib-1));
  }
  //
  for (int iord=0;iord<=maxVZOrd;iord++) {
    currHDVvsZ->Fit(fitVvsZs[iord],"q0");
    chi2s[iord] = fitVvsZs[iord]->GetChisquare();
    int ndf = fitVvsZs[iord]->GetNDF();
    if (ndf>0) chi2s[iord] /= ndf;
  }
  //
  // analyse chi2's
  int bestOrd = 0;
  double bestChi2 = 9999;
  for (int iOrd=0;iOrd<=maxVZOrd;iOrd++) {
    if (chi2s[iOrd]<bestChi2-0.5) {bestChi2 = chi2s[iOrd]; bestOrd = iOrd;}
  }
  TF1* fitVvsZ = fitVvsZs[bestOrd];
  currHDVvsZ->Fit(fitVvsZ,"q");
  //  
  // extract mean correction neglecting the constant term
  vmean = 0;
  double freePar = 0;//fitVvsZ->GetParameter(1);
  for (int ib=1;ib<=nb;ib++) {
    if (statZB[ib]<1) continue;
    vmean += statZB[ib]*(fitVvsZ->Eval(currHDVvsZ->GetBinCenter(ib)) - freePar); // account only Z dependent part
    norm  += statZB[ib];
  }
  //
  if (!resVDCorrZ[currSDDSide]) {
    resVDCorrZ[currSDDSide] = new TH1F(Form("VDcorrvsZ%d",currSDDSide),Form("mean VDrift correction vs Z, side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resVDCorrZ[currSDDSide]->SetMarkerColor(2+currSDDSide);
    resVDCorrZ[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);    
  }
  //
  //  if (currSDDSide) vmean = -vmean;
  resVDCorrZ[currSDDSide]->SetBinContent(currMod+1, norm>0 ? vmean/norm : 0);
  delete statZB;
  return kTRUE;
}

//_________________________________________________________________________
void PrepareModuleHistos(Int_t mdID, Int_t side, Bool_t vsX)
{
  // retrieve QA histos, if needed, convert to TH1
  SetModuleID(mdID, side);
  if (vsX) {
    currHDXvsX = GetQAHisto(kDxX);
    currHTDvsX = GetQAHisto(kTDX);
  }
  else {
    currHTDvsZ = GetQAHisto(kTDZ);
    currHDXvsZ = GetQAHisto(kDxZ);
  }
}

//_________________________________________________________________________
void SetModuleID(Int_t mdID,Int_t side)
{
  // set current module ID,side
  currSDDId   = mdID;
  currSDDSide = side;
  currMod     = currSDDId - kSDDMin;
}

//_________________________________________________________________________
TProfile* GetQAHisto(Int_t qaType)
{
  // retrieve needed QA histo
  if (!qaHistos) {printf("QA Histos collection is not set\n"); exit(1);}
  //
  if (currSDDId<kSDDMin || currSDDId>kSDDMax || currSDDSide<0 || currSDDSide>2) 
    {printf("Illegal SDD module ID/Side: %d/%d\n",currSDDId,currSDDSide); exit(1);}
  //
  if (qaType<0 || qaType>=kNQATypes) 
    {printf("Illegal QA Histo Type %d\n",qaType); exit(1);}
  //
  int trueSide = userLeftRightFromTASK ? (1-currSDDSide) : currSDDSide;
  const char* hname = Form("%s%d_%s",kQAHistoNames[qaType],currSDDId,kLRNames[trueSide]);
  TH1* h = (TH1*) qaHistos->FindObject(hname);
  if (!h) {printf("Did not find histo %s in QA output collection\n",hname); exit(1);}
  //
  if (h->InheritsFrom(TH2::Class())) h = H2Profile((TH2*)h); // make sure it is not TH2 histo
  //
  if ( (qaType==kDxX || qaType==kTDX) && userRebinX>1) SafeRebin((TProfile*)h,userRebinX,kTRUE);
  if ( (qaType==kDxZ || qaType==kTDZ) && userRebinZ>1) SafeRebin((TProfile*)h,userRebinZ,kFALSE);
  //
  return (TProfile*)h;
}

//_________________________________________________________________________
TH1* H2ProfileAsTH1(TH2* h2)
{
  // extract profile as TH1 histo
  TProfile* prf = h2->ProfileX();
  TH1* prof = ProfileAsTH1(prf, "_profH1");
  delete prf;
  return prof;
}

//_________________________________________________________________________
TH1* ProfileAsTH1(TProfile* prf, const char* addName)
{
  // convert profile to TH1 histo
  TString nm = prf->GetName(); nm += addName;
  TAxis* xax = prf->GetXaxis();
  TH1* prof = 0;
  const TArrayD *bins = xax->GetXbins();
  if (bins->GetSize() == 0) {
    prof = new TH1F(nm.Data(),nm.Data(),prf->GetNbinsX(),xax->GetXmin(),xax->GetXmax());
  }
  else {
    prof = new TH1F(nm.Data(),nm.Data(),xax->GetNbins(),bins->GetArray());
  }
  for (int i=1;i<=prof->GetNbinsX();i++) {
    prof->SetBinContent(i, prf->GetBinContent(i));
    prof->SetBinError(i, prf->GetBinError(i));
  }
  return prof;
}

//_________________________________________________________________________
TProfile* H2Profile(TH2* h2)
{
  // extract profile 
  TString nm = h2->GetName(); nm += "_prof";
  TProfile* prf = h2->ProfileX(nm.Data());
  return prf;
}

//_________________________________________________________________________________
TH1* CleanProfile(TProfile* profR)
{
  // clean profile copy
  TH1* prof = FitDXEdges(profR); // cure edges

  int ib0 = profR->FindBin(1), ib1 = profR->FindBin(sddSeg.Dx()-1);
  int nbn = profR->GetNbinsX();
  int nSkip = skipDXEdge/profR->GetBinWidth(nbn/2);
  int nMean = wDXEdge/profR->GetBinWidth(nbn/2);
  //
  // get mean occupancy skipping first and last nSkip occupied bins
  //
  int nbCntL=0, nbCntR=0,nskipL=0,nskipR=0;
  double smL=0,smR=0;
  for (int ib=ib0;ib<=ib1 && nbCntL<nMean;ib++) { // skipping left, get average of good bins
    double vl = profR->GetBinEntries(ib);
    if (vl<minBEntryX) continue;
    if (nskipL<nSkip) {nskipL++; continue;}
    smL += vl;
    nbCntL++;
  }
  if (nbCntL<1) return 0;
  smL /= nbCntL;
  //
  for (int ib=ib1+1;ib>ib0 && nbCntR<nMean;ib--) { // skipping right
    double vl = profR->GetBinEntries(ib);
    if (vl<minBEntryX) continue;
    if (nskipR<nSkip) {nskipR++; continue;}
    smR += vl;
    nbCntR++;
  }
  //
  if (nbCntR<1) return 0;
  smR /= nbCntR;
  //
  prof->GetXaxis()->SetRange(ib0,ib1);
  prof->Smooth(smoothLevel,"r");
  prof->GetXaxis()->SetRange(1,nbn);
  // kill bins with small statistics, from left and right
  for (int ib=1;ib<ib1;ib++)   if (profR->GetBinEntries(ib)<threshClean*smL) {prof->SetBinContent(ib,0);prof->SetBinError(ib,0);} else break;
  for (int ib=ib1;ib>ib0;ib--) if (profR->GetBinEntries(ib)<threshClean*smR) {prof->SetBinContent(ib,0);prof->SetBinError(ib,0);} else break;
  //
  return prof;
}


//_________________________________________________________________________________
TH1* Resid2Vdrift(TH1* res)
{
  // extract Vdrift profile from residuals profile
  //
  TSpline3 spl(res);
  TString nm = res->GetName(); nm += "_vd";
  TH1* vd = (TH1*) res->Clone(nm.Data());
  vd->Reset();
  int nb = vd->GetNbinsX();
  //
  int nbcnt=0, nbfl = wVDEdge/vd->GetBinWidth(nb/2);
  if (nbfl<nVDEdge) nbfl=nVDEdge;
  //
  double vAv=0,eAv=0;                           // average vdrift / v0
  for (int i=1;i<=nb;i++) {
    double deriv = useSplieForR2V ? spl.Derivative(vd->GetBinCenter(i)) : (res->GetBinContent(i)-res->GetBinContent(i-1))/res->GetBinWidth(i);
    double v = TMath::Abs(deriv-1)>1e-6 ? 1./(1-deriv) : 1.;
    vd->SetBinContent(i, v);
    double err2 = 0; // set relative error
    int nbd = 1;
    for (int i1=i-1;i1<=i+1;i1++) {
      if (i1<1 || i1>nb) continue;
      double err = res->GetBinError(i);
      if (err<1e-9) err = 1e4;
      err2 += err*err;
      nbd++;
    }
    if (nbd) err2/=nbd;
    if (err2>0 && v>0 && v<3) {vAv += v/err2; eAv += 1./err2;}
    err2 = TMath::Sqrt(err2)/res->GetBinWidth(nb/2);
    vd->SetBinError(i, err2 );
    nbcnt++;
  }
  vAv = eAv>0 ? vAv/eAv : 1.0;
  //  printf("mean V = %f in %d bins\n",vAv,nbcnt);
  // cure anomalous bins
  //  for (int i=1;i<=nb;i++) if (vd->GetBinContent(i)<0.1) vd->SetBinContent(i,vAv);
  //
  int ib = 0;
  for (ib=1;ib<nb;ib++) { // detect up to which bin the left tail is unstable
    double x = vd->GetBinCenter(ib);
    if (x<0 || res->GetBinError(ib)<1e-9) {vd->SetBinContent(ib,1); vd->SetBinError(ib,0); continue;}
    double vl = vd->GetBinContent(ib);
    if (TMath::Abs(vl-vAv)<0.2) break;
    vd->SetBinContent(ib,1);
    vd->SetBinError(ib,0);    
  }
  //
  double vL=0,eL=0,vR=0,eR=0;
  // get the mean of leftmost stable vdrift
  int lastCounted = 0;
  nbcnt = 0;
  for (int i=ib;i<=nb && nbcnt<nbfl;i++) {
    double berr = vd->GetBinError(i);
    if (berr<1e-9 || berr>0.5 || TMath::Abs(vd->GetBinContent(i)-vAv)>0.2) continue;
    vL += vd->GetBinContent(i)/berr/berr;
    eL += 1./berr/berr;
    nbcnt++;
    lastCounted = i;
  }
  vL = eL>0 ? vL/eL : vAv;
  //printf("VLeft: %f, in %d bins (%d %d)\n",vL,nbcnt,ib,lastCounted);
  for (int i=1;i<=ib;i++) vd->SetBinContent(i, vL);
  // for safety check if there are no outliers in first 3 "stable" bins
  for (int i=ib+1;i<ib+3;i++) if (  vd->GetBinError(i)<1e-9 || TMath::Abs(vd->GetBinContent(i)-vL)>0.2) vd->SetBinContent(i, vL);
  vd->SetBinContent(vd->FindBin(1),1.); // no correction at t=0 !!
  //
  double lmax = sddSeg.Dx()-1;
  for (ib=nb+1;ib--;) { // detect up to which bin the right tail is unstable
    double x = vd->GetBinCenter(ib);
    if (x>=lmax || res->GetBinError(ib)<1e-9) {vd->SetBinContent(ib,1);vd->SetBinError(ib,0);  continue;}
    if (TMath::Abs(vd->GetBinContent(ib)-vAv)<0.4) break;
    vd->SetBinContent(ib,vAv);
    vd->SetBinError(ib,0);    
  }
  nbcnt= 0;
  lastCounted = 0;
  for (int i=ib;i>=1 && nbcnt<nbfl;i--) {
    double berr = vd->GetBinError(i);
    if (berr<1e-9 || berr>0.5 || TMath::Abs(vd->GetBinContent(i)-vAv)>0.4) continue;
    vR += vd->GetBinContent(i)/berr/berr;
    eR += 1./berr/berr;
    nbcnt++;
    lastCounted = i;
  }
  vR = eR>0 ? vR/eR : vAv;
  // printf("VRight: %f, in %d bins (%d %d)\n",vR,nbcnt,lastCounted,ib);
  for (int i=ib;i<=nb;i++) vd->SetBinContent(i, vR);
  // for safety check if there are no outliers in first 3 "stable bins
  for (int i=(lastCounted+ib)/2;i<ib;i++) 
    if (  vd->GetBinError(i)<1e-9 || (vd->GetBinError(i)>0.3 && TMath::Abs(vd->GetBinContent(i)-vR)>0.2)) vd->SetBinContent(i, vR);
  // fit the empty bins on the right
  //  vd->Fit(fitP1,"+","",vd->GetBinCenter(ib-nbfl),vd->GetBinCenter(nb));
  //for (int i=ib;i<=nb;i++) vd->SetBinContent(i, fitP1->Eval(vd->GetBinCenter(i)));
  //
  return vd;
}


//_________________________________________________________________________________
TH1* Vdrift2Resid(TH1* vd)
{
  // convert Vdrift profile to residuals profile (final correction map)
  //
  TString nm = vd->GetName(); nm += "_vd2res";
  TH1* res = (TH1*) vd->Clone(nm.Data());
  res->Reset();
  if (userDummyCorrMap) return res;
  int ib0 = res->FindBin(1);
  int ib1 = res->FindBin(sddSeg.Dx()-1);
  double resv=0;
  int lastB=0;
  for (lastB=ib1+1;lastB--;) if (vd->GetBinError(lastB)>1e-9) break;   // find last good bin
  double lastX = vd->GetBinCenter(lastB);
  // extend by 1mm
  lastX += 1000;
  if (lastX>sddSeg.Dx()) lastX = sddSeg.Dx();
  lastB = vd->FindBin(lastX);
  // 
  // 1st iteration : estimate correction at max Xdrift
  for (int i=ib0;i<=lastB;i++) {
    double dx = res->GetBinWidth(i);
    double v = vd->GetBinContent(i);
    resv += dx*(1.-1./v);    
  }
  double vcorr = (resv)/lastX;
  //
  // 2nd iteration : create new residuals forcing them to be 0 at Xdrift=0 and maxXDrift
  resv = res->GetBinWidth(ib0)*vcorr;
  for (int i=ib0;i<=lastB;i++) {
    double dx = res->GetBinWidth(i);
    double v = vd->GetBinContent(i);
    resv += dx*(1.-1./v - vcorr);
    res->SetBinContent(i, resv);
  }
  //
  return res;
}

//__________________________________________________________________________________
void CheckResultDX()
{
  // check mean residuals before and after correction
  const double kFOffs = 0.05; // skip edges
  static TF1* fitP1 = new TF1("fitP1","pol1",-5000,40000);
  static TF1* fitP0 = new TF1("fitP0","pol0",-5000,40000);
  //
  if (currHDXvsX->GetEntries()<minBEntryX*currHDXvsX->GetNbinsX()) {
    if (currHCorrMapX) currHCorrMapX->Reset();
    return;
  }
  //
  // vdrift correction 
  int b0 = currHDXvsXCorr->FindBin(1),b1 = currHDXvsXCorr->FindBin(sddSeg.Dx()-1);
  int nb = 0;
  for (int ib=b0;ib<b1;ib++) if (currHTDvsX->GetBinEntries(ib)>=minBEntryX) nb++;
  currHDXvsX->Fit(fitP0,"q0N","");
  double offsRaw = fitP0->GetParameter(0);
  currHDXvsXCorr->Fit(fitP0,"q0N","");
  double offsAMap = fitP0->GetParameter(0);

  //
  currGrDxx    = new TGraphErrors(nb);               // residual vs Xdrift
  currGrTDx    = new TGraphErrors(nb);               // residual vs tdrift
  currGrTXCorr = new TGraphErrors(nb);               // Xdrift vs tdrift
  double tmin = 1e6, tmax = -1e6, xmin = 1e6, xmax = -1e6;
  int ip = 0;
  for (int i=b0;i<b1;i++) {
    if (currHTDvsX->GetBinEntries(i)<minBEntryX) continue;
    double t = currHTDvsX->GetBinContent(i);
    double x = currHDXvsXCorr->GetBinCenter(i);
    if (tmin>t) tmin = t;
    if (tmax<t) tmax = t;
    if (xmin>x) xmin = x;
    if (xmax<x) xmax = x;    
    currGrDxx->SetPoint(ip,x,currHDXvsXCorr->GetBinContent(i));
    currGrDxx->SetPointError(ip,currHDXvsXCorr->GetBinWidth(i),currHDXvsXCorr->GetBinError(i));
    //
    currGrTDx->SetPoint(ip,t, currHDXvsXCorr->GetBinContent(i));
    currGrTDx->SetPointError(ip, currHTDvsX->GetBinError(i), currHDXvsXCorr->GetBinError(i));    
    //
    currGrTXCorr->SetPoint(ip,t, currHTDvsX->GetBinCenter(i));
    currGrTXCorr->SetPointError(ip,currHTDvsX->GetBinError(i), currHTDvsX->GetBinWidth(i));    
    //
    ip++;
  }
  double del = tmax-tmin;
  tmin += kFOffs*del;
  tmax -= kFOffs*del;  
  del = xmax - xmin;
  xmin += kFOffs*del;
  xmax -= kFOffs*del;
  //
  fitP1->SetParameters(0,0);
  currGrDxx->Fit(fitP1,"q","",xmin, xmax);
  double offs = fitP1->GetParameter(0);           // offset of correction line at Xdrift=0
  //
  //  printf("Fitting VD correction in the range %.1f:%.1f\n",tmin,tmax);
  fitP1->SetParameters(0,0);
  currGrTDx->Fit(fitP1,"q","",tmin,tmax);
  double vcor = fitP1->GetParameter(1);
  //
  fitP1->SetParameters(0,0);
  currGrTXCorr->Fit(fitP1,"q","",tmin,tmax);
  double vav = fitP1->GetParameter(1);
  //
  // store results
  if (!resOffsDXraw[currSDDSide]) {
    resOffsDXraw[currSDDSide] = new TH1F(Form("OffsRaw%d",currSDDSide),Form("DX Raw Offset, side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resOffsDXraw[currSDDSide]->SetMarkerColor(2+currSDDSide);
    resOffsDXraw[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);
  }
  //
  if (!resOffsDXAMap[currSDDSide]) {
    resOffsDXAMap[currSDDSide] = new TH1F(Form("OffsAMap%d",currSDDSide),Form("DX Offset after Map corr. Mean, side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resOffsDXAMap[currSDDSide]->SetMarkerColor(3+currSDDSide);
    resOffsDXAMap[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);
  }
  //
  if (!resOffsDX[currSDDSide]) {
    resOffsDX[currSDDSide] = new TH1F(Form("Offs%d",currSDDSide),Form("DX Offset at TD=0 after Map corr., side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resOffsDX[currSDDSide]->SetMarkerColor(2+currSDDSide);
    resOffsDX[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);    
  }
  //
  if (!resVDCorr[currSDDSide]) {
    resVDCorr[currSDDSide] = new TH1F(Form("VDcorr%d",currSDDSide),Form("VDrift correction, side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resVDCorr[currSDDSide]->SetMarkerColor(2+currSDDSide);
    resVDCorr[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);    
  }
  //
  if (!resVDMean[currSDDSide]) {
    resVDMean[currSDDSide] = new TH1F(Form("VDmean%d",currSDDSide),Form("VDrift mean, side %d",currSDDSide),kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resVDMean[currSDDSide]->SetMarkerColor(2+currSDDSide);
    resVDMean[currSDDSide]->SetMarkerStyle(20+4*currSDDSide);    
  }
  //
  resOffsDXraw[currSDDSide]->SetBinContent(currMod+1, offsRaw);
  resOffsDXAMap[currSDDSide]->SetBinContent(currMod+1, offsAMap);
  resOffsDX[currSDDSide]->SetBinContent(currMod+1, offs);
  resVDCorr[currSDDSide]->SetBinContent(currMod+1, vcor);
  resVDMean[currSDDSide]->SetBinContent(currMod+1, vav);
  //
}

//__________________________________________________________________________
void CalcDXCorrections()
{
  // estimate time0 and alignment correction for the whole module
  if (!resT0Corr) {
    resT0Corr = new TH1F("T0Corr","T0 Correction",kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resT0Corr->SetMarkerColor(2);
    resT0Corr->SetMarkerStyle(20);    
  }
  //
  if (!resXLocCorr) {
    resXLocCorr = new TH1F("XLocCorr","XLoc Correction",kNSDD,kSDDMin-0.5,kSDDMax+0.5);
    resXLocCorr->SetMarkerColor(2);
    resXLocCorr->SetMarkerStyle(20);    
  }
  //
  if (!resVDMean[0] || !resVDMean[1]) return;
  if (!resOffsDX[0] || !resOffsDX[1]) return;
  double vL = resVDMean[0]->GetBinContent(currMod+1);   // true mean VL
  double vR = resVDMean[1]->GetBinContent(currMod+1);   // true mean VR
  double offsL = resOffsDX[0]->GetBinContent(currMod+1);
  double offsR = resOffsDX[1]->GetBinContent(currMod+1);
  //
  double vsum=0,t0Corr=0,xlCorr=0;
  if (vL>1 && vR>1) { // both sides available
    vsum = vL + vR;
    t0Corr = -(offsL+offsR)/vsum;
    xlCorr = -(offsL*vR - offsR*vL)/vsum;
  }
  /*
  else if (vL>1) t0Corr = -offsL/vL; // only one side is available
  else if (vR>1) t0Corr = -offsR/vR;
  */
  else if (vL>1) xlCorr = -offsL; // only one side is available
  else if (vR>1) xlCorr =  offsR;
  //
  if (userDummyt0Corr) t0Corr = 0;
  if (userDummyxlCorr) xlCorr = 0;  
  //  printf("SDD%d VL:%f VR:%f offsL:%+f offsR:%+f  dT:%+f dX:%+f\n",currSDDId, vL,vR, offsL,offsR, t0Corr,xlCorr);
  resT0Corr->SetBinContent(currMod+1, t0Corr);        // T0 correction
  resXLocCorr->SetBinContent(currMod+1, xlCorr);      // X alignment correction
  //
  double addMap[2]={0,0};
  Bool_t redoMaps = kFALSE;
  //
  if (forceT0CorrTo0) { // T0 correction was forced to be 0, attribute this to map
    addMap[0] -= vL*t0Corr;
    addMap[1] -= vR*t0Corr;
    redoMaps = kTRUE;
  }
  if (forceRPhiCorrTo0) { // alignment correction was forced to be 0, attribute this to map
    addMap[0] -=  xlCorr;
    addMap[1] -= -xlCorr;
    redoMaps = kTRUE;
  }
  //
  if (redoMaps) {
    for (int ix=0;ix<2;ix++) {
      TH1* map  = (TH1*)procHistos.At( GetStoreID(kSCorrMapX, currSDDId, ix) );
      TH1* mapc = (TH1*)procHistos.At( GetStoreID(kSXvsXCorr, currSDDId, ix) );
      if (!map || !mapc) continue;
      int ib0 = map->FindBin(1);
      int ib1 = map->FindBin(sddSeg.Dx()-1);
      for (int ib=ib0+1;ib<ib1;ib++) {
	map->AddBinContent(ib,  addMap[ix]);
	mapc->AddBinContent(ib, -addMap[ix]);
      }
    }
  }

  //
}

//______________________________________________________________
Int_t GetStoreID(int type, int imd,int side)
{
  // entry of the histo/graph of type in the procHistos array
  //
  if (imd<0)  imd  = currSDDId;
  if (side<0) side = currSDDSide;
  if (type<0||type>=kNStore || imd<kSDDMin || imd>kSDDMax || side<0 || side>1) {
    printf("Wrong object requested: type: %d, Mod:%d/%d\n",type,imd,side);
    exit(1);
  }
  return (2*(imd-kSDDMin)+side)*kNStore + type;
}

//______________________________________________________________
void CleanPrev()
{
  // clean "current" objects from last event
  currHDXvsX = 0;
  currHDXvsZ = 0;
  currHTDvsX = 0;
  currHTDvsZ = 0;
  currHDXvsXclean = 0;
  currHVDvsX = 0;
  currHCorrMapX = 0;
  currHDXvsXCorr = 0;
  currHDVvsZ = 0;
  currGrDxx = 0;
  currGrTDx = 0;
  currGrTXCorr = 0;
  //
}

//______________________________________________________________
void StoreCurrent()
{
  // store "current" objects in procHistos
  if (currHDXvsX)       procHistos.AddAtAndExpand(currHDXvsX,      GetStoreID(kSXvsX));
  if (currHDXvsZ)       procHistos.AddAtAndExpand(currHDXvsZ,      GetStoreID(kSXvsZ));
  if (currHTDvsX)       procHistos.AddAtAndExpand(currHTDvsX,      GetStoreID(kSTDvsX));
  if (currHTDvsZ)       procHistos.AddAtAndExpand(currHTDvsZ,      GetStoreID(kSTDvsZ));
  if (currHDXvsXclean)  procHistos.AddAtAndExpand(currHDXvsXclean, GetStoreID(kSDXvsXclean));
  if (currHVDvsX)       procHistos.AddAtAndExpand(currHVDvsX,      GetStoreID(kSVDvsX));
  if (currHCorrMapX)    procHistos.AddAtAndExpand(currHCorrMapX,   GetStoreID(kSCorrMapX));
  if (currHDXvsXCorr)   procHistos.AddAtAndExpand(currHDXvsXCorr,  GetStoreID(kSXvsXCorr));
  if (currHDXvsZCorrMT0) procHistos.AddAtAndExpand(currHDXvsZCorrMT0,  GetStoreID(kSXvsZCorr));
  if (currHDVvsZ)       procHistos.AddAtAndExpand(currHDVvsZ,      GetStoreID(kSDVvsZ));
  if (currHDVvsZOrig)   procHistos.AddAtAndExpand(currHDVvsZOrig,  GetStoreID(kSDVvsZOrig));
  if (currGrDxx)        procHistos.AddAtAndExpand(currGrDxx,       GetStoreID(kSGrDxx));
  if (currGrTDx)        procHistos.AddAtAndExpand(currGrTDx,       GetStoreID(kSGrTDx));
  if (currGrTXCorr)     procHistos.AddAtAndExpand(currGrTXCorr,    GetStoreID(kSGrTXCorr));
  //
}

//_________________________________________________________________________________
TObjArray* CreateCorrMaps()
{
  // create correction maps for all modules
  printf("Creating correction maps (update %s)\n",pathSDDCorrMapOld.Data());
  TObjArray *dest = new TObjArray(2*kNSDD);
  TObjArray* update = 0;
  if (!pathSDDCorrMapOld.IsNull() && !LoadSDDCorrMap(pathSDDCorrMapOld,update)) {
    printf("The update of correction map was requested but the source %s is not found\n",pathSDDCorrMapOld.Data());
    exit(1);
  }
  //
  dest->Clear();
  AliITSCorrMap1DSDD *updMap = 0;
  for (int imd=kSDDMin;imd<=kSDDMax;imd++) {
    for (int side=0;side<2;side++) {
      TH1* mph = (TH1*)procHistos.At( GetStoreID(kSCorrMapX,imd,side) );
      //if (!mph) printf("Correction map is missing for module %d/%d\n",imd,side);
      if (update) updMap = (AliITSCorrMap1DSDD*)update->At(2*(imd-kSDDMin) + side);
      AliITSCorrMap1DSDD* mp = CreateCorrMap(mph,imd,side, updMap);
      dest->AddAtAndExpand(mp, 2*(imd-kSDDMin) + side);
    }
  }
  //
  return dest;
}

//_________________________________________________________________________________
AliITSCorrMap1DSDD* CreateCorrMap(TH1* mapHisto, int imd, int side, AliITSCorrMap1DSDD* updateMap)
{
  // create or update correction map from histo
  int nbCorr = 1, nbOld = 0;
  int b0=0,b1=0;
  if (mapHisto) {
    b0 = mapHisto->FindBin(1);
    b1 = mapHisto->FindBin(sddSeg.Dx()-1);
  }
  nbCorr = b1-b0+1;
  AliITSCorrMap1DSDD* mpCorr = 0;
  //
  // check if the updateMap is meaningful
  if (updateMap && updateMap->GetNBinsDrift()>2 && nbCorr>1) {
    if (mapHisto) {
      TSpline3 spl(mapHisto);
      nbOld = updateMap->GetNBinsDrift();
      double dx = sddSeg.Dx()/nbOld;
      for (int ip=0;ip<nbOld;ip++) {
	double x = dx*(0.5+ip);
	updateMap->SetCellContent(0,ip,updateMap->GetCellContent(0,ip)-spl.Eval(x));
      }
    }
    mpCorr = updateMap;
  }
  else {
    mpCorr = new AliITSCorrMap1DSDD(Form("DriftTimeMap_%d_%d",imd,side),nbCorr);
    if (side==0) mpCorr->SetInversionBit(); // !!! left side should return correction*-1
    if (mapHisto) for (int ib=b0;ib<=b1;ib++) mpCorr->SetCellContent(0,ib-b0,-mapHisto->GetBinContent(ib));
  }
  //
  return mpCorr;
}

//_________________________________________________________________________________
TObjArray* UpdateSDDVDrift()
{
  // retrieve SDD VDrift object and update it
  if (!vdarrayOld && !LoadSDDVDrift(pathSDDVDriftOld,vdarrayOld)) return 0;
  TObjArray *vdarrayUp = new TObjArray(2*kNSDD);
  //
  for (int imd=kSDDMin;imd<=kSDDMax;imd++) {
    for (int side=0;side<2;side++) {
      int iad = 2*(imd-kSDDMin)+side;
      AliITSDriftSpeedArraySDD* drarr = (AliITSDriftSpeedArraySDD*) vdarrayOld->At( iad );
      AliITSDriftSpeedArraySDD* drarrUp = new AliITSDriftSpeedArraySDD();
      AliITSDriftSpeedSDD* vOr = drarr->GetDriftSpeedObject(0);
      AliITSDriftSpeedSDD* vUp = new AliITSDriftSpeedSDD(*vOr); 
      drarrUp->AddDriftSpeed(vUp);
      vdarrayUp->AddAt(drarrUp, iad);
      UpdateSDDVDrift(drarrUp, imd, side);
    }
  }
  //
  sddVDriftUpdOK = kTRUE;
  return vdarrayUp;
}


//_________________________________________________________________________________
void UpdateSDDVDrift(AliITSDriftSpeedArraySDD* vdArr, int imd, int side)
{
  // update vdrift vs anode in the object
  AliITSDriftSpeedSDD* ds;
  if (!vdArr || !(ds=vdArr->GetDriftSpeedObject(0))) {printf("No VDrift object for  module %d/%d\n",imd,side); exit(1);}
  TH1* vdh = (TH1*)procHistos.At( GetStoreID(kSDVvsZ,imd,side) );
  if (!vdh) {
    //printf("VDrift vs Z correction is not processed for module %d/%d\n",imd,side); 
    return;
  }
  TF1* fp = vdh->GetFunction("fitVvsZ");
  if (!fp)  {printf("VDrift vs Z correction fit is missing SDD%d/%d\n",imd,side); return;}
  //
  int ord = (int)fp->GetParameter(0); // 1st param is the order of poly
  int ordOld = ds->GetDegreeofPoly();
  if (ord>ordOld) ds->SetDegreeofPoly(ord);
  for (int ip=0;ip<ord+1;ip++) {       // don't store offset (par[1])
    double par = ds->GetDriftSpeedParameter(ip) - fp->GetParameter(ip+1);
    ds->SetDriftSpeedParameter(ip, par);
  }
  //
}

//_________________________________________________________________________________
AliITSresponseSDD* UpdateSDDResponse(Bool_t t0, Bool_t vdrift)
{
  // retrieve RespSDD object and update it
  AliITSresponseSDD* resp = 0;
  if (!LoadSDDResponse(pathSDDRespOld, resp)) return 0;
  UpdateSDDResponse(resp, t0, vdrift);
  sddRespUpdT0OK = t0;
  sddRespUpdVDOK = vdrift;
  //
  return resp;
}

//_________________________________________________________________________________
void UpdateSDDResponse(AliITSresponseSDD *resp, Bool_t t0, Bool_t vdrift)
{
  // update the map with extracted values
  printf("Updating RespSDD object: T0:%s VDrift:%s\n",t0?"ON":"OFF",vdrift?"ON":"OFF");
  //
  if (t0 && !resT0Corr) 
    {printf("T0 update is requested but corrections were not processed"); exit(1);}
  if (vdrift && !(resVDCorr[0] && resVDCorr[1]))
    {printf("VDrift update is requested but corrections were not processed"); exit(1);}
  //
  for (int imd=kSDDMin;imd<=kSDDMax;imd++) {
    if (t0 && !forceT0CorrTo0) resp->SetModuleTimeZero(imd, resp->GetTimeZero(imd) - resT0Corr->GetBinContent(imd-kSDDMin+1));
    if (vdrift) {
      for (int ix=0;ix<2;ix++) {
	double vdZ = sddVDriftUpdOK&&resVDCorrZ[ix] ? resVDCorrZ[ix]->GetBinContent(imd-kSDDMin+1) : 0; // contribution from DXvsZ correction
	double vdX = resVDCorr[ix]->GetBinContent(imd-kSDDMin+1); // contribution from DXvsX correction
	resp->SetDeltaVDrift(imd, resp->GetDeltaVDrift(imd,ix) - (vdX-vdZ), ix);
      }
    }
  }
  //
}

//___________________________________________________________________
double GetVOld(double z)
{
  // return VDrift assumed in reconstruction
  if (!vdarrayOld && !LoadSDDVDrift(pathSDDVDriftOld,vdarrayOld)) return 0;
  AliITSDriftSpeedArraySDD* drarr = (AliITSDriftSpeedArraySDD*) vdarrayOld->At( 2*currMod + currSDDSide);
  float anode = sddSeg.GetAnodeFromLocal( currSDDSide==0 ? 1.:-1. ,z*1e-4);
  double v = drarr->GetDriftSpeed(0, anode);
  return v;
}

//___________________________________________________________________
double ftVdZ(double *x, double *par)
{
  // function to fit the vdrift dependence on Z
  //
  // convert Z to anode
  double z = x[0];
  double ian = (z/sddSeg.Dz() + 0.5);
  if (ian<0) ian = 0.;
  else if (ian>1) ian = 1.;
  ian *= sddSeg.NpzHalf();
  //
  int ord = int(par[0]);
  double v = par[ord+1];
  for (int i=ord;i--;) v = par[i+1]+ian*v;
  return v;
}

//________________________________________________________________________________________________________
Bool_t LoadSDDVDrift(TString& path, TObjArray *&arr)
{
  // load VDrift object
  if (path.IsNull()) return kFALSE;
  printf("Loading SDD VDrift from %s\n",path.Data());
  //
  AliCDBEntry *entry = 0;
  delete arr;
  arr = 0;
  while(1) {
    if (path.BeginsWith("path: ")) { // must load from OCDB
      entry = GetCDBEntry(path.Data());
      if (!entry) break;
      arr = (TObjArray*) entry->GetObject();
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      break;
    }
    //
    if (gSystem->AccessPathName(path.Data())) break;
    TFile* precf = TFile::Open(path.Data());
    if (precf->FindKey("TObjArray")) arr = (TObjArray*)precf->Get("TObjArray");
    else if (precf->FindKey("AliCDBEntry") && (entry=(AliCDBEntry*)precf->Get("AliCDBEntry"))) {
      arr = (TObjArray*) entry->GetObject();
      if (arr && arr->InheritsFrom(TObjArray::Class())) entry->SetObject(NULL);
      else arr = 0;
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      delete entry;
    }
    //
    precf->Close();
    delete precf;
    break;
  } 
  //
  if (!arr) {printf("Failed to load SDD vdrift from %s\n",path.Data()); return kFALSE;}
  arr->SetOwner(kTRUE);
  return kTRUE;
}

//________________________________________________________________________________________________________
Bool_t LoadSDDResponse(TString& path, AliITSresponseSDD *&resp)
{
  // load SDD response
  if (path.IsNull()) return kFALSE;
  printf("Loading SDD response from %s\n",path.Data());
  //
  AliCDBEntry *entry = 0;
  delete resp;
  resp = 0;
  //
  while(1) {
    if (path.BeginsWith("path: ")) { // must load from OCDB
      entry = GetCDBEntry(path.Data());
      if (!entry) break;
      resp = (AliITSresponseSDD*) entry->GetObject();
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      break;
    }
    //
    if (gSystem->AccessPathName(path.Data())) break;
    TFile* precf = TFile::Open(path.Data());
    if (precf->FindKey("AliITSresponseSDD")) resp = (AliITSresponseSDD*)precf->Get("AliITSresponseSDD");
    else if (precf->FindKey("AliCDBEntry") && (entry=(AliCDBEntry*)precf->Get("AliCDBEntry"))) {
      resp = (AliITSresponseSDD*) entry->GetObject();
      if (resp && resp->InheritsFrom(AliITSresponseSDD::Class())) entry->SetObject(NULL);
      else resp = 0;
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      delete entry;
    }
    //
    precf->Close();
    delete precf;
    break;
  } 
  //
  if (!resp) {printf("Error: Failed to load SDD response from %s\n",path.Data()); return kFALSE;}
  return kTRUE;
}

//________________________________________________________________________________________________________
Bool_t LoadSDDCorrMap(TString& path, TObjArray *&maps)
{
  // Load SDD correction map
  //
  if (path.IsNull()) return kFALSE;
  printf("Loading SDD Correction Maps from %s\n",path.Data());
  //
  AliCDBEntry *entry = 0;
  delete maps;
  maps = 0;
  while(1) {
    if (path.BeginsWith("path: ")) { // must load from OCDB
      entry = GetCDBEntry(path.Data());
      if (!entry) break;
      maps = (TObjArray*) entry->GetObject();
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      break;
    }
    //
    if (gSystem->AccessPathName(path.Data())) break;
    TFile* precf = TFile::Open(path.Data());
    if (precf->FindKey("TObjArray")) maps = (TObjArray*)precf->Get("TObjArray");
    else if (precf->FindKey("AliCDBEntry") && (entry=(AliCDBEntry*)precf->Get("AliCDBEntry"))) {
      maps = (TObjArray*) entry->GetObject();
      if (maps && maps->InheritsFrom(TObjArray::Class())) entry->SetObject(NULL);
      else maps = 0;
      entry->SetObject(NULL);
      entry->SetOwner(kTRUE);
      delete entry;
    }
    //
    precf->Close();
    delete precf;
    break;
  } 
  //
  if (!maps) {printf("Failed to load SDD Correction Map from %s\n",path.Data()); return kFALSE;}
  
  return kTRUE;
}

//_______________________________________________________________________________________
AliCDBEntry* GetCDBEntry(const char* path)
{
  // return object from the OCDB
  AliCDBEntry *entry = 0;
  printf("Loading object %s\n",path);
  AliCDBManager* man = AliCDBManager::Instance();
  AliCDBId* cdbId = AliCDBId::MakeFromString(path);
  if (!cdbId) {
    printf("Failed to create cdbId\n");
    return 0;
  }
  //
  AliCDBStorage* stor = man->GetDefaultStorage();
  if (!stor && !man->GetRaw()) man->SetDefaultStorage("raw://");
  if (man->GetRaw()) man->SetRun(cdbId->GetFirstRun());
  if (stor) {
    TString tp = stor->GetType();
    if (tp.Contains("alien",TString::kIgnoreCase) && !gGrid) TGrid::Connect("alien:"); 
  } 
  entry = man->Get(cdbId->GetPath(),cdbId->GetFirstRun(),cdbId->GetVersion(),cdbId->GetSubVersion());
  //  entry = man->Get( *cdbId );
  man->ClearCache();
  //
  delete cdbId;
  return entry;
  //
}
//

//_______________________________________________________________________________________
Bool_t PlotHisto(TH1* h, Option_t* opt, int mrkStyle,int mrkCol, double mrkSize)
{
  const double kOffsH = 0.15;
  if (!h) return kFALSE;
  TString opts = opt; opts.ToLower();
  if (opts.Contains("p")) {
    h->SetMarkerStyle(mrkStyle);
    h->SetMarkerColor(mrkCol);
    h->SetMarkerSize(mrkSize);
  }
  h->SetLineColor(mrkCol);
  h->Draw(opt);
  //
  h->SetMinimum(); h->SetMaximum();
  double hmn=h->GetMinimum(),hmx=h->GetMaximum(); // new histo min/max
  //
  TH1* hbase = GetPadBaseHisto((TPad*)gPad); if (!hbase) return 0;
  double smn = hbase->GetMinimum(),smx = hbase->GetMaximum(); // base set min/max?
  hbase->SetMinimum();  hbase->SetMaximum();
  double omn = hbase->GetMinimum(),omx = hbase->GetMaximum(); // base real min max
  if (smn<omn && smx>omx) { // min/max for bas histo was set by hand: extract original min/max
    omx = (smn*kOffsH+smx*(1+kOffsH))/(1+2*kOffsH);
    omn = (smn-kOffsH*omx)/(1+kOffsH);
  }
  if (hmn<omn) omn = hmn;
  if (hmx>omx) omx = hmx;
  double del = omx-omn;
  hbase->SetMinimum( omn - kOffsH*del );
  hbase->SetMaximum( omx + kOffsH*del );
  gPad->Update();
  return kTRUE;
}

//_______________________________________________________________________________________
void GetHistoMinMaxInRange(TH1* h, double &mn,double &mx)
{
  // compute min/max of histo in the user range
  mn = 1e50;
  mx =-1e50;
  int b0 = h->GetXaxis()->GetFirst(), b1 = h->GetXaxis()->GetLast();
  for (int i=b0;i<=b1;i++) {
    double e = h->GetBinError(i); 
    if (TMath::Abs(e)<1e-9) continue;
    double v = h->GetBinContent(i);
    if (mn>v-e) mn = v-e;
    if (mx<v+e) mx = v+e;
  }
}

//_______________________________________________________________________________________
void PlotReport(const char* psname)
{
  // report results
  sddCanv = new TCanvas("sddCanv","sddCanv",700,900);
  //
  gStyle->SetOptStat(0);
  gStyle->SetOptTitle(0);
  //
  TString psnm1 = psname;
  if (psnm1.IsNull()) psnm1 = "sddQAreport.ps";
  TString psnm0 = psnm1 + "["; 
  TString psnm2 = psnm1 + "]";
  sddCanv->Print(psnm0.Data());
  //
  // mean corrections per module/side
  sddCanv->Clear();
  sddCanv->Divide(2,3);
  int cntPad = 0;
  //
  for (int ix=0;ix<2;ix++) { // mean residuals before/after correction
    sddCanv->cd(++cntPad);
    PlotHisto(resOffsDXraw[ix],"p"     ,7,kBlack,0.5);
    PlotHisto(resOffsDX[ix]   ,"p same",7,kRed  ,1);    
    AddPadLabel(Form("<#DeltaX> %s : Raw",ix?"Right":"Left"), 0.1,0.93,kBlack,0.05);
    AddPadLabel("After Map", 0.5,0.93,kRed,0.05);
  }
  //
  for (int ix=0;ix<2;ix++) { // mean residuals before/after correction
    sddCanv->cd(++cntPad);
    PlotHisto(resVDCorr[ix] ,"p"     ,7,kBlack,1);
    PlotHisto(resVDCorrZ[ix],"p same",7,kRed  ,1);    
    AddPadLabel(Form("<#DeltaV> %s : from #DeltaX vs X",ix?"Right":"Left"), 0.1,0.93,kBlack,0.05);
    AddPadLabel("from #DeltaX vs Z", 0.6,0.93,kRed,0.05);
  }
  //
  sddCanv->cd(++cntPad);
  PlotHisto(resT0Corr,"p",7,kBlue,1);
  AddPadLabel("T0 Correction", 0.3,0.93,kRed,0.05);
  if (forceT0CorrTo0) AddPadLabel("Forced to 0 by transferring to maps", 0.15,0.88,kRed,0.05);
  //
  sddCanv->cd(++cntPad);
  PlotHisto(resXLocCorr,"p",7,kBlack,1);
  AddPadLabel("#DeltaX Correction", 0.3,0.93,kRed,0.05);
  if (forceRPhiCorrTo0) AddPadLabel("Forced to 0 by transferring to maps", 0.15,0.88,kRed,0.05);
  //
  sddCanv->cd();
  sddCanv->Print(psnm1.Data());
  //
  //-------------------------------------------------------------------
  TH1* hsdd = 0;
  //
  cntPad = 999;
  int nModPerPage = 3;
  int nRowPerMod = 2;
  Bool_t saved = kFALSE;
  int ib0=1,ib1=999;
  //
  for (int imd=kSDDMin;imd<=kSDDMax;imd++) {
    if (cntPad>=2*nModPerPage*nRowPerMod) {
      sddCanv->cd();
      if (imd!=kSDDMin) sddCanv->Print(psnm1.Data());
      sddCanv->Clear();
      sddCanv->Divide(2,nModPerPage*nRowPerMod);
      cntPad = 0;
      saved = kTRUE;
    }
    for (int ix=0;ix<2;ix++) {
      sddCanv->cd(++cntPad);
      TH1* hsddcl = (TH1*)procHistos.At(GetStoreID(kSDXvsXclean,imd,ix)); // raw residuals
      if (hsddcl) {
	ib0 = hsddcl->FindBin(1);
	ib1 = hsddcl->FindBin(sddSeg.Dx()-1);
	hsddcl->GetXaxis()->SetRange(ib0,ib1);
      }            
      PlotHisto(hsddcl,"p",24,kGreen+2,0.5);
      //
      hsdd = (TH1*)procHistos.At(GetStoreID(kSXvsX,imd,ix)); // raw residuals
      if (hsdd) {
	ib0 = hsdd->FindBin(1);
	ib1 = hsdd->FindBin(sddSeg.Dx()-1);
	hsdd->GetXaxis()->SetRange(ib0,ib1);
      }
      PlotHisto(hsdd,"p same",20,kBlack,0.4);
      PlotHisto(hsddcl,"p sames",24,kGreen+2,0.5);
      //
      //
      hsdd = (TH1*)procHistos.At(GetStoreID(kSCorrMapX,imd,ix)); // map
      if (hsdd) hsdd->GetXaxis()->SetRange(ib0,ib1);
      PlotHisto(hsdd,"same",7,kRed,0.5);
      hsdd = (TH1*)procHistos.At(GetStoreID(kSXvsXCorr,imd,ix)); 
      if (hsdd) hsdd->GetXaxis()->SetRange(ib0,ib1);
      PlotHisto(hsdd,"histo same",7,kBlue,0.5);
      //
      AddPadLabel(Form("<#DeltaX> %d %s: Raw",imd,ix?"Right":"Left"), 0.1,0.93,kBlack,0.07);
      AddPadLabel("Clean", 0.35,0.93,kGreen+2,0.07);
      AddPadLabel("Map", 0.42,0.93,kRed,0.07);
      AddPadLabel("+Map", 0.5,0.93,kBlue,0.07);
      //
      AddPadLabel(Form("#DeltaV:%+.4f | #DeltaT0:%+5.0f | #DeltaX:%+4.0f",
		       resVDCorr[ix] ? resVDCorr[ix]->GetBinContent(imd-kSDDMin+1):0,
		       resT0Corr     ?     resT0Corr->GetBinContent(imd-kSDDMin+1):0,
		       resXLocCorr   ?   resXLocCorr->GetBinContent(imd-kSDDMin+1):0),
		  0.5, 0.15, kRed, 0.07);
      //
      saved = kFALSE;
    }
    //
    for (int ix=0;ix<2;ix++) {
      sddCanv->cd(++cntPad);
      hsdd = (TH1*)procHistos.At(GetStoreID(kSDVvsZ,imd,ix)); // correction Vd vs Z
      PlotHisto(hsdd," ",7,kBlack,1);
      hsdd = (TH1*)procHistos.At(GetStoreID(kSDVvsZOrig,imd,ix)); // correction Vd vs Z
      PlotHisto(hsdd,"same",24,kBlue,1);
      AddPadLabel(Form("<#DeltaV> vs Z %d %s | Stat:%.2e",imd,ix?"Right":"Left",
		       ((TH1*)procHistos.At(GetStoreID(kSXvsX,imd,ix)))->GetEntries()), 0.1,0.93,kBlack,0.07);
      //
      AddPadLabel(Form("<#DeltaV>:%+.4f",resVDCorrZ[ix] ? resVDCorrZ[ix]->GetBinContent(imd-kSDDMin+1):0), 0.5, 0.15, kRed, 0.07);
      //
      saved = kFALSE;
    }
    //
  }
  //
  sddCanv->cd();
  if (!saved) sddCanv->Print(psnm1.Data());
  sddCanv->Print(psnm2.Data());
}

//__________________________________
TH1* GetPadBaseHisto(TPad* pad)
{
  if (!pad) pad = (TPad*)gPad;
  if (!pad) return 0;
  TList* lst = pad->GetListOfPrimitives();
  int size = lst->GetSize();
  TH1* hst=0;
  for (int i=0;i<size;i++) {
    TObject* obj = lst->At(i);
    if (!obj) continue;
    if (obj->InheritsFrom("TH1")) {hst = (TH1*)obj; break;}
  }
  return hst;
}

//__________________________________
TLatex* AddPadLabel(const char*txt,float x,float y,int color,float size)
{
  TLatex* lt = new TLatex(x,y,txt); 
  lt->SetNDC(); 
  lt->SetTextColor(color);
  lt->SetTextSize(size);
  lt->Draw();
  return lt;
}

//__________________________________
void SetCDBObjData(int firstrun,int lastrun,const char* comment)
{
  // change range and comment of the objects to store
  firstRun = firstrun;
  lastRun  = lastrun;
  cdbComment = comment;  
}

//__________________________________
void PrepCDBObj(TObject *obj,const char* path,int firstrun,int lastrun,const char* comment)
{
  if (firstrun<0) firstrun = 0;
  //
  AliCDBManager* man = AliCDBManager::Instance();
  man->UnsetDefaultStorage();
  man->SetDefaultStorage("local://");
  AliCDBMetaData* md = new AliCDBMetaData();
  md->SetResponsible("Ruben Shahoyan");
  md->SetComment(comment);
  AliCDBId id(path,firstrun,lastrun<=0 ? (AliCDBRunRange::Infinity()) : lastrun);
  //AliCDBStorage* st = man->GetStorage("local//.");
  man->Put(obj,id,md); 
  //
}

//__________________________________________________________
double edgeLow(double* x, double *par)
{
  // Low TDrift edge:
  // residuals assuming linear dependence of "natural" residual vs Xtrue and smeared
  // by the finite track resolution
  double x0    = par[0];
  double sigma = par[1];
  double offs  = par[2];
  double slop  = par[3];
  //
  if (sigma<1) return 0;
  if (x0<-sigma) return 0; 
  //
  double xex = x[0];
  xex -= x0;
  //
  double arg = xex/sigma;
  arg *= arg/2;
  double res = arg<50 ? slop*sigma*TMath::Exp(-arg)/TMath::Sqrt(2*TMath::Pi()) : 0;
  double erftrm = 1.+TMath::Erf(xex/sigma/TMath::Sqrt(2));
  //printf("%+e %+e %+e\n",x[0],x0,erftrm);
  if (xex<0 && TMath::Abs(erftrm)<1e-10) res = -xex*slop;
  else res /= erftrm/2.;
  res += (offs + (slop-1.)*xex);
  return res;
  //
}

//__________________________________________________________
double edgeHigh(double* x, double *par)
{
  // High TDrift edge
  // residual assuming linear dependence of "natural" residual vs Xtrue and smeared
  // by the finite track resolution
  double x0    = par[0];
  double sigma = par[1];
  double offs  = par[2];
  double slop  = par[3];
  double tailCorr  = par[4];
  //
  if (sigma<1) return 0;
  if (x0<-sigma) return 0; 
  //
  double xex = (x0 - x[0])*tailCorr;
  //
  double arg = xex/sigma;
  arg *= arg/2;
  double res = arg<50 ? slop*sigma*TMath::Exp(-arg)/TMath::Sqrt(2*TMath::Pi()) : 0;
  double erftrm = 1.+TMath::Erf(xex/sigma/TMath::Sqrt(2));
  if (xex<0 && TMath::Abs(erftrm)<1e-10) res = xex*slop;
  else res /= -erftrm/2.;
  res += (offs + (slop-1.)*xex);
  return res;
  //
}

//_________________________________________________________________________
void RedoProfileErrors(TH1* profH, TProfile* prof)
{
  // cure errors of low.stat bins
  int nbCnt = 0, nbn = prof->GetNbinsX();
  double meanStat = 0, meanSpread = 0, wghStat = 0;
  for (int i=1;i<=nbn;i++) {
    double stat = prof->GetBinEntries(i);
    if (stat>0) {meanStat+=stat; nbCnt++;}
  }
  if (nbCnt>0) meanStat/= nbCnt;   // mean occupancy
  //
  for (int i=1;i<=nbn;i++) {
    double stat = prof->GetBinEntries(i);
    if (stat<meanStat/2) continue;
    meanSpread += prof->GetBinError(i)*TMath::Sqrt(stat)*stat;
    wghStat += stat;
  }
  if (wghStat) meanSpread /= wghStat;             // mean spread
  //
  for (int i=1;i<=nbn;i++) {                       // assign error acording to occupancy
    double stat = prof->GetBinEntries(i);
    if (stat>meanStat/2 || stat<1) continue;
    profH->SetBinError(i, meanSpread/TMath::Sqrt(stat));
  }
}

//_________________________________________________________________________
void CureEdges(TH1* prof)
{
  // cure edges of the profile histo
  const double kMaxChi2 = 20.;
  const double kSlpDf = 0.05;
  static TF1* fitEdgeLow  = new TF1("fitEdgeLow" ,edgeLow , -5000, sddSeg.Dx()+5000,4);
  static TF1* fitEdgeHigh = new TF1("fitEdgeHigh",edgeHigh, -5000, sddSeg.Dx()+5000,5);
  //
  int ndf,ib0,ib1,nbn = prof->GetNbinsX();
  double sigma,offs,slp,chi2,x0;
  //
  // LowT edge
  // find 1st non-empty bin
  for (ib0=1;ib0<=nbn;ib0++) if (prof->GetBinError(ib0)>1e-9) break;
  x0 = prof->GetBinCenter(ib0);
  ib1 = prof->FindBin(wDXEdge); 
  if (ib1-ib0<minBinsEdge) ib1 = ib0+minBinsEdge;
  //
  fitEdgeLow->SetParameters(100,100,0,1);
  fitEdgeLow->SetParLimits(0,0, sddSeg.Dx());
  fitEdgeLow->SetParLimits(1,edgeSmearMinErr, edgeSmearMaxErr);
  fitEdgeLow->SetParLimits(3,1.-kSlpDf, 1.+kSlpDf);
  //
  prof->Fit(fitEdgeLow,"q","",prof->GetBinLowEdge(ib0)+1, prof->GetBinCenter(ib1+1)-1);
  chi2 = fitEdgeLow->GetChisquare();
  ndf = fitEdgeLow->GetNDF();
  if (ndf>0) chi2 /= ndf;
  //
  x0    = fitEdgeLow->GetParameter(0);
  sigma = fitEdgeLow->GetParameter(1);
  offs  = fitEdgeLow->GetParameter(2);
  slp   = fitEdgeLow->GetParameter(3);
  if ( chi2<kMaxChi2) { 
    x0 += 3*sigma;
    ib1 = prof->FindBin(x0);
    for (int i=ib0;i<=ib1;i++) {
      if (prof->GetBinError(i)<1e-9) continue;
      double xb = prof->GetBinCenter(i);
      double polval = offs+(slp-1.)*(xb-x0);
      if (xb>0) prof->AddBinContent(i, polval -  fitEdgeLow->Eval( xb ) );
      else prof->SetBinContent(i,polval);
    }
  }
  //
  // find last non-empty bin
  for (ib1=nbn;ib1>=1;ib1--) if (prof->GetBinError(ib1)>1e-9) break;
  x0 = prof->GetBinCenter(ib1);
  ib0 = prof->FindBin(sddSeg.Dx() - wDXEdge); 
  if (ib1-ib0<minBinsEdge) ib0 = ib1-minBinsEdge;
  //
  fitEdgeHigh->SetParameters(prof->GetBinCenter(ib0)+wDXEdge-100,100,0,1,1.);
  fitEdgeHigh->SetParLimits(0,0, sddSeg.Dx()+150);
  fitEdgeHigh->SetParLimits(1,edgeSmearMinErr, edgeSmearMaxErr);
  fitEdgeHigh->SetParLimits(3,1.-kSlpDf, 1.+kSlpDf);
  fitEdgeHigh->SetParLimits(4,0.3, 3.);
  prof->Fit(fitEdgeHigh,"q+","",prof->GetBinLowEdge(ib0)+1, prof->GetBinCenter(ib1+1)+1);
  //
  chi2 = fitEdgeHigh->GetChisquare();
  ndf = fitEdgeHigh->GetNDF();
  if (ndf>0) chi2 /= ndf;
  //
  x0    = fitEdgeHigh->GetParameter(0);
  sigma = fitEdgeHigh->GetParameter(1);
  offs  = fitEdgeHigh->GetParameter(2);
  slp   = fitEdgeHigh->GetParameter(3);
  if ( chi2<kMaxChi2 ) {
    x0 -= 3*sigma;
    ib0 = prof->FindBin(x0);
    for (int i=ib0;i<=ib1;i++) {
      if (prof->GetBinError(i)<1e-9) continue;
      double xb = prof->GetBinCenter(i);
      double polval = offs+(slp-1.)*(xb-x0);
      if (xb<sddSeg.Dx()) prof->AddBinContent(i, polval -  fitEdgeHigh->Eval( xb ) );
      else prof->SetBinContent(i,polval);
    }
  }
  //
}

//_________________________________________________________________________
void SafeRebin(TProfile* prof, Int_t factor, Bool_t xprof)
{
  // rebin taking into account left/right margins
  const int minBins = 5;
  int bmn,bmx;
  if (factor<1) return;
  Bool_t firstX=kTRUE,firstZ=kTRUE;
  //
  if (xprof) { // drift profiles
    bmn = prof->FindBin(1);
    bmx = prof->FindBin(sddSeg.Dx()-1); 
  }
  else { // Z profile
    double zrange = sddSeg.Dz()/2 - 1.;
    bmn = prof->FindBin(-zrange);
    bmx = prof->FindBin( zrange);
  }
  int nbTot = prof->GetNbinsX();
  int nbUse = bmx - bmn + 1;
  int edge = bmn-1; // number of edge bins from each side
  //
  // find closest divisor
  int fCClose = 2;
  int dst = 9999;
  for (int i=2;i<nbUse;i++) {
    if ((nbUse%i)==0 && (nbUse/fCClose)>=minBins) {
      int dsti = TMath::Abs(factor-i);
      if (dsti<dst) {fCClose=i; dst=dsti;}
    }
  }
  if (dst==9999) {
    printf("Could find good rebinning factor\n"); exit(1);
  }
  //
  if (fCClose!=factor) {
    if ( (xprof&&firstX) || ((!xprof)&&firstZ) ) printf("Rebin%c: For roundness will use factor %d instead of %d\n",xprof ? 'X':'Z',fCClose,factor);
    factor = fCClose;
  }
  //
  int nbUseNew = nbUse/factor;
  if (nbUseNew<minBins) {
    factor = nbUse/5;
    if (factor<2) factor=1;
    nbUseNew = nbUse/factor;
  }
  //
  if ( (xprof&&firstX) || ((!xprof)&&firstZ) ) printf("Rebin%c: Will rebin %d to %d\n",xprof ? 'X':'Z',nbUse,nbUseNew);
  if (factor<2) return;
  //
  int nbTotNew = nbUseNew + 2*edge;
  double *xnew = new double[nbTotNew+1];
  TAxis* xax = prof->GetXaxis();
  for (int i=1;i<=edge;i++) { // edges are not rebined
    xnew[i-1] = xax->GetBinLowEdge(i);
    xnew[nbTotNew-i+1] = xax->GetBinLowEdge(nbTot+2-i);
  }
  int cnt = 0, bcnt = edge+1;
  for (int i=edge+1;i<=nbTot-edge+1;i++) {
    if (cnt==0) {xnew[bcnt-1] = xax->GetBinLowEdge(i); bcnt++;}
    if (++cnt>=factor) cnt = 0;
  }
  TProfile *profNew = (TProfile*)prof->Rebin(nbTotNew,"rbTMPprof$",xnew);
  profNew->SetName(prof->GetName());
  profNew->SetTitle(prof->GetTitle());  
  *prof = *profNew;
  delete profNew;
  //
  if (xprof&&firstX) firstX = kFALSE;
  else if (firstZ) firstZ = kFALSE;
}

//____________________________________________________
Double_t EdgeFun(double *x, double *par)
{
  // Function to fit Xresiduals vs X, accounting for the limited sensor size and finite gaussian track resolution
  // Assumes that the hits density along sensor X has linear dependence rho(x) = a+b*x, and the track have resolution N(x,sig)
  // Then, the <residual> seen at coordinate X will be 
  // R(x) = Integrate[(y-x)*F,{y,t0,t1}]/Integrate[F,{y,t0,t1}];
  // with 
  // F = (a+b*y)*Exp(-(y-x)^2/2/sig^2)
  // where t0 and t1 are start and end coordinates of the physical module (in fact, only the coordinate
  // of the fitted edge is relevant.
  //
  const double sqrt2 = 1.41421356237309515e+00;
  const double sqrtPi = 1.77245385090551588e+00;
  double px = x[0];
  //
  // edge parameters
  double sig = par[0];   // resolution
  double t0  = par[1];   // active left edge
  double t1  = par[2];   // active right edge
  double tc0   = t0+par[3];  // constant occupancy left edge
  double tc1   = t1-par[4];  // constant occupancy right edge
  if (t0>t1)  return 1e6;
  if (tc0<t0) tc0 = t0;
  if (tc1>t1) tc1 = t1;
  double ped = par[5];
  //
  if (sig<1e-6) return 1e6;
  //
  // slope parameters
  double offset = par[6];
  double slope  = par[7];
  double curve  = par[8];
  //
  double top=0,norm=0;
  for (int it=0;it<3;it++) { // assume three regions of occupance: rise, const, fall
    double tmp0,tmp1,a,b;
    //
    if (it==0) {
      tmp0 = t0;
      tmp1 = tc0;
      double rise = tmp1-tmp0;
      if (rise<1e-9) continue;
      b = (1.-ped)/rise; // linear occupancy rise from ped at t0 to 1 at tc0
      a = ped-t0*b;
    }
    else if (it==1) {
      tmp0 = tc0;
      tmp1 = tc1;
      if (tmp0>=tmp1) continue;
      a = 1.;      // constant occupancy between tc0 and tc1
      b = 0; 
    }
    else {
      tmp0 = tc1;
      tmp1 = t1;
      double rise = tmp1-tmp0;
      if (rise<1e-9) continue;
      b = -(1.-ped)/rise;   // linear occupancy fall from 1 at tc1 to ped at t1
      a = ped+(1.-ped)*tmp1/rise;
    }
    double q0 = (tmp0-px)/sig/sqrt2;
    double q1 = (tmp1-px)/sig/sqrt2;
    double expq0 = TMath::Abs(q0)<27. ? TMath::Exp(-q0*q0) : 0;
    double expq1 = TMath::Abs(q1)<27. ? TMath::Exp(-q1*q1) : 0;
    //
    double erfcq0 = TMath::Abs(q0)<27. ? TMath::Erfc(TMath::Abs(q0)) : 0;
    double erfcq1 = TMath::Abs(q1)<27. ? TMath::Erfc(TMath::Abs(q1)) : 0;
    //
    double derfc = 0;
    if       (q0>0 && q1>0) derfc = erfcq0 - erfcq1;
    else if  (q0<0 && q1>0) derfc = (2.-erfcq0) - erfcq1;
    else if  (q0>0 && q1<0) derfc = erfcq0 - (2.-erfcq1);
    else if  (q0<0 && q1<0) derfc = erfcq1 - erfcq0;
    //
    double topLoc = sig*(expq0*(a+b*tmp0) - expq1*(a+b*tmp1) + b*sqrtPi/sqrt2*sig*derfc);
    double nrmLoc = b*(expq0-expq1)*sig + sqrtPi/sqrt2*(a+b*px)*derfc;
    top += topLoc;
    norm+= nrmLoc;
    if (verbose) {
      printf("it%d | a:%+e b:%+e | topLoc: %+e nrmLoc:%+e -> top: %+e norm: %+e\n",it, a,b,topLoc,nrmLoc,top,norm);
    }
  }
  //
  double res = 0;
  if (TMath::Abs(norm)==0) {
    printf("!! x= %f sig=%+e t0=%+e t1=%+e | Top=%e Norm=%e -> %+e\n",px,sig,t0,t1,top,norm,res);
  }
  else res = top/norm;
  //
  return res + offset + slope*px + curve*px*px;
}

/*
//____________________________________________________
Double_t EdgeFun(double *x, double *par)
{
  // Function to fit Xresiduals vs X, accounting for the limited sensor size and finite gaussian track resolution
  // Assumes that the hits density along sensor X has linear dependence rho(x) = a+b*x, and the track have resolution N(x,sig)
  // Then, the <residual> seen at coordinate X will be 
  // R(x) = Integrate[(y-x)*F,{y,t0,t1}]/Integrate[F,{y,t0,t1}];
  // with 
  // F = (a+b*y)*Exp(-(y-x)^2/2/sig^2)
  // where t0 and t1 are start and end coordinates of the physical module (in fact, only the coordinate
  // of the fitted edge is relevant.
  //
  const double sqrt2 = 1.41421356237309515e+00;
  const double sqrtPi = 1.77245385090551588e+00;
  double px = x[0];
  //
  // edge parameters
  double sig = par[0];
  double t0  = par[1];
  double t1  = par[2];
  double a   = par[3];
  double b   = par[4];
  if (sig<1e-6) return 0;
  //
  // slope parameters
  double offset = par[5];
  double slope  = par[6];
  //
  double q0 = (t0-px)/sig/sqrt2;
  double q1 = (t1-px)/sig/sqrt2;
  double expq0 = TMath::Abs(q0)<27. ? TMath::Exp(-q0*q0) : 0;
  double expq1 = TMath::Abs(q1)<27. ? TMath::Exp(-q1*q1) : 0;
  //
  double erfcq0 = TMath::Abs(q0)<27. ? TMath::Erfc(TMath::Abs(q0)) : 0;
  double erfcq1 = TMath::Abs(q1)<27. ? TMath::Erfc(TMath::Abs(q1)) : 0;
  //
  double derfc = 0;
  if       (q0>=0 && q1>=0) derfc = erfcq0 - erfcq1;
  else if  (q0<=0 && q1>=0) derfc = (2.-erfcq0) - erfcq1;
  else if  (q0>=0 && q1<=0) derfc = erfcq0 - (2.-erfcq1);
  else if  (q0<=0 && q1<=0) derfc = erfcq1 - erfcq0;
  //
  double top = sig*(expq0*(a+b*t0) - expq1*(a+b*t1) + b*sqrtPi/sqrt2*sig*derfc);
  double norm= b*(expq0-expq1)*sig + sqrtPi/sqrt2*(a+b*px)*derfc;
  //
  if (verbose) {
    printf("x=%+.2f | q0:%+e q1:%+e exp0:%+e exp1:%+e erf0:%+e erf1:%+e (->%+.e)-> %+e/%+e\n",
	   px,q0,q1,expq0,expq1,erfcq0,erfcq1, derfc, top,norm);
  }
  //
  double res = 0;
  if (TMath::Abs(norm)<1e-300) {
    printf("!! x= %f sig=%+e t0=%+e t1=%+e a=%+e b=%+e | Top=%e Norm=%e -> %+e\n",px,sig,t0,t1,a,b,top,norm,res);
  }
  else res = top/norm;
  //
  return res + offset + slope*px;
}
*/

//____________________________________________________________
TH1* GetProfHEntries(TProfile* prof)
{
  // create histo with entries of the profile histo
  TH1* hent = ProfileAsTH1(prof, "_Entries");
  if (!hent) return 0;
  hent->Reset();
  int nb = hent->GetNbinsX()+1;
  for (int ib=0;ib<=nb;ib++) hent->SetBinContent(ib, prof->GetBinEntries(ib));
  return hent;
}

//___________________________________________________________
TH1* FitDXEdges(TProfile* prof)
{
  //
  static TF1 *flft=0,*frgt=0;
  const double kMinTot = 1000;
  const double kMinThresh = 0.15;
  const double kEdgeTol = 2000.; 
  const double kFitLgt = 10000.;
  const double kMinRes = 300.;
  const double kMaxRes = 600.;
  const double kMaxDX = 5000.;
  const double kMaxRiseRange = 10000;
  const double kMaxChi2 = 6;
  double xspan = sddSeg.Dx();
  TString fstatus;
  //
  TH1* histo = ProfileAsTH1(prof,"_h1");
  //
  int nb = prof->GetNbinsX();
  double tot = prof->GetEntries();
  histo->SetBinContent(0,0);        // lower active edge
  histo->SetBinContent(nb+1,xspan); // upper active edge
  if (tot<kMinTot) return histo;
  double meanbin = tot/nb;
  //
  //  RedoProfileErrors(histo,prof);
  // find left/right significant bins
  int bleft = -1;
  for (int i=1;i<=nb;i++) {
    double enti = prof->GetBinEntries(i);
    if (enti>kMinThresh*meanbin) {bleft=i; break;}
  }
  if (bleft<0) return kFALSE;
  if (bleft<prof->FindBin(1)) bleft = 1;
  double lEdgeMn = TMath::Max(0.,prof->GetBinLowEdge(bleft)-kEdgeTol/2);
  double lEdgeMx = lEdgeMn + kEdgeTol;
  //
  int bright = -1;
  for (int i=nb;i>0;i--) {
    double enti = prof->GetBinEntries(i);
    if (enti>kMinThresh*meanbin) {bright=i; break;}
  }
  if (bright<0) return kFALSE;
  if (bright>prof->FindBin(xspan-1)) bleft = prof->FindBin(xspan-1);
  double rEdgeMx = TMath::Min(xspan,prof->GetBinLowEdge(bright)+kEdgeTol/2);
  double rEdgeMn = rEdgeMx - kEdgeTol;
  //
  printf("Fit left edge\n");
  if (!flft) flft = new TF1("lftEdge",EdgeFun,		      
		      prof->GetBinLowEdge(1),
		      prof->GetBinLowEdge(nb+1),
		      9);
  flft->SetParameters((kMaxRes+kMinRes)/2, (lEdgeMn+lEdgeMx)/2,(rEdgeMn+rEdgeMx)/2,lEdgeMx,0,0.5);
  flft->SetParLimits(0,kMinRes,kMaxRes);
  flft->SetParLimits(1,lEdgeMn,lEdgeMx);
  flft->SetParLimits(2,rEdgeMn,rEdgeMx);
  flft->SetParLimits(3,0,kMaxRiseRange);
  flft->FixParameter(4,0);
  flft->SetParLimits(5,0.,1.);
  flft->SetParLimits(6,-kMaxDX,kMaxDX);
  flft->SetParLimits(7,-kMaxDX/xspan,kMaxDX/xspan);
  flft->SetParLimits(8,-kMaxDX/xspan/xspan,kMaxDX/xspan/xspan);
  flft->SetLineWidth(1);
  double fitLStart = TMath::Max(prof->GetBinLowEdge(1),lEdgeMn-5.*(kMinRes+kMaxRes)/2.);
  double fitLEnd   = TMath::Min(fitLStart+kFitLgt,rEdgeMn);
  int cntL = 0;
  double chiL = 0;
  do {
    prof->Fit(flft,"q+","",fitLStart,fitLEnd);
    fstatus = (char*)gMinuit->fCstatu.Data();
    if (fstatus.Contains("CONVERGED") || fstatus.Contains("SUCCESSFUL")) {
      cntL=100;
      chiL = flft->GetNDF()>0 ? flft->GetChisquare()/flft->GetNDF() : 0;
    }
    else {
      TF1* oldf = (TF1*)prof->GetListOfFunctions()->FindObject(flft->GetName());
      if (oldf) prof->GetListOfFunctions()->Remove(oldf);
    }
  } while(++cntL<3);
  if (chiL<kMaxChi2 && cntL>=100) {
    // flft->SetParameter(6,0.);
    // flft->SetParameter(7,0.);
    // flft->SetParameter(8,0.);
    // int mxbin = histo->FindBin(flft->GetParameter(1)+6*flft->GetParameter(0));
    double edgL = TMath::Max(skipDXEdge,flft->GetParameter(1)+3*flft->GetParameter(0));
    printf("Smoothing left edge up to %.4f\n",edgL);
    int mxbin = histo->FindBin(edgL);
    for (int i=1;i<=mxbin;i++) {
      double x = histo->GetBinCenter(i);
      double val = flft->GetParameter(6)+x*(flft->GetParameter(7)+x*flft->GetParameter(8));
      histo->SetBinContent(i,val);
    }
    histo->SetBinContent(0, TMath::Max(0.0, flft->GetParameter(1)-6*flft->GetParameter(0))); // effective lower sensor edge
  }
  else {
    printf("Left edge bad: %f %d %s\n",chiL,cntL,fstatus.Data());
  }
  //
  printf("Fit right edge\n");
  if (!frgt) frgt = new TF1("rgtEdge",EdgeFun,		      
			    prof->GetBinLowEdge(1),
			    prof->GetBinLowEdge(nb+1),
			    9);
  frgt->SetParameters((kMaxRes+kMinRes)/2, (lEdgeMn+lEdgeMx)/2,(rEdgeMn+rEdgeMx)/2,0,(rEdgeMx-rEdgeMn)/2.,0.5);
  frgt->SetParLimits(0,kMinRes,kMaxRes);
  frgt->SetParLimits(1,lEdgeMn,lEdgeMx);
  frgt->SetParLimits(2,rEdgeMn,rEdgeMx);
  frgt->FixParameter(3,0);
  frgt->SetParLimits(4,0,kMaxRiseRange);
  frgt->SetParLimits(5,0.,1.);
  frgt->SetParLimits(6,-kMaxDX,kMaxDX);
  frgt->SetParLimits(7,-kMaxDX/xspan,kMaxDX/xspan);
  frgt->SetParLimits(8,-kMaxDX/xspan/xspan,kMaxDX/xspan/xspan);
  frgt->SetLineWidth(1);
  double fitREnd   = TMath::Min(prof->GetBinLowEdge(nb+1),rEdgeMx+5.*(kMinRes+kMaxRes)/2.);
  double fitRStart = TMath::Max(fitREnd-kFitLgt,lEdgeMx);
  double chiR = 0;
  int cntR = 0;
  do {
    prof->Fit(frgt,"q+","",fitRStart,fitREnd);
    fstatus = (char*)gMinuit->fCstatu.Data();
    if (fstatus.Contains("CONVERGED") || fstatus.Contains("SUCCESSFUL")) {
      cntR=100;
      chiR = frgt->GetNDF()>0 ? frgt->GetChisquare()/frgt->GetNDF() : 0;
    }
    else {
      TF1* oldf = (TF1*)prof->GetListOfFunctions()->FindObject(frgt->GetName());
      if (oldf) prof->GetListOfFunctions()->Remove(oldf);
    }
  } while((++cntR<3));
  //
  if (chiR<kMaxChi2 && cntR>=100) {
    // frgt->SetParameter(6,0.);
    // frgt->SetParameter(7,0.);
    // frgt->SetParameter(8,0.);
    // int mnbin = histo->FindBin(frgt->GetParameter(2)-6*frgt->GetParameter(0));
    double edgR = TMath::Min(xspan-skipDXEdge,frgt->GetParameter(2)-3*frgt->GetParameter(0));
    printf("Smoothing right edge from %.4f\n",edgR);
    int mnbin = histo->FindBin(edgR);
    for (int i=mnbin;i<=nb;i++) {
      double x = histo->GetBinCenter(i);
      double val = frgt->GetParameter(6)+x*(frgt->GetParameter(7)+x*frgt->GetParameter(8));
      histo->SetBinContent(i,val);
    }
    histo->SetBinContent(nb+1, TMath::Min((double)sddSeg.Dx(), frgt->GetParameter(2)+6*frgt->GetParameter(0))); // effective upper sensor edge
  }
  else {
    printf("Right edge bad: %f %d %s\n",chiR,cntR,fstatus.Data());
  }
  //
  return histo;
}

double ftPolComb(double* x, double *par)
{
  // fit with combination of 2 polinomials of order par[0]
  int ord = int(par[0]);
  int npars = ord+1;
  double brk = par[1];
  //
  double px = x[0];
  double res = 0;
  int start = 2;
  if (px<=brk) start += npars;
  for (int i=npars;i--;) {
    //    printf("%.1f (%+.1f) | %d %d %e\n",px,brk,start,start+i,par[start+i]);
    res = px*res+par[start+i];
  }
  return res;
}

//______________________________________________________________
TH1* SimpleMap(TH1* prof)
{
  // get limits as over/under flows
  int nb = prof->GetNbinsX();
  double lft = prof->GetBinContent(0);
  double rgt = prof->GetBinContent(nb+1);  
  //
  int b0 = prof->FindBin(lft+1);
  int b1 = prof->FindBin(rgt-1);  
  TString nm = prof->GetName(); nm += "_map";
  TH1* smap = (TH1*)prof->Clone(nm.Data());
  //
  while(1) {
    //
    TF1* smapf = 0;
    double mean = 0;
    // 1) try pol1
    smapf = new TF1("smapf","pol1",prof->GetBinLowEdge(0),prof->GetBinLowEdge(nb+1));
    if (TestMapFunction(prof,smapf,lft,rgt)) {delete smapf; break;}
    else {
      mean = smapf->GetParameter(0);
      delete smapf;
    }
    //
    // 2) try pol2
    smapf = new TF1("smapf","pol2",prof->GetBinLowEdge(0),prof->GetBinLowEdge(nb+1));
    if (TestMapFunction(prof,smapf,lft,rgt)) {delete smapf; break;}
    else delete smapf;
    //
    /*
    double middle = (lft+rgt)/2;
    int bmid = prof->FindBin(middle);
    double a0 = prof->GetBinContent(b0);
    double a1 = prof->GetBinContent(bmid+1);
    double s0 = prof->GetBinContent(bmid-1);
    double s1 = prof->GetBinContent(b1);
    //
    s0 = (s0-a0)/((rgt-lft)/2); // slope for 1st part
    a0 -= b0*lft;               // offset for 1st part
    s1 = (s1-a1)/((rgt-lft)/2); // slope for 2nd part
    a1 -= s1*middle;            // offset for 2nd part
    //
    // 3) try pol1 + pol1
    smapf = new TF1("smapf",ftPolComb,prof->GetBinLowEdge(0),prof->GetBinLowEdge(nb+1),2+2*2);
    smapf->SetParameters(1,middle,a0,b0,a1,b1);
    smapf->FixParameter(0,1);
    smapf->SetParLimits(1,lft+4*prof->GetBinWidth(nb/2),rgt-4*prof->GetBinWidth(nb/2));
    if (TestMapFunction(prof,smapf,lft,rgt)) {delete smapf; break;}
    else delete smapf;
    //
    // 3) try pol2 + pol2
    smapf = new TF1("smapf",ftPolComb,prof->GetBinLowEdge(0),prof->GetBinLowEdge(nb+1),2+2*3);
    smapf->SetParameters(2,middle,a0,b0,0,a1,b1,0);
    smapf->FixParameter(0,2);
    smapf->SetParLimits(1,lft+4*prof->GetBinWidth(nb/2),rgt-4*prof->GetBinWidth(nb/2));
    if (TestMapFunction(prof,smapf,lft,rgt)) {delete smapf; break;}
    else delete smapf;
    //
    */
    break;
  }
  TF1* fnsel = (TF1*) prof->GetListOfFunctions()->FindObject("smapf");
  if (!fnsel) {delete smap; return 0;} // no simple solution
  //
  // function is ok, set edges to 0
  b0 = smap->FindBin(1);
  b1 = smap->FindBin(sddSeg.Dx()-1);
  double f0 = fnsel->Eval( smap->GetBinCenter(b0) );
  double f1 = fnsel->Eval( smap->GetBinCenter(b1) );
  double slp = (f1-f0)/(smap->GetBinCenter(b1) -  smap->GetBinCenter(b0));
  smap->Reset();
  for (int ib=b0+1;ib<b1;ib++) {
    double x = smap->GetBinCenter(ib);
    double diff = fnsel->Eval(x) - (f0+slp*x);
    smap->SetBinContent(ib, diff);
  }
  return smap;
}


//______________________________________________________________________
Bool_t TestMapFunction(TH1* smap, TF1* fun, double lft, double rgt)
{
  // test if fun describes the shape
  TString fstatus;
  double chi2;
  smap->Fit(fun,"0qN","",lft,rgt);
  fstatus = (char*)gMinuit->fCstatu.Data();
  if ( fstatus.Contains("CONVERGED") || fstatus.Contains("SUCCESSFUL")) {
    chi2 = fun->GetNDF()>0 ? fun->GetChisquare()/fun->GetNDF() : 0;
    if (chi2<=kMaxChi2SimpleMap) {
      fun->SetLineWidth(1);
      fun->SetLineStyle(2);
      smap->Fit(fun,"q","",lft,rgt);
      return kTRUE;
    }
  }
  return kFALSE;
}
 CalibrateSDD.C:1
 CalibrateSDD.C:2
 CalibrateSDD.C:3
 CalibrateSDD.C:4
 CalibrateSDD.C:5
 CalibrateSDD.C:6
 CalibrateSDD.C:7
 CalibrateSDD.C:8
 CalibrateSDD.C:9
 CalibrateSDD.C:10
 CalibrateSDD.C:11
 CalibrateSDD.C:12
 CalibrateSDD.C:13
 CalibrateSDD.C:14
 CalibrateSDD.C:15
 CalibrateSDD.C:16
 CalibrateSDD.C:17
 CalibrateSDD.C:18
 CalibrateSDD.C:19
 CalibrateSDD.C:20
 CalibrateSDD.C:21
 CalibrateSDD.C:22
 CalibrateSDD.C:23
 CalibrateSDD.C:24
 CalibrateSDD.C:25
 CalibrateSDD.C:26
 CalibrateSDD.C:27
 CalibrateSDD.C:28
 CalibrateSDD.C:29
 CalibrateSDD.C:30
 CalibrateSDD.C:31
 CalibrateSDD.C:32
 CalibrateSDD.C:33
 CalibrateSDD.C:34
 CalibrateSDD.C:35
 CalibrateSDD.C:36
 CalibrateSDD.C:37
 CalibrateSDD.C:38
 CalibrateSDD.C:39
 CalibrateSDD.C:40
 CalibrateSDD.C:41
 CalibrateSDD.C:42
 CalibrateSDD.C:43
 CalibrateSDD.C:44
 CalibrateSDD.C:45
 CalibrateSDD.C:46
 CalibrateSDD.C:47
 CalibrateSDD.C:48
 CalibrateSDD.C:49
 CalibrateSDD.C:50
 CalibrateSDD.C:51
 CalibrateSDD.C:52
 CalibrateSDD.C:53
 CalibrateSDD.C:54
 CalibrateSDD.C:55
 CalibrateSDD.C:56
 CalibrateSDD.C:57
 CalibrateSDD.C:58
 CalibrateSDD.C:59
 CalibrateSDD.C:60
 CalibrateSDD.C:61
 CalibrateSDD.C:62
 CalibrateSDD.C:63
 CalibrateSDD.C:64
 CalibrateSDD.C:65
 CalibrateSDD.C:66
 CalibrateSDD.C:67
 CalibrateSDD.C:68
 CalibrateSDD.C:69
 CalibrateSDD.C:70
 CalibrateSDD.C:71
 CalibrateSDD.C:72
 CalibrateSDD.C:73
 CalibrateSDD.C:74
 CalibrateSDD.C:75
 CalibrateSDD.C:76
 CalibrateSDD.C:77
 CalibrateSDD.C:78
 CalibrateSDD.C:79
 CalibrateSDD.C:80
 CalibrateSDD.C:81
 CalibrateSDD.C:82
 CalibrateSDD.C:83
 CalibrateSDD.C:84
 CalibrateSDD.C:85
 CalibrateSDD.C:86
 CalibrateSDD.C:87
 CalibrateSDD.C:88
 CalibrateSDD.C:89
 CalibrateSDD.C:90
 CalibrateSDD.C:91
 CalibrateSDD.C:92
 CalibrateSDD.C:93
 CalibrateSDD.C:94
 CalibrateSDD.C:95
 CalibrateSDD.C:96
 CalibrateSDD.C:97
 CalibrateSDD.C:98
 CalibrateSDD.C:99
 CalibrateSDD.C:100
 CalibrateSDD.C:101
 CalibrateSDD.C:102
 CalibrateSDD.C:103
 CalibrateSDD.C:104
 CalibrateSDD.C:105
 CalibrateSDD.C:106
 CalibrateSDD.C:107
 CalibrateSDD.C:108
 CalibrateSDD.C:109
 CalibrateSDD.C:110
 CalibrateSDD.C:111
 CalibrateSDD.C:112
 CalibrateSDD.C:113
 CalibrateSDD.C:114
 CalibrateSDD.C:115
 CalibrateSDD.C:116
 CalibrateSDD.C:117
 CalibrateSDD.C:118
 CalibrateSDD.C:119
 CalibrateSDD.C:120
 CalibrateSDD.C:121
 CalibrateSDD.C:122
 CalibrateSDD.C:123
 CalibrateSDD.C:124
 CalibrateSDD.C:125
 CalibrateSDD.C:126
 CalibrateSDD.C:127
 CalibrateSDD.C:128
 CalibrateSDD.C:129
 CalibrateSDD.C:130
 CalibrateSDD.C:131
 CalibrateSDD.C:132
 CalibrateSDD.C:133
 CalibrateSDD.C:134
 CalibrateSDD.C:135
 CalibrateSDD.C:136
 CalibrateSDD.C:137
 CalibrateSDD.C:138
 CalibrateSDD.C:139
 CalibrateSDD.C:140
 CalibrateSDD.C:141
 CalibrateSDD.C:142
 CalibrateSDD.C:143
 CalibrateSDD.C:144
 CalibrateSDD.C:145
 CalibrateSDD.C:146
 CalibrateSDD.C:147
 CalibrateSDD.C:148
 CalibrateSDD.C:149
 CalibrateSDD.C:150
 CalibrateSDD.C:151
 CalibrateSDD.C:152
 CalibrateSDD.C:153
 CalibrateSDD.C:154
 CalibrateSDD.C:155
 CalibrateSDD.C:156
 CalibrateSDD.C:157
 CalibrateSDD.C:158
 CalibrateSDD.C:159
 CalibrateSDD.C:160
 CalibrateSDD.C:161
 CalibrateSDD.C:162
 CalibrateSDD.C:163
 CalibrateSDD.C:164
 CalibrateSDD.C:165
 CalibrateSDD.C:166
 CalibrateSDD.C:167
 CalibrateSDD.C:168
 CalibrateSDD.C:169
 CalibrateSDD.C:170
 CalibrateSDD.C:171
 CalibrateSDD.C:172
 CalibrateSDD.C:173
 CalibrateSDD.C:174
 CalibrateSDD.C:175
 CalibrateSDD.C:176
 CalibrateSDD.C:177
 CalibrateSDD.C:178
 CalibrateSDD.C:179
 CalibrateSDD.C:180
 CalibrateSDD.C:181
 CalibrateSDD.C:182
 CalibrateSDD.C:183
 CalibrateSDD.C:184
 CalibrateSDD.C:185
 CalibrateSDD.C:186
 CalibrateSDD.C:187
 CalibrateSDD.C:188
 CalibrateSDD.C:189
 CalibrateSDD.C:190
 CalibrateSDD.C:191
 CalibrateSDD.C:192
 CalibrateSDD.C:193
 CalibrateSDD.C:194
 CalibrateSDD.C:195
 CalibrateSDD.C:196
 CalibrateSDD.C:197
 CalibrateSDD.C:198
 CalibrateSDD.C:199
 CalibrateSDD.C:200
 CalibrateSDD.C:201
 CalibrateSDD.C:202
 CalibrateSDD.C:203
 CalibrateSDD.C:204
 CalibrateSDD.C:205
 CalibrateSDD.C:206
 CalibrateSDD.C:207
 CalibrateSDD.C:208
 CalibrateSDD.C:209
 CalibrateSDD.C:210
 CalibrateSDD.C:211
 CalibrateSDD.C:212
 CalibrateSDD.C:213
 CalibrateSDD.C:214
 CalibrateSDD.C:215
 CalibrateSDD.C:216
 CalibrateSDD.C:217
 CalibrateSDD.C:218
 CalibrateSDD.C:219
 CalibrateSDD.C:220
 CalibrateSDD.C:221
 CalibrateSDD.C:222
 CalibrateSDD.C:223
 CalibrateSDD.C:224
 CalibrateSDD.C:225
 CalibrateSDD.C:226
 CalibrateSDD.C:227
 CalibrateSDD.C:228
 CalibrateSDD.C:229
 CalibrateSDD.C:230
 CalibrateSDD.C:231
 CalibrateSDD.C:232
 CalibrateSDD.C:233
 CalibrateSDD.C:234
 CalibrateSDD.C:235
 CalibrateSDD.C:236
 CalibrateSDD.C:237
 CalibrateSDD.C:238
 CalibrateSDD.C:239
 CalibrateSDD.C:240
 CalibrateSDD.C:241
 CalibrateSDD.C:242
 CalibrateSDD.C:243
 CalibrateSDD.C:244
 CalibrateSDD.C:245
 CalibrateSDD.C:246
 CalibrateSDD.C:247
 CalibrateSDD.C:248
 CalibrateSDD.C:249
 CalibrateSDD.C:250
 CalibrateSDD.C:251
 CalibrateSDD.C:252
 CalibrateSDD.C:253
 CalibrateSDD.C:254
 CalibrateSDD.C:255
 CalibrateSDD.C:256
 CalibrateSDD.C:257
 CalibrateSDD.C:258
 CalibrateSDD.C:259
 CalibrateSDD.C:260
 CalibrateSDD.C:261
 CalibrateSDD.C:262
 CalibrateSDD.C:263
 CalibrateSDD.C:264
 CalibrateSDD.C:265
 CalibrateSDD.C:266
 CalibrateSDD.C:267
 CalibrateSDD.C:268
 CalibrateSDD.C:269
 CalibrateSDD.C:270
 CalibrateSDD.C:271
 CalibrateSDD.C:272
 CalibrateSDD.C:273
 CalibrateSDD.C:274
 CalibrateSDD.C:275
 CalibrateSDD.C:276
 CalibrateSDD.C:277
 CalibrateSDD.C:278
 CalibrateSDD.C:279
 CalibrateSDD.C:280
 CalibrateSDD.C:281
 CalibrateSDD.C:282
 CalibrateSDD.C:283
 CalibrateSDD.C:284
 CalibrateSDD.C:285
 CalibrateSDD.C:286
 CalibrateSDD.C:287
 CalibrateSDD.C:288
 CalibrateSDD.C:289
 CalibrateSDD.C:290
 CalibrateSDD.C:291
 CalibrateSDD.C:292
 CalibrateSDD.C:293
 CalibrateSDD.C:294
 CalibrateSDD.C:295
 CalibrateSDD.C:296
 CalibrateSDD.C:297
 CalibrateSDD.C:298
 CalibrateSDD.C:299
 CalibrateSDD.C:300
 CalibrateSDD.C:301
 CalibrateSDD.C:302
 CalibrateSDD.C:303
 CalibrateSDD.C:304
 CalibrateSDD.C:305
 CalibrateSDD.C:306
 CalibrateSDD.C:307
 CalibrateSDD.C:308
 CalibrateSDD.C:309
 CalibrateSDD.C:310
 CalibrateSDD.C:311
 CalibrateSDD.C:312
 CalibrateSDD.C:313
 CalibrateSDD.C:314
 CalibrateSDD.C:315
 CalibrateSDD.C:316
 CalibrateSDD.C:317
 CalibrateSDD.C:318
 CalibrateSDD.C:319
 CalibrateSDD.C:320
 CalibrateSDD.C:321
 CalibrateSDD.C:322
 CalibrateSDD.C:323
 CalibrateSDD.C:324
 CalibrateSDD.C:325
 CalibrateSDD.C:326
 CalibrateSDD.C:327
 CalibrateSDD.C:328
 CalibrateSDD.C:329
 CalibrateSDD.C:330
 CalibrateSDD.C:331
 CalibrateSDD.C:332
 CalibrateSDD.C:333
 CalibrateSDD.C:334
 CalibrateSDD.C:335
 CalibrateSDD.C:336
 CalibrateSDD.C:337
 CalibrateSDD.C:338
 CalibrateSDD.C:339
 CalibrateSDD.C:340
 CalibrateSDD.C:341
 CalibrateSDD.C:342
 CalibrateSDD.C:343
 CalibrateSDD.C:344
 CalibrateSDD.C:345
 CalibrateSDD.C:346
 CalibrateSDD.C:347
 CalibrateSDD.C:348
 CalibrateSDD.C:349
 CalibrateSDD.C:350
 CalibrateSDD.C:351
 CalibrateSDD.C:352
 CalibrateSDD.C:353
 CalibrateSDD.C:354
 CalibrateSDD.C:355
 CalibrateSDD.C:356
 CalibrateSDD.C:357
 CalibrateSDD.C:358
 CalibrateSDD.C:359
 CalibrateSDD.C:360
 CalibrateSDD.C:361
 CalibrateSDD.C:362
 CalibrateSDD.C:363
 CalibrateSDD.C:364
 CalibrateSDD.C:365
 CalibrateSDD.C:366
 CalibrateSDD.C:367
 CalibrateSDD.C:368
 CalibrateSDD.C:369
 CalibrateSDD.C:370
 CalibrateSDD.C:371
 CalibrateSDD.C:372
 CalibrateSDD.C:373
 CalibrateSDD.C:374
 CalibrateSDD.C:375
 CalibrateSDD.C:376
 CalibrateSDD.C:377
 CalibrateSDD.C:378
 CalibrateSDD.C:379
 CalibrateSDD.C:380
 CalibrateSDD.C:381
 CalibrateSDD.C:382
 CalibrateSDD.C:383
 CalibrateSDD.C:384
 CalibrateSDD.C:385
 CalibrateSDD.C:386
 CalibrateSDD.C:387
 CalibrateSDD.C:388
 CalibrateSDD.C:389
 CalibrateSDD.C:390
 CalibrateSDD.C:391
 CalibrateSDD.C:392
 CalibrateSDD.C:393
 CalibrateSDD.C:394
 CalibrateSDD.C:395
 CalibrateSDD.C:396
 CalibrateSDD.C:397
 CalibrateSDD.C:398
 CalibrateSDD.C:399
 CalibrateSDD.C:400
 CalibrateSDD.C:401
 CalibrateSDD.C:402
 CalibrateSDD.C:403
 CalibrateSDD.C:404
 CalibrateSDD.C:405
 CalibrateSDD.C:406
 CalibrateSDD.C:407
 CalibrateSDD.C:408
 CalibrateSDD.C:409
 CalibrateSDD.C:410
 CalibrateSDD.C:411
 CalibrateSDD.C:412
 CalibrateSDD.C:413
 CalibrateSDD.C:414
 CalibrateSDD.C:415
 CalibrateSDD.C:416
 CalibrateSDD.C:417
 CalibrateSDD.C:418
 CalibrateSDD.C:419
 CalibrateSDD.C:420
 CalibrateSDD.C:421
 CalibrateSDD.C:422
 CalibrateSDD.C:423
 CalibrateSDD.C:424
 CalibrateSDD.C:425
 CalibrateSDD.C:426
 CalibrateSDD.C:427
 CalibrateSDD.C:428
 CalibrateSDD.C:429
 CalibrateSDD.C:430
 CalibrateSDD.C:431
 CalibrateSDD.C:432
 CalibrateSDD.C:433
 CalibrateSDD.C:434
 CalibrateSDD.C:435
 CalibrateSDD.C:436
 CalibrateSDD.C:437
 CalibrateSDD.C:438
 CalibrateSDD.C:439
 CalibrateSDD.C:440
 CalibrateSDD.C:441
 CalibrateSDD.C:442
 CalibrateSDD.C:443
 CalibrateSDD.C:444
 CalibrateSDD.C:445
 CalibrateSDD.C:446
 CalibrateSDD.C:447
 CalibrateSDD.C:448
 CalibrateSDD.C:449
 CalibrateSDD.C:450
 CalibrateSDD.C:451
 CalibrateSDD.C:452
 CalibrateSDD.C:453
 CalibrateSDD.C:454
 CalibrateSDD.C:455
 CalibrateSDD.C:456
 CalibrateSDD.C:457
 CalibrateSDD.C:458
 CalibrateSDD.C:459
 CalibrateSDD.C:460
 CalibrateSDD.C:461
 CalibrateSDD.C:462
 CalibrateSDD.C:463
 CalibrateSDD.C:464
 CalibrateSDD.C:465
 CalibrateSDD.C:466
 CalibrateSDD.C:467
 CalibrateSDD.C:468
 CalibrateSDD.C:469
 CalibrateSDD.C:470
 CalibrateSDD.C:471
 CalibrateSDD.C:472
 CalibrateSDD.C:473
 CalibrateSDD.C:474
 CalibrateSDD.C:475
 CalibrateSDD.C:476
 CalibrateSDD.C:477
 CalibrateSDD.C:478
 CalibrateSDD.C:479
 CalibrateSDD.C:480
 CalibrateSDD.C:481
 CalibrateSDD.C:482
 CalibrateSDD.C:483
 CalibrateSDD.C:484
 CalibrateSDD.C:485
 CalibrateSDD.C:486
 CalibrateSDD.C:487
 CalibrateSDD.C:488
 CalibrateSDD.C:489
 CalibrateSDD.C:490
 CalibrateSDD.C:491
 CalibrateSDD.C:492
 CalibrateSDD.C:493
 CalibrateSDD.C:494
 CalibrateSDD.C:495
 CalibrateSDD.C:496
 CalibrateSDD.C:497
 CalibrateSDD.C:498
 CalibrateSDD.C:499
 CalibrateSDD.C:500
 CalibrateSDD.C:501
 CalibrateSDD.C:502
 CalibrateSDD.C:503
 CalibrateSDD.C:504
 CalibrateSDD.C:505
 CalibrateSDD.C:506
 CalibrateSDD.C:507
 CalibrateSDD.C:508
 CalibrateSDD.C:509
 CalibrateSDD.C:510
 CalibrateSDD.C:511
 CalibrateSDD.C:512
 CalibrateSDD.C:513
 CalibrateSDD.C:514
 CalibrateSDD.C:515
 CalibrateSDD.C:516
 CalibrateSDD.C:517
 CalibrateSDD.C:518
 CalibrateSDD.C:519
 CalibrateSDD.C:520
 CalibrateSDD.C:521
 CalibrateSDD.C:522
 CalibrateSDD.C:523
 CalibrateSDD.C:524
 CalibrateSDD.C:525
 CalibrateSDD.C:526
 CalibrateSDD.C:527
 CalibrateSDD.C:528
 CalibrateSDD.C:529
 CalibrateSDD.C:530
 CalibrateSDD.C:531
 CalibrateSDD.C:532
 CalibrateSDD.C:533
 CalibrateSDD.C:534
 CalibrateSDD.C:535
 CalibrateSDD.C:536
 CalibrateSDD.C:537
 CalibrateSDD.C:538
 CalibrateSDD.C:539
 CalibrateSDD.C:540
 CalibrateSDD.C:541
 CalibrateSDD.C:542
 CalibrateSDD.C:543
 CalibrateSDD.C:544
 CalibrateSDD.C:545
 CalibrateSDD.C:546
 CalibrateSDD.C:547
 CalibrateSDD.C:548
 CalibrateSDD.C:549
 CalibrateSDD.C:550
 CalibrateSDD.C:551
 CalibrateSDD.C:552
 CalibrateSDD.C:553
 CalibrateSDD.C:554
 CalibrateSDD.C:555
 CalibrateSDD.C:556
 CalibrateSDD.C:557
 CalibrateSDD.C:558
 CalibrateSDD.C:559
 CalibrateSDD.C:560
 CalibrateSDD.C:561
 CalibrateSDD.C:562
 CalibrateSDD.C:563
 CalibrateSDD.C:564
 CalibrateSDD.C:565
 CalibrateSDD.C:566
 CalibrateSDD.C:567
 CalibrateSDD.C:568
 CalibrateSDD.C:569
 CalibrateSDD.C:570
 CalibrateSDD.C:571
 CalibrateSDD.C:572
 CalibrateSDD.C:573
 CalibrateSDD.C:574
 CalibrateSDD.C:575
 CalibrateSDD.C:576
 CalibrateSDD.C:577
 CalibrateSDD.C:578
 CalibrateSDD.C:579
 CalibrateSDD.C:580
 CalibrateSDD.C:581
 CalibrateSDD.C:582
 CalibrateSDD.C:583
 CalibrateSDD.C:584
 CalibrateSDD.C:585
 CalibrateSDD.C:586
 CalibrateSDD.C:587
 CalibrateSDD.C:588
 CalibrateSDD.C:589
 CalibrateSDD.C:590
 CalibrateSDD.C:591
 CalibrateSDD.C:592
 CalibrateSDD.C:593
 CalibrateSDD.C:594
 CalibrateSDD.C:595
 CalibrateSDD.C:596
 CalibrateSDD.C:597
 CalibrateSDD.C:598
 CalibrateSDD.C:599
 CalibrateSDD.C:600
 CalibrateSDD.C:601
 CalibrateSDD.C:602
 CalibrateSDD.C:603
 CalibrateSDD.C:604
 CalibrateSDD.C:605
 CalibrateSDD.C:606
 CalibrateSDD.C:607
 CalibrateSDD.C:608
 CalibrateSDD.C:609
 CalibrateSDD.C:610
 CalibrateSDD.C:611
 CalibrateSDD.C:612
 CalibrateSDD.C:613
 CalibrateSDD.C:614
 CalibrateSDD.C:615
 CalibrateSDD.C:616
 CalibrateSDD.C:617
 CalibrateSDD.C:618
 CalibrateSDD.C:619
 CalibrateSDD.C:620
 CalibrateSDD.C:621
 CalibrateSDD.C:622
 CalibrateSDD.C:623
 CalibrateSDD.C:624
 CalibrateSDD.C:625
 CalibrateSDD.C:626
 CalibrateSDD.C:627
 CalibrateSDD.C:628
 CalibrateSDD.C:629
 CalibrateSDD.C:630
 CalibrateSDD.C:631
 CalibrateSDD.C:632
 CalibrateSDD.C:633
 CalibrateSDD.C:634
 CalibrateSDD.C:635
 CalibrateSDD.C:636
 CalibrateSDD.C:637
 CalibrateSDD.C:638
 CalibrateSDD.C:639
 CalibrateSDD.C:640
 CalibrateSDD.C:641
 CalibrateSDD.C:642
 CalibrateSDD.C:643
 CalibrateSDD.C:644
 CalibrateSDD.C:645
 CalibrateSDD.C:646
 CalibrateSDD.C:647
 CalibrateSDD.C:648
 CalibrateSDD.C:649
 CalibrateSDD.C:650
 CalibrateSDD.C:651
 CalibrateSDD.C:652
 CalibrateSDD.C:653
 CalibrateSDD.C:654
 CalibrateSDD.C:655
 CalibrateSDD.C:656
 CalibrateSDD.C:657
 CalibrateSDD.C:658
 CalibrateSDD.C:659
 CalibrateSDD.C:660
 CalibrateSDD.C:661
 CalibrateSDD.C:662
 CalibrateSDD.C:663
 CalibrateSDD.C:664
 CalibrateSDD.C:665
 CalibrateSDD.C:666
 CalibrateSDD.C:667
 CalibrateSDD.C:668
 CalibrateSDD.C:669
 CalibrateSDD.C:670
 CalibrateSDD.C:671
 CalibrateSDD.C:672
 CalibrateSDD.C:673
 CalibrateSDD.C:674
 CalibrateSDD.C:675
 CalibrateSDD.C:676
 CalibrateSDD.C:677
 CalibrateSDD.C:678
 CalibrateSDD.C:679
 CalibrateSDD.C:680
 CalibrateSDD.C:681
 CalibrateSDD.C:682
 CalibrateSDD.C:683
 CalibrateSDD.C:684
 CalibrateSDD.C:685
 CalibrateSDD.C:686
 CalibrateSDD.C:687
 CalibrateSDD.C:688
 CalibrateSDD.C:689
 CalibrateSDD.C:690
 CalibrateSDD.C:691
 CalibrateSDD.C:692
 CalibrateSDD.C:693
 CalibrateSDD.C:694
 CalibrateSDD.C:695
 CalibrateSDD.C:696
 CalibrateSDD.C:697
 CalibrateSDD.C:698
 CalibrateSDD.C:699
 CalibrateSDD.C:700
 CalibrateSDD.C:701
 CalibrateSDD.C:702
 CalibrateSDD.C:703
 CalibrateSDD.C:704
 CalibrateSDD.C:705
 CalibrateSDD.C:706
 CalibrateSDD.C:707
 CalibrateSDD.C:708
 CalibrateSDD.C:709
 CalibrateSDD.C:710
 CalibrateSDD.C:711
 CalibrateSDD.C:712
 CalibrateSDD.C:713
 CalibrateSDD.C:714
 CalibrateSDD.C:715
 CalibrateSDD.C:716
 CalibrateSDD.C:717
 CalibrateSDD.C:718
 CalibrateSDD.C:719
 CalibrateSDD.C:720
 CalibrateSDD.C:721
 CalibrateSDD.C:722
 CalibrateSDD.C:723
 CalibrateSDD.C:724
 CalibrateSDD.C:725
 CalibrateSDD.C:726
 CalibrateSDD.C:727
 CalibrateSDD.C:728
 CalibrateSDD.C:729
 CalibrateSDD.C:730
 CalibrateSDD.C:731
 CalibrateSDD.C:732
 CalibrateSDD.C:733
 CalibrateSDD.C:734
 CalibrateSDD.C:735
 CalibrateSDD.C:736
 CalibrateSDD.C:737
 CalibrateSDD.C:738
 CalibrateSDD.C:739
 CalibrateSDD.C:740
 CalibrateSDD.C:741
 CalibrateSDD.C:742
 CalibrateSDD.C:743
 CalibrateSDD.C:744
 CalibrateSDD.C:745
 CalibrateSDD.C:746
 CalibrateSDD.C:747
 CalibrateSDD.C:748
 CalibrateSDD.C:749
 CalibrateSDD.C:750
 CalibrateSDD.C:751
 CalibrateSDD.C:752
 CalibrateSDD.C:753
 CalibrateSDD.C:754
 CalibrateSDD.C:755
 CalibrateSDD.C:756
 CalibrateSDD.C:757
 CalibrateSDD.C:758
 CalibrateSDD.C:759
 CalibrateSDD.C:760
 CalibrateSDD.C:761
 CalibrateSDD.C:762
 CalibrateSDD.C:763
 CalibrateSDD.C:764
 CalibrateSDD.C:765
 CalibrateSDD.C:766
 CalibrateSDD.C:767
 CalibrateSDD.C:768
 CalibrateSDD.C:769
 CalibrateSDD.C:770
 CalibrateSDD.C:771
 CalibrateSDD.C:772
 CalibrateSDD.C:773
 CalibrateSDD.C:774
 CalibrateSDD.C:775
 CalibrateSDD.C:776
 CalibrateSDD.C:777
 CalibrateSDD.C:778
 CalibrateSDD.C:779
 CalibrateSDD.C:780
 CalibrateSDD.C:781
 CalibrateSDD.C:782
 CalibrateSDD.C:783
 CalibrateSDD.C:784
 CalibrateSDD.C:785
 CalibrateSDD.C:786
 CalibrateSDD.C:787
 CalibrateSDD.C:788
 CalibrateSDD.C:789
 CalibrateSDD.C:790
 CalibrateSDD.C:791
 CalibrateSDD.C:792
 CalibrateSDD.C:793
 CalibrateSDD.C:794
 CalibrateSDD.C:795
 CalibrateSDD.C:796
 CalibrateSDD.C:797
 CalibrateSDD.C:798
 CalibrateSDD.C:799
 CalibrateSDD.C:800
 CalibrateSDD.C:801
 CalibrateSDD.C:802
 CalibrateSDD.C:803
 CalibrateSDD.C:804
 CalibrateSDD.C:805
 CalibrateSDD.C:806
 CalibrateSDD.C:807
 CalibrateSDD.C:808
 CalibrateSDD.C:809
 CalibrateSDD.C:810
 CalibrateSDD.C:811
 CalibrateSDD.C:812
 CalibrateSDD.C:813
 CalibrateSDD.C:814
 CalibrateSDD.C:815
 CalibrateSDD.C:816
 CalibrateSDD.C:817
 CalibrateSDD.C:818
 CalibrateSDD.C:819
 CalibrateSDD.C:820
 CalibrateSDD.C:821
 CalibrateSDD.C:822
 CalibrateSDD.C:823
 CalibrateSDD.C:824
 CalibrateSDD.C:825
 CalibrateSDD.C:826
 CalibrateSDD.C:827
 CalibrateSDD.C:828
 CalibrateSDD.C:829
 CalibrateSDD.C:830
 CalibrateSDD.C:831
 CalibrateSDD.C:832
 CalibrateSDD.C:833
 CalibrateSDD.C:834
 CalibrateSDD.C:835
 CalibrateSDD.C:836
 CalibrateSDD.C:837
 CalibrateSDD.C:838
 CalibrateSDD.C:839
 CalibrateSDD.C:840
 CalibrateSDD.C:841
 CalibrateSDD.C:842
 CalibrateSDD.C:843
 CalibrateSDD.C:844
 CalibrateSDD.C:845
 CalibrateSDD.C:846
 CalibrateSDD.C:847
 CalibrateSDD.C:848
 CalibrateSDD.C:849
 CalibrateSDD.C:850
 CalibrateSDD.C:851
 CalibrateSDD.C:852
 CalibrateSDD.C:853
 CalibrateSDD.C:854
 CalibrateSDD.C:855
 CalibrateSDD.C:856
 CalibrateSDD.C:857
 CalibrateSDD.C:858
 CalibrateSDD.C:859
 CalibrateSDD.C:860
 CalibrateSDD.C:861
 CalibrateSDD.C:862
 CalibrateSDD.C:863
 CalibrateSDD.C:864
 CalibrateSDD.C:865
 CalibrateSDD.C:866
 CalibrateSDD.C:867
 CalibrateSDD.C:868
 CalibrateSDD.C:869
 CalibrateSDD.C:870
 CalibrateSDD.C:871
 CalibrateSDD.C:872
 CalibrateSDD.C:873
 CalibrateSDD.C:874
 CalibrateSDD.C:875
 CalibrateSDD.C:876
 CalibrateSDD.C:877
 CalibrateSDD.C:878
 CalibrateSDD.C:879
 CalibrateSDD.C:880
 CalibrateSDD.C:881
 CalibrateSDD.C:882
 CalibrateSDD.C:883
 CalibrateSDD.C:884
 CalibrateSDD.C:885
 CalibrateSDD.C:886
 CalibrateSDD.C:887
 CalibrateSDD.C:888
 CalibrateSDD.C:889
 CalibrateSDD.C:890
 CalibrateSDD.C:891
 CalibrateSDD.C:892
 CalibrateSDD.C:893
 CalibrateSDD.C:894
 CalibrateSDD.C:895
 CalibrateSDD.C:896
 CalibrateSDD.C:897
 CalibrateSDD.C:898
 CalibrateSDD.C:899
 CalibrateSDD.C:900
 CalibrateSDD.C:901
 CalibrateSDD.C:902
 CalibrateSDD.C:903
 CalibrateSDD.C:904
 CalibrateSDD.C:905
 CalibrateSDD.C:906
 CalibrateSDD.C:907
 CalibrateSDD.C:908
 CalibrateSDD.C:909
 CalibrateSDD.C:910
 CalibrateSDD.C:911
 CalibrateSDD.C:912
 CalibrateSDD.C:913
 CalibrateSDD.C:914
 CalibrateSDD.C:915
 CalibrateSDD.C:916
 CalibrateSDD.C:917
 CalibrateSDD.C:918
 CalibrateSDD.C:919
 CalibrateSDD.C:920
 CalibrateSDD.C:921
 CalibrateSDD.C:922
 CalibrateSDD.C:923
 CalibrateSDD.C:924
 CalibrateSDD.C:925
 CalibrateSDD.C:926
 CalibrateSDD.C:927
 CalibrateSDD.C:928
 CalibrateSDD.C:929
 CalibrateSDD.C:930
 CalibrateSDD.C:931
 CalibrateSDD.C:932
 CalibrateSDD.C:933
 CalibrateSDD.C:934
 CalibrateSDD.C:935
 CalibrateSDD.C:936
 CalibrateSDD.C:937
 CalibrateSDD.C:938
 CalibrateSDD.C:939
 CalibrateSDD.C:940
 CalibrateSDD.C:941
 CalibrateSDD.C:942
 CalibrateSDD.C:943
 CalibrateSDD.C:944
 CalibrateSDD.C:945
 CalibrateSDD.C:946
 CalibrateSDD.C:947
 CalibrateSDD.C:948
 CalibrateSDD.C:949
 CalibrateSDD.C:950
 CalibrateSDD.C:951
 CalibrateSDD.C:952
 CalibrateSDD.C:953
 CalibrateSDD.C:954
 CalibrateSDD.C:955
 CalibrateSDD.C:956
 CalibrateSDD.C:957
 CalibrateSDD.C:958
 CalibrateSDD.C:959
 CalibrateSDD.C:960
 CalibrateSDD.C:961
 CalibrateSDD.C:962
 CalibrateSDD.C:963
 CalibrateSDD.C:964
 CalibrateSDD.C:965
 CalibrateSDD.C:966
 CalibrateSDD.C:967
 CalibrateSDD.C:968
 CalibrateSDD.C:969
 CalibrateSDD.C:970
 CalibrateSDD.C:971
 CalibrateSDD.C:972
 CalibrateSDD.C:973
 CalibrateSDD.C:974
 CalibrateSDD.C:975
 CalibrateSDD.C:976
 CalibrateSDD.C:977
 CalibrateSDD.C:978
 CalibrateSDD.C:979
 CalibrateSDD.C:980
 CalibrateSDD.C:981
 CalibrateSDD.C:982
 CalibrateSDD.C:983
 CalibrateSDD.C:984
 CalibrateSDD.C:985
 CalibrateSDD.C:986
 CalibrateSDD.C:987
 CalibrateSDD.C:988
 CalibrateSDD.C:989
 CalibrateSDD.C:990
 CalibrateSDD.C:991
 CalibrateSDD.C:992
 CalibrateSDD.C:993
 CalibrateSDD.C:994
 CalibrateSDD.C:995
 CalibrateSDD.C:996
 CalibrateSDD.C:997
 CalibrateSDD.C:998
 CalibrateSDD.C:999
 CalibrateSDD.C:1000
 CalibrateSDD.C:1001
 CalibrateSDD.C:1002
 CalibrateSDD.C:1003
 CalibrateSDD.C:1004
 CalibrateSDD.C:1005
 CalibrateSDD.C:1006
 CalibrateSDD.C:1007
 CalibrateSDD.C:1008
 CalibrateSDD.C:1009
 CalibrateSDD.C:1010
 CalibrateSDD.C:1011
 CalibrateSDD.C:1012
 CalibrateSDD.C:1013
 CalibrateSDD.C:1014
 CalibrateSDD.C:1015
 CalibrateSDD.C:1016
 CalibrateSDD.C:1017
 CalibrateSDD.C:1018
 CalibrateSDD.C:1019
 CalibrateSDD.C:1020
 CalibrateSDD.C:1021
 CalibrateSDD.C:1022
 CalibrateSDD.C:1023
 CalibrateSDD.C:1024
 CalibrateSDD.C:1025
 CalibrateSDD.C:1026
 CalibrateSDD.C:1027
 CalibrateSDD.C:1028
 CalibrateSDD.C:1029
 CalibrateSDD.C:1030
 CalibrateSDD.C:1031
 CalibrateSDD.C:1032
 CalibrateSDD.C:1033
 CalibrateSDD.C:1034
 CalibrateSDD.C:1035
 CalibrateSDD.C:1036
 CalibrateSDD.C:1037
 CalibrateSDD.C:1038
 CalibrateSDD.C:1039
 CalibrateSDD.C:1040
 CalibrateSDD.C:1041
 CalibrateSDD.C:1042
 CalibrateSDD.C:1043
 CalibrateSDD.C:1044
 CalibrateSDD.C:1045
 CalibrateSDD.C:1046
 CalibrateSDD.C:1047
 CalibrateSDD.C:1048
 CalibrateSDD.C:1049
 CalibrateSDD.C:1050
 CalibrateSDD.C:1051
 CalibrateSDD.C:1052
 CalibrateSDD.C:1053
 CalibrateSDD.C:1054
 CalibrateSDD.C:1055
 CalibrateSDD.C:1056
 CalibrateSDD.C:1057
 CalibrateSDD.C:1058
 CalibrateSDD.C:1059
 CalibrateSDD.C:1060
 CalibrateSDD.C:1061
 CalibrateSDD.C:1062
 CalibrateSDD.C:1063
 CalibrateSDD.C:1064
 CalibrateSDD.C:1065
 CalibrateSDD.C:1066
 CalibrateSDD.C:1067
 CalibrateSDD.C:1068
 CalibrateSDD.C:1069
 CalibrateSDD.C:1070
 CalibrateSDD.C:1071
 CalibrateSDD.C:1072
 CalibrateSDD.C:1073
 CalibrateSDD.C:1074
 CalibrateSDD.C:1075
 CalibrateSDD.C:1076
 CalibrateSDD.C:1077
 CalibrateSDD.C:1078
 CalibrateSDD.C:1079
 CalibrateSDD.C:1080
 CalibrateSDD.C:1081
 CalibrateSDD.C:1082
 CalibrateSDD.C:1083
 CalibrateSDD.C:1084
 CalibrateSDD.C:1085
 CalibrateSDD.C:1086
 CalibrateSDD.C:1087
 CalibrateSDD.C:1088
 CalibrateSDD.C:1089
 CalibrateSDD.C:1090
 CalibrateSDD.C:1091
 CalibrateSDD.C:1092
 CalibrateSDD.C:1093
 CalibrateSDD.C:1094
 CalibrateSDD.C:1095
 CalibrateSDD.C:1096
 CalibrateSDD.C:1097
 CalibrateSDD.C:1098
 CalibrateSDD.C:1099
 CalibrateSDD.C:1100
 CalibrateSDD.C:1101
 CalibrateSDD.C:1102
 CalibrateSDD.C:1103
 CalibrateSDD.C:1104
 CalibrateSDD.C:1105
 CalibrateSDD.C:1106
 CalibrateSDD.C:1107
 CalibrateSDD.C:1108
 CalibrateSDD.C:1109
 CalibrateSDD.C:1110
 CalibrateSDD.C:1111
 CalibrateSDD.C:1112
 CalibrateSDD.C:1113
 CalibrateSDD.C:1114
 CalibrateSDD.C:1115
 CalibrateSDD.C:1116
 CalibrateSDD.C:1117
 CalibrateSDD.C:1118
 CalibrateSDD.C:1119
 CalibrateSDD.C:1120
 CalibrateSDD.C:1121
 CalibrateSDD.C:1122
 CalibrateSDD.C:1123
 CalibrateSDD.C:1124
 CalibrateSDD.C:1125
 CalibrateSDD.C:1126
 CalibrateSDD.C:1127
 CalibrateSDD.C:1128
 CalibrateSDD.C:1129
 CalibrateSDD.C:1130
 CalibrateSDD.C:1131
 CalibrateSDD.C:1132
 CalibrateSDD.C:1133
 CalibrateSDD.C:1134
 CalibrateSDD.C:1135
 CalibrateSDD.C:1136
 CalibrateSDD.C:1137
 CalibrateSDD.C:1138
 CalibrateSDD.C:1139
 CalibrateSDD.C:1140
 CalibrateSDD.C:1141
 CalibrateSDD.C:1142
 CalibrateSDD.C:1143
 CalibrateSDD.C:1144
 CalibrateSDD.C:1145
 CalibrateSDD.C:1146
 CalibrateSDD.C:1147
 CalibrateSDD.C:1148
 CalibrateSDD.C:1149
 CalibrateSDD.C:1150
 CalibrateSDD.C:1151
 CalibrateSDD.C:1152
 CalibrateSDD.C:1153
 CalibrateSDD.C:1154
 CalibrateSDD.C:1155
 CalibrateSDD.C:1156
 CalibrateSDD.C:1157
 CalibrateSDD.C:1158
 CalibrateSDD.C:1159
 CalibrateSDD.C:1160
 CalibrateSDD.C:1161
 CalibrateSDD.C:1162
 CalibrateSDD.C:1163
 CalibrateSDD.C:1164
 CalibrateSDD.C:1165
 CalibrateSDD.C:1166
 CalibrateSDD.C:1167
 CalibrateSDD.C:1168
 CalibrateSDD.C:1169
 CalibrateSDD.C:1170
 CalibrateSDD.C:1171
 CalibrateSDD.C:1172
 CalibrateSDD.C:1173
 CalibrateSDD.C:1174
 CalibrateSDD.C:1175
 CalibrateSDD.C:1176
 CalibrateSDD.C:1177
 CalibrateSDD.C:1178
 CalibrateSDD.C:1179
 CalibrateSDD.C:1180
 CalibrateSDD.C:1181
 CalibrateSDD.C:1182
 CalibrateSDD.C:1183
 CalibrateSDD.C:1184
 CalibrateSDD.C:1185
 CalibrateSDD.C:1186
 CalibrateSDD.C:1187
 CalibrateSDD.C:1188
 CalibrateSDD.C:1189
 CalibrateSDD.C:1190
 CalibrateSDD.C:1191
 CalibrateSDD.C:1192
 CalibrateSDD.C:1193
 CalibrateSDD.C:1194
 CalibrateSDD.C:1195
 CalibrateSDD.C:1196
 CalibrateSDD.C:1197
 CalibrateSDD.C:1198
 CalibrateSDD.C:1199
 CalibrateSDD.C:1200
 CalibrateSDD.C:1201
 CalibrateSDD.C:1202
 CalibrateSDD.C:1203
 CalibrateSDD.C:1204
 CalibrateSDD.C:1205
 CalibrateSDD.C:1206
 CalibrateSDD.C:1207
 CalibrateSDD.C:1208
 CalibrateSDD.C:1209
 CalibrateSDD.C:1210
 CalibrateSDD.C:1211
 CalibrateSDD.C:1212
 CalibrateSDD.C:1213
 CalibrateSDD.C:1214
 CalibrateSDD.C:1215
 CalibrateSDD.C:1216
 CalibrateSDD.C:1217
 CalibrateSDD.C:1218
 CalibrateSDD.C:1219
 CalibrateSDD.C:1220
 CalibrateSDD.C:1221
 CalibrateSDD.C:1222
 CalibrateSDD.C:1223
 CalibrateSDD.C:1224
 CalibrateSDD.C:1225
 CalibrateSDD.C:1226
 CalibrateSDD.C:1227
 CalibrateSDD.C:1228
 CalibrateSDD.C:1229
 CalibrateSDD.C:1230
 CalibrateSDD.C:1231
 CalibrateSDD.C:1232
 CalibrateSDD.C:1233
 CalibrateSDD.C:1234
 CalibrateSDD.C:1235
 CalibrateSDD.C:1236
 CalibrateSDD.C:1237
 CalibrateSDD.C:1238
 CalibrateSDD.C:1239
 CalibrateSDD.C:1240
 CalibrateSDD.C:1241
 CalibrateSDD.C:1242
 CalibrateSDD.C:1243
 CalibrateSDD.C:1244
 CalibrateSDD.C:1245
 CalibrateSDD.C:1246
 CalibrateSDD.C:1247
 CalibrateSDD.C:1248
 CalibrateSDD.C:1249
 CalibrateSDD.C:1250
 CalibrateSDD.C:1251
 CalibrateSDD.C:1252
 CalibrateSDD.C:1253
 CalibrateSDD.C:1254
 CalibrateSDD.C:1255
 CalibrateSDD.C:1256
 CalibrateSDD.C:1257
 CalibrateSDD.C:1258
 CalibrateSDD.C:1259
 CalibrateSDD.C:1260
 CalibrateSDD.C:1261
 CalibrateSDD.C:1262
 CalibrateSDD.C:1263
 CalibrateSDD.C:1264
 CalibrateSDD.C:1265
 CalibrateSDD.C:1266
 CalibrateSDD.C:1267
 CalibrateSDD.C:1268
 CalibrateSDD.C:1269
 CalibrateSDD.C:1270
 CalibrateSDD.C:1271
 CalibrateSDD.C:1272
 CalibrateSDD.C:1273
 CalibrateSDD.C:1274
 CalibrateSDD.C:1275
 CalibrateSDD.C:1276
 CalibrateSDD.C:1277
 CalibrateSDD.C:1278
 CalibrateSDD.C:1279
 CalibrateSDD.C:1280
 CalibrateSDD.C:1281
 CalibrateSDD.C:1282
 CalibrateSDD.C:1283
 CalibrateSDD.C:1284
 CalibrateSDD.C:1285
 CalibrateSDD.C:1286
 CalibrateSDD.C:1287
 CalibrateSDD.C:1288
 CalibrateSDD.C:1289
 CalibrateSDD.C:1290
 CalibrateSDD.C:1291
 CalibrateSDD.C:1292
 CalibrateSDD.C:1293
 CalibrateSDD.C:1294
 CalibrateSDD.C:1295
 CalibrateSDD.C:1296
 CalibrateSDD.C:1297
 CalibrateSDD.C:1298
 CalibrateSDD.C:1299
 CalibrateSDD.C:1300
 CalibrateSDD.C:1301
 CalibrateSDD.C:1302
 CalibrateSDD.C:1303
 CalibrateSDD.C:1304
 CalibrateSDD.C:1305
 CalibrateSDD.C:1306
 CalibrateSDD.C:1307
 CalibrateSDD.C:1308
 CalibrateSDD.C:1309
 CalibrateSDD.C:1310
 CalibrateSDD.C:1311
 CalibrateSDD.C:1312
 CalibrateSDD.C:1313
 CalibrateSDD.C:1314
 CalibrateSDD.C:1315
 CalibrateSDD.C:1316
 CalibrateSDD.C:1317
 CalibrateSDD.C:1318
 CalibrateSDD.C:1319
 CalibrateSDD.C:1320
 CalibrateSDD.C:1321
 CalibrateSDD.C:1322
 CalibrateSDD.C:1323
 CalibrateSDD.C:1324
 CalibrateSDD.C:1325
 CalibrateSDD.C:1326
 CalibrateSDD.C:1327
 CalibrateSDD.C:1328
 CalibrateSDD.C:1329
 CalibrateSDD.C:1330
 CalibrateSDD.C:1331
 CalibrateSDD.C:1332
 CalibrateSDD.C:1333
 CalibrateSDD.C:1334
 CalibrateSDD.C:1335
 CalibrateSDD.C:1336
 CalibrateSDD.C:1337
 CalibrateSDD.C:1338
 CalibrateSDD.C:1339
 CalibrateSDD.C:1340
 CalibrateSDD.C:1341
 CalibrateSDD.C:1342
 CalibrateSDD.C:1343
 CalibrateSDD.C:1344
 CalibrateSDD.C:1345
 CalibrateSDD.C:1346
 CalibrateSDD.C:1347
 CalibrateSDD.C:1348
 CalibrateSDD.C:1349
 CalibrateSDD.C:1350
 CalibrateSDD.C:1351
 CalibrateSDD.C:1352
 CalibrateSDD.C:1353
 CalibrateSDD.C:1354
 CalibrateSDD.C:1355
 CalibrateSDD.C:1356
 CalibrateSDD.C:1357
 CalibrateSDD.C:1358
 CalibrateSDD.C:1359
 CalibrateSDD.C:1360
 CalibrateSDD.C:1361
 CalibrateSDD.C:1362
 CalibrateSDD.C:1363
 CalibrateSDD.C:1364
 CalibrateSDD.C:1365
 CalibrateSDD.C:1366
 CalibrateSDD.C:1367
 CalibrateSDD.C:1368
 CalibrateSDD.C:1369
 CalibrateSDD.C:1370
 CalibrateSDD.C:1371
 CalibrateSDD.C:1372
 CalibrateSDD.C:1373
 CalibrateSDD.C:1374
 CalibrateSDD.C:1375
 CalibrateSDD.C:1376
 CalibrateSDD.C:1377
 CalibrateSDD.C:1378
 CalibrateSDD.C:1379
 CalibrateSDD.C:1380
 CalibrateSDD.C:1381
 CalibrateSDD.C:1382
 CalibrateSDD.C:1383
 CalibrateSDD.C:1384
 CalibrateSDD.C:1385
 CalibrateSDD.C:1386
 CalibrateSDD.C:1387
 CalibrateSDD.C:1388
 CalibrateSDD.C:1389
 CalibrateSDD.C:1390
 CalibrateSDD.C:1391
 CalibrateSDD.C:1392
 CalibrateSDD.C:1393
 CalibrateSDD.C:1394
 CalibrateSDD.C:1395
 CalibrateSDD.C:1396
 CalibrateSDD.C:1397
 CalibrateSDD.C:1398
 CalibrateSDD.C:1399
 CalibrateSDD.C:1400
 CalibrateSDD.C:1401
 CalibrateSDD.C:1402
 CalibrateSDD.C:1403
 CalibrateSDD.C:1404
 CalibrateSDD.C:1405
 CalibrateSDD.C:1406
 CalibrateSDD.C:1407
 CalibrateSDD.C:1408
 CalibrateSDD.C:1409
 CalibrateSDD.C:1410
 CalibrateSDD.C:1411
 CalibrateSDD.C:1412
 CalibrateSDD.C:1413
 CalibrateSDD.C:1414
 CalibrateSDD.C:1415
 CalibrateSDD.C:1416
 CalibrateSDD.C:1417
 CalibrateSDD.C:1418
 CalibrateSDD.C:1419
 CalibrateSDD.C:1420
 CalibrateSDD.C:1421
 CalibrateSDD.C:1422
 CalibrateSDD.C:1423
 CalibrateSDD.C:1424
 CalibrateSDD.C:1425
 CalibrateSDD.C:1426
 CalibrateSDD.C:1427
 CalibrateSDD.C:1428
 CalibrateSDD.C:1429
 CalibrateSDD.C:1430
 CalibrateSDD.C:1431
 CalibrateSDD.C:1432
 CalibrateSDD.C:1433
 CalibrateSDD.C:1434
 CalibrateSDD.C:1435
 CalibrateSDD.C:1436
 CalibrateSDD.C:1437
 CalibrateSDD.C:1438
 CalibrateSDD.C:1439
 CalibrateSDD.C:1440
 CalibrateSDD.C:1441
 CalibrateSDD.C:1442
 CalibrateSDD.C:1443
 CalibrateSDD.C:1444
 CalibrateSDD.C:1445
 CalibrateSDD.C:1446
 CalibrateSDD.C:1447
 CalibrateSDD.C:1448
 CalibrateSDD.C:1449
 CalibrateSDD.C:1450
 CalibrateSDD.C:1451
 CalibrateSDD.C:1452
 CalibrateSDD.C:1453
 CalibrateSDD.C:1454
 CalibrateSDD.C:1455
 CalibrateSDD.C:1456
 CalibrateSDD.C:1457
 CalibrateSDD.C:1458
 CalibrateSDD.C:1459
 CalibrateSDD.C:1460
 CalibrateSDD.C:1461
 CalibrateSDD.C:1462
 CalibrateSDD.C:1463
 CalibrateSDD.C:1464
 CalibrateSDD.C:1465
 CalibrateSDD.C:1466
 CalibrateSDD.C:1467
 CalibrateSDD.C:1468
 CalibrateSDD.C:1469
 CalibrateSDD.C:1470
 CalibrateSDD.C:1471
 CalibrateSDD.C:1472
 CalibrateSDD.C:1473
 CalibrateSDD.C:1474
 CalibrateSDD.C:1475
 CalibrateSDD.C:1476
 CalibrateSDD.C:1477
 CalibrateSDD.C:1478
 CalibrateSDD.C:1479
 CalibrateSDD.C:1480
 CalibrateSDD.C:1481
 CalibrateSDD.C:1482
 CalibrateSDD.C:1483
 CalibrateSDD.C:1484
 CalibrateSDD.C:1485
 CalibrateSDD.C:1486
 CalibrateSDD.C:1487
 CalibrateSDD.C:1488
 CalibrateSDD.C:1489
 CalibrateSDD.C:1490
 CalibrateSDD.C:1491
 CalibrateSDD.C:1492
 CalibrateSDD.C:1493
 CalibrateSDD.C:1494
 CalibrateSDD.C:1495
 CalibrateSDD.C:1496
 CalibrateSDD.C:1497
 CalibrateSDD.C:1498
 CalibrateSDD.C:1499
 CalibrateSDD.C:1500
 CalibrateSDD.C:1501
 CalibrateSDD.C:1502
 CalibrateSDD.C:1503
 CalibrateSDD.C:1504
 CalibrateSDD.C:1505
 CalibrateSDD.C:1506
 CalibrateSDD.C:1507
 CalibrateSDD.C:1508
 CalibrateSDD.C:1509
 CalibrateSDD.C:1510
 CalibrateSDD.C:1511
 CalibrateSDD.C:1512
 CalibrateSDD.C:1513
 CalibrateSDD.C:1514
 CalibrateSDD.C:1515
 CalibrateSDD.C:1516
 CalibrateSDD.C:1517
 CalibrateSDD.C:1518
 CalibrateSDD.C:1519
 CalibrateSDD.C:1520
 CalibrateSDD.C:1521
 CalibrateSDD.C:1522
 CalibrateSDD.C:1523
 CalibrateSDD.C:1524
 CalibrateSDD.C:1525
 CalibrateSDD.C:1526
 CalibrateSDD.C:1527
 CalibrateSDD.C:1528
 CalibrateSDD.C:1529
 CalibrateSDD.C:1530
 CalibrateSDD.C:1531
 CalibrateSDD.C:1532
 CalibrateSDD.C:1533
 CalibrateSDD.C:1534
 CalibrateSDD.C:1535
 CalibrateSDD.C:1536
 CalibrateSDD.C:1537
 CalibrateSDD.C:1538
 CalibrateSDD.C:1539
 CalibrateSDD.C:1540
 CalibrateSDD.C:1541
 CalibrateSDD.C:1542
 CalibrateSDD.C:1543
 CalibrateSDD.C:1544
 CalibrateSDD.C:1545
 CalibrateSDD.C:1546
 CalibrateSDD.C:1547
 CalibrateSDD.C:1548
 CalibrateSDD.C:1549
 CalibrateSDD.C:1550
 CalibrateSDD.C:1551
 CalibrateSDD.C:1552
 CalibrateSDD.C:1553
 CalibrateSDD.C:1554
 CalibrateSDD.C:1555
 CalibrateSDD.C:1556
 CalibrateSDD.C:1557
 CalibrateSDD.C:1558
 CalibrateSDD.C:1559
 CalibrateSDD.C:1560
 CalibrateSDD.C:1561
 CalibrateSDD.C:1562
 CalibrateSDD.C:1563
 CalibrateSDD.C:1564
 CalibrateSDD.C:1565
 CalibrateSDD.C:1566
 CalibrateSDD.C:1567
 CalibrateSDD.C:1568
 CalibrateSDD.C:1569
 CalibrateSDD.C:1570
 CalibrateSDD.C:1571
 CalibrateSDD.C:1572
 CalibrateSDD.C:1573
 CalibrateSDD.C:1574
 CalibrateSDD.C:1575
 CalibrateSDD.C:1576
 CalibrateSDD.C:1577
 CalibrateSDD.C:1578
 CalibrateSDD.C:1579
 CalibrateSDD.C:1580
 CalibrateSDD.C:1581
 CalibrateSDD.C:1582
 CalibrateSDD.C:1583
 CalibrateSDD.C:1584
 CalibrateSDD.C:1585
 CalibrateSDD.C:1586
 CalibrateSDD.C:1587
 CalibrateSDD.C:1588
 CalibrateSDD.C:1589
 CalibrateSDD.C:1590
 CalibrateSDD.C:1591
 CalibrateSDD.C:1592
 CalibrateSDD.C:1593
 CalibrateSDD.C:1594
 CalibrateSDD.C:1595
 CalibrateSDD.C:1596
 CalibrateSDD.C:1597
 CalibrateSDD.C:1598
 CalibrateSDD.C:1599
 CalibrateSDD.C:1600
 CalibrateSDD.C:1601
 CalibrateSDD.C:1602
 CalibrateSDD.C:1603
 CalibrateSDD.C:1604
 CalibrateSDD.C:1605
 CalibrateSDD.C:1606
 CalibrateSDD.C:1607
 CalibrateSDD.C:1608
 CalibrateSDD.C:1609
 CalibrateSDD.C:1610
 CalibrateSDD.C:1611
 CalibrateSDD.C:1612
 CalibrateSDD.C:1613
 CalibrateSDD.C:1614
 CalibrateSDD.C:1615
 CalibrateSDD.C:1616
 CalibrateSDD.C:1617
 CalibrateSDD.C:1618
 CalibrateSDD.C:1619
 CalibrateSDD.C:1620
 CalibrateSDD.C:1621
 CalibrateSDD.C:1622
 CalibrateSDD.C:1623
 CalibrateSDD.C:1624
 CalibrateSDD.C:1625
 CalibrateSDD.C:1626
 CalibrateSDD.C:1627
 CalibrateSDD.C:1628
 CalibrateSDD.C:1629
 CalibrateSDD.C:1630
 CalibrateSDD.C:1631
 CalibrateSDD.C:1632
 CalibrateSDD.C:1633
 CalibrateSDD.C:1634
 CalibrateSDD.C:1635
 CalibrateSDD.C:1636
 CalibrateSDD.C:1637
 CalibrateSDD.C:1638
 CalibrateSDD.C:1639
 CalibrateSDD.C:1640
 CalibrateSDD.C:1641
 CalibrateSDD.C:1642
 CalibrateSDD.C:1643
 CalibrateSDD.C:1644
 CalibrateSDD.C:1645
 CalibrateSDD.C:1646
 CalibrateSDD.C:1647
 CalibrateSDD.C:1648
 CalibrateSDD.C:1649
 CalibrateSDD.C:1650
 CalibrateSDD.C:1651
 CalibrateSDD.C:1652
 CalibrateSDD.C:1653
 CalibrateSDD.C:1654
 CalibrateSDD.C:1655
 CalibrateSDD.C:1656
 CalibrateSDD.C:1657
 CalibrateSDD.C:1658
 CalibrateSDD.C:1659
 CalibrateSDD.C:1660
 CalibrateSDD.C:1661
 CalibrateSDD.C:1662
 CalibrateSDD.C:1663
 CalibrateSDD.C:1664
 CalibrateSDD.C:1665
 CalibrateSDD.C:1666
 CalibrateSDD.C:1667
 CalibrateSDD.C:1668
 CalibrateSDD.C:1669
 CalibrateSDD.C:1670
 CalibrateSDD.C:1671
 CalibrateSDD.C:1672
 CalibrateSDD.C:1673
 CalibrateSDD.C:1674
 CalibrateSDD.C:1675
 CalibrateSDD.C:1676
 CalibrateSDD.C:1677
 CalibrateSDD.C:1678
 CalibrateSDD.C:1679
 CalibrateSDD.C:1680
 CalibrateSDD.C:1681
 CalibrateSDD.C:1682
 CalibrateSDD.C:1683
 CalibrateSDD.C:1684
 CalibrateSDD.C:1685
 CalibrateSDD.C:1686
 CalibrateSDD.C:1687
 CalibrateSDD.C:1688
 CalibrateSDD.C:1689
 CalibrateSDD.C:1690
 CalibrateSDD.C:1691
 CalibrateSDD.C:1692
 CalibrateSDD.C:1693
 CalibrateSDD.C:1694
 CalibrateSDD.C:1695
 CalibrateSDD.C:1696
 CalibrateSDD.C:1697
 CalibrateSDD.C:1698
 CalibrateSDD.C:1699
 CalibrateSDD.C:1700
 CalibrateSDD.C:1701
 CalibrateSDD.C:1702
 CalibrateSDD.C:1703
 CalibrateSDD.C:1704
 CalibrateSDD.C:1705
 CalibrateSDD.C:1706
 CalibrateSDD.C:1707
 CalibrateSDD.C:1708
 CalibrateSDD.C:1709
 CalibrateSDD.C:1710
 CalibrateSDD.C:1711
 CalibrateSDD.C:1712
 CalibrateSDD.C:1713
 CalibrateSDD.C:1714
 CalibrateSDD.C:1715
 CalibrateSDD.C:1716
 CalibrateSDD.C:1717
 CalibrateSDD.C:1718
 CalibrateSDD.C:1719
 CalibrateSDD.C:1720
 CalibrateSDD.C:1721
 CalibrateSDD.C:1722
 CalibrateSDD.C:1723
 CalibrateSDD.C:1724
 CalibrateSDD.C:1725
 CalibrateSDD.C:1726
 CalibrateSDD.C:1727
 CalibrateSDD.C:1728
 CalibrateSDD.C:1729
 CalibrateSDD.C:1730
 CalibrateSDD.C:1731
 CalibrateSDD.C:1732
 CalibrateSDD.C:1733
 CalibrateSDD.C:1734
 CalibrateSDD.C:1735
 CalibrateSDD.C:1736
 CalibrateSDD.C:1737
 CalibrateSDD.C:1738
 CalibrateSDD.C:1739
 CalibrateSDD.C:1740
 CalibrateSDD.C:1741
 CalibrateSDD.C:1742
 CalibrateSDD.C:1743
 CalibrateSDD.C:1744
 CalibrateSDD.C:1745
 CalibrateSDD.C:1746
 CalibrateSDD.C:1747
 CalibrateSDD.C:1748
 CalibrateSDD.C:1749
 CalibrateSDD.C:1750
 CalibrateSDD.C:1751
 CalibrateSDD.C:1752
 CalibrateSDD.C:1753
 CalibrateSDD.C:1754
 CalibrateSDD.C:1755
 CalibrateSDD.C:1756
 CalibrateSDD.C:1757
 CalibrateSDD.C:1758
 CalibrateSDD.C:1759
 CalibrateSDD.C:1760
 CalibrateSDD.C:1761
 CalibrateSDD.C:1762
 CalibrateSDD.C:1763
 CalibrateSDD.C:1764
 CalibrateSDD.C:1765
 CalibrateSDD.C:1766
 CalibrateSDD.C:1767
 CalibrateSDD.C:1768
 CalibrateSDD.C:1769
 CalibrateSDD.C:1770
 CalibrateSDD.C:1771
 CalibrateSDD.C:1772
 CalibrateSDD.C:1773
 CalibrateSDD.C:1774
 CalibrateSDD.C:1775
 CalibrateSDD.C:1776
 CalibrateSDD.C:1777
 CalibrateSDD.C:1778
 CalibrateSDD.C:1779
 CalibrateSDD.C:1780
 CalibrateSDD.C:1781
 CalibrateSDD.C:1782
 CalibrateSDD.C:1783
 CalibrateSDD.C:1784
 CalibrateSDD.C:1785
 CalibrateSDD.C:1786
 CalibrateSDD.C:1787
 CalibrateSDD.C:1788
 CalibrateSDD.C:1789
 CalibrateSDD.C:1790
 CalibrateSDD.C:1791
 CalibrateSDD.C:1792
 CalibrateSDD.C:1793
 CalibrateSDD.C:1794
 CalibrateSDD.C:1795
 CalibrateSDD.C:1796
 CalibrateSDD.C:1797
 CalibrateSDD.C:1798
 CalibrateSDD.C:1799
 CalibrateSDD.C:1800
 CalibrateSDD.C:1801
 CalibrateSDD.C:1802
 CalibrateSDD.C:1803
 CalibrateSDD.C:1804
 CalibrateSDD.C:1805
 CalibrateSDD.C:1806
 CalibrateSDD.C:1807
 CalibrateSDD.C:1808
 CalibrateSDD.C:1809
 CalibrateSDD.C:1810
 CalibrateSDD.C:1811
 CalibrateSDD.C:1812
 CalibrateSDD.C:1813
 CalibrateSDD.C:1814
 CalibrateSDD.C:1815
 CalibrateSDD.C:1816
 CalibrateSDD.C:1817
 CalibrateSDD.C:1818
 CalibrateSDD.C:1819
 CalibrateSDD.C:1820
 CalibrateSDD.C:1821
 CalibrateSDD.C:1822
 CalibrateSDD.C:1823
 CalibrateSDD.C:1824
 CalibrateSDD.C:1825
 CalibrateSDD.C:1826
 CalibrateSDD.C:1827
 CalibrateSDD.C:1828
 CalibrateSDD.C:1829
 CalibrateSDD.C:1830
 CalibrateSDD.C:1831
 CalibrateSDD.C:1832
 CalibrateSDD.C:1833
 CalibrateSDD.C:1834
 CalibrateSDD.C:1835
 CalibrateSDD.C:1836
 CalibrateSDD.C:1837
 CalibrateSDD.C:1838
 CalibrateSDD.C:1839
 CalibrateSDD.C:1840
 CalibrateSDD.C:1841
 CalibrateSDD.C:1842
 CalibrateSDD.C:1843
 CalibrateSDD.C:1844
 CalibrateSDD.C:1845
 CalibrateSDD.C:1846
 CalibrateSDD.C:1847
 CalibrateSDD.C:1848
 CalibrateSDD.C:1849
 CalibrateSDD.C:1850
 CalibrateSDD.C:1851
 CalibrateSDD.C:1852
 CalibrateSDD.C:1853
 CalibrateSDD.C:1854
 CalibrateSDD.C:1855
 CalibrateSDD.C:1856
 CalibrateSDD.C:1857
 CalibrateSDD.C:1858
 CalibrateSDD.C:1859
 CalibrateSDD.C:1860
 CalibrateSDD.C:1861
 CalibrateSDD.C:1862
 CalibrateSDD.C:1863
 CalibrateSDD.C:1864
 CalibrateSDD.C:1865
 CalibrateSDD.C:1866
 CalibrateSDD.C:1867
 CalibrateSDD.C:1868
 CalibrateSDD.C:1869
 CalibrateSDD.C:1870
 CalibrateSDD.C:1871
 CalibrateSDD.C:1872
 CalibrateSDD.C:1873
 CalibrateSDD.C:1874
 CalibrateSDD.C:1875
 CalibrateSDD.C:1876
 CalibrateSDD.C:1877
 CalibrateSDD.C:1878
 CalibrateSDD.C:1879
 CalibrateSDD.C:1880
 CalibrateSDD.C:1881
 CalibrateSDD.C:1882
 CalibrateSDD.C:1883
 CalibrateSDD.C:1884
 CalibrateSDD.C:1885
 CalibrateSDD.C:1886
 CalibrateSDD.C:1887
 CalibrateSDD.C:1888
 CalibrateSDD.C:1889
 CalibrateSDD.C:1890
 CalibrateSDD.C:1891
 CalibrateSDD.C:1892
 CalibrateSDD.C:1893
 CalibrateSDD.C:1894
 CalibrateSDD.C:1895
 CalibrateSDD.C:1896
 CalibrateSDD.C:1897
 CalibrateSDD.C:1898
 CalibrateSDD.C:1899
 CalibrateSDD.C:1900
 CalibrateSDD.C:1901
 CalibrateSDD.C:1902
 CalibrateSDD.C:1903
 CalibrateSDD.C:1904
 CalibrateSDD.C:1905
 CalibrateSDD.C:1906
 CalibrateSDD.C:1907
 CalibrateSDD.C:1908
 CalibrateSDD.C:1909
 CalibrateSDD.C:1910
 CalibrateSDD.C:1911
 CalibrateSDD.C:1912
 CalibrateSDD.C:1913
 CalibrateSDD.C:1914
 CalibrateSDD.C:1915
 CalibrateSDD.C:1916
 CalibrateSDD.C:1917
 CalibrateSDD.C:1918
 CalibrateSDD.C:1919
 CalibrateSDD.C:1920
 CalibrateSDD.C:1921
 CalibrateSDD.C:1922
 CalibrateSDD.C:1923
 CalibrateSDD.C:1924
 CalibrateSDD.C:1925
 CalibrateSDD.C:1926
 CalibrateSDD.C:1927
 CalibrateSDD.C:1928
 CalibrateSDD.C:1929
 CalibrateSDD.C:1930
 CalibrateSDD.C:1931
 CalibrateSDD.C:1932
 CalibrateSDD.C:1933
 CalibrateSDD.C:1934
 CalibrateSDD.C:1935
 CalibrateSDD.C:1936
 CalibrateSDD.C:1937
 CalibrateSDD.C:1938
 CalibrateSDD.C:1939
 CalibrateSDD.C:1940
 CalibrateSDD.C:1941
 CalibrateSDD.C:1942
 CalibrateSDD.C:1943
 CalibrateSDD.C:1944
 CalibrateSDD.C:1945
 CalibrateSDD.C:1946
 CalibrateSDD.C:1947
 CalibrateSDD.C:1948
 CalibrateSDD.C:1949
 CalibrateSDD.C:1950
 CalibrateSDD.C:1951
 CalibrateSDD.C:1952
 CalibrateSDD.C:1953
 CalibrateSDD.C:1954
 CalibrateSDD.C:1955
 CalibrateSDD.C:1956
 CalibrateSDD.C:1957
 CalibrateSDD.C:1958
 CalibrateSDD.C:1959
 CalibrateSDD.C:1960
 CalibrateSDD.C:1961
 CalibrateSDD.C:1962
 CalibrateSDD.C:1963
 CalibrateSDD.C:1964
 CalibrateSDD.C:1965
 CalibrateSDD.C:1966
 CalibrateSDD.C:1967
 CalibrateSDD.C:1968
 CalibrateSDD.C:1969
 CalibrateSDD.C:1970
 CalibrateSDD.C:1971
 CalibrateSDD.C:1972
 CalibrateSDD.C:1973
 CalibrateSDD.C:1974
 CalibrateSDD.C:1975
 CalibrateSDD.C:1976
 CalibrateSDD.C:1977
 CalibrateSDD.C:1978
 CalibrateSDD.C:1979
 CalibrateSDD.C:1980
 CalibrateSDD.C:1981
 CalibrateSDD.C:1982
 CalibrateSDD.C:1983
 CalibrateSDD.C:1984
 CalibrateSDD.C:1985
 CalibrateSDD.C:1986
 CalibrateSDD.C:1987
 CalibrateSDD.C:1988
 CalibrateSDD.C:1989
 CalibrateSDD.C:1990
 CalibrateSDD.C:1991
 CalibrateSDD.C:1992
 CalibrateSDD.C:1993
 CalibrateSDD.C:1994
 CalibrateSDD.C:1995
 CalibrateSDD.C:1996
 CalibrateSDD.C:1997
 CalibrateSDD.C:1998
 CalibrateSDD.C:1999
 CalibrateSDD.C:2000
 CalibrateSDD.C:2001
 CalibrateSDD.C:2002
 CalibrateSDD.C:2003
 CalibrateSDD.C:2004
 CalibrateSDD.C:2005
 CalibrateSDD.C:2006
 CalibrateSDD.C:2007
 CalibrateSDD.C:2008
 CalibrateSDD.C:2009
 CalibrateSDD.C:2010
 CalibrateSDD.C:2011
 CalibrateSDD.C:2012
 CalibrateSDD.C:2013
 CalibrateSDD.C:2014
 CalibrateSDD.C:2015
 CalibrateSDD.C:2016
 CalibrateSDD.C:2017
 CalibrateSDD.C:2018
 CalibrateSDD.C:2019
 CalibrateSDD.C:2020
 CalibrateSDD.C:2021
 CalibrateSDD.C:2022
 CalibrateSDD.C:2023
 CalibrateSDD.C:2024
 CalibrateSDD.C:2025
 CalibrateSDD.C:2026
 CalibrateSDD.C:2027
 CalibrateSDD.C:2028
 CalibrateSDD.C:2029
 CalibrateSDD.C:2030
 CalibrateSDD.C:2031
 CalibrateSDD.C:2032
 CalibrateSDD.C:2033
 CalibrateSDD.C:2034
 CalibrateSDD.C:2035
 CalibrateSDD.C:2036
 CalibrateSDD.C:2037
 CalibrateSDD.C:2038
 CalibrateSDD.C:2039
 CalibrateSDD.C:2040
 CalibrateSDD.C:2041
 CalibrateSDD.C:2042
 CalibrateSDD.C:2043
 CalibrateSDD.C:2044
 CalibrateSDD.C:2045
 CalibrateSDD.C:2046
 CalibrateSDD.C:2047
 CalibrateSDD.C:2048
 CalibrateSDD.C:2049
 CalibrateSDD.C:2050
 CalibrateSDD.C:2051
 CalibrateSDD.C:2052
 CalibrateSDD.C:2053
 CalibrateSDD.C:2054
 CalibrateSDD.C:2055
 CalibrateSDD.C:2056
 CalibrateSDD.C:2057
 CalibrateSDD.C:2058
 CalibrateSDD.C:2059
 CalibrateSDD.C:2060
 CalibrateSDD.C:2061
 CalibrateSDD.C:2062
 CalibrateSDD.C:2063
 CalibrateSDD.C:2064
 CalibrateSDD.C:2065
 CalibrateSDD.C:2066
 CalibrateSDD.C:2067
 CalibrateSDD.C:2068
 CalibrateSDD.C:2069
 CalibrateSDD.C:2070
 CalibrateSDD.C:2071
 CalibrateSDD.C:2072
 CalibrateSDD.C:2073
 CalibrateSDD.C:2074
 CalibrateSDD.C:2075
 CalibrateSDD.C:2076
 CalibrateSDD.C:2077
 CalibrateSDD.C:2078
 CalibrateSDD.C:2079
 CalibrateSDD.C:2080
 CalibrateSDD.C:2081
 CalibrateSDD.C:2082
 CalibrateSDD.C:2083
 CalibrateSDD.C:2084
 CalibrateSDD.C:2085
 CalibrateSDD.C:2086
 CalibrateSDD.C:2087
 CalibrateSDD.C:2088
 CalibrateSDD.C:2089
 CalibrateSDD.C:2090
 CalibrateSDD.C:2091
 CalibrateSDD.C:2092
 CalibrateSDD.C:2093
 CalibrateSDD.C:2094
 CalibrateSDD.C:2095
 CalibrateSDD.C:2096
 CalibrateSDD.C:2097
 CalibrateSDD.C:2098
 CalibrateSDD.C:2099
 CalibrateSDD.C:2100
 CalibrateSDD.C:2101
 CalibrateSDD.C:2102
 CalibrateSDD.C:2103
 CalibrateSDD.C:2104
 CalibrateSDD.C:2105
 CalibrateSDD.C:2106
 CalibrateSDD.C:2107
 CalibrateSDD.C:2108
 CalibrateSDD.C:2109
 CalibrateSDD.C:2110
 CalibrateSDD.C:2111
 CalibrateSDD.C:2112
 CalibrateSDD.C:2113
 CalibrateSDD.C:2114
 CalibrateSDD.C:2115
 CalibrateSDD.C:2116
 CalibrateSDD.C:2117
 CalibrateSDD.C:2118
 CalibrateSDD.C:2119
 CalibrateSDD.C:2120
 CalibrateSDD.C:2121
 CalibrateSDD.C:2122
 CalibrateSDD.C:2123
 CalibrateSDD.C:2124
 CalibrateSDD.C:2125
 CalibrateSDD.C:2126
 CalibrateSDD.C:2127
 CalibrateSDD.C:2128
 CalibrateSDD.C:2129
 CalibrateSDD.C:2130
 CalibrateSDD.C:2131
 CalibrateSDD.C:2132
 CalibrateSDD.C:2133
 CalibrateSDD.C:2134
 CalibrateSDD.C:2135
 CalibrateSDD.C:2136
 CalibrateSDD.C:2137
 CalibrateSDD.C:2138
 CalibrateSDD.C:2139
 CalibrateSDD.C:2140
 CalibrateSDD.C:2141
 CalibrateSDD.C:2142
 CalibrateSDD.C:2143
 CalibrateSDD.C:2144
 CalibrateSDD.C:2145
 CalibrateSDD.C:2146
 CalibrateSDD.C:2147
 CalibrateSDD.C:2148
 CalibrateSDD.C:2149
 CalibrateSDD.C:2150
 CalibrateSDD.C:2151
 CalibrateSDD.C:2152
 CalibrateSDD.C:2153
 CalibrateSDD.C:2154
 CalibrateSDD.C:2155
 CalibrateSDD.C:2156
 CalibrateSDD.C:2157
 CalibrateSDD.C:2158
 CalibrateSDD.C:2159
 CalibrateSDD.C:2160
 CalibrateSDD.C:2161
 CalibrateSDD.C:2162
 CalibrateSDD.C:2163
 CalibrateSDD.C:2164
 CalibrateSDD.C:2165
 CalibrateSDD.C:2166
 CalibrateSDD.C:2167
 CalibrateSDD.C:2168
 CalibrateSDD.C:2169
 CalibrateSDD.C:2170
 CalibrateSDD.C:2171
 CalibrateSDD.C:2172
 CalibrateSDD.C:2173
 CalibrateSDD.C:2174
 CalibrateSDD.C:2175
 CalibrateSDD.C:2176
 CalibrateSDD.C:2177
 CalibrateSDD.C:2178
 CalibrateSDD.C:2179
 CalibrateSDD.C:2180
 CalibrateSDD.C:2181
 CalibrateSDD.C:2182
 CalibrateSDD.C:2183
 CalibrateSDD.C:2184