#include <AliCDBEntry.h>
#include <AliCDBManager.h>
#include <AliCDBId.h>
+#include <AliSplineFit.h>
#include "AliTPCcalibDB.h"
#include "AliTPCCalPad.h"
#include "AliTPCCalROC.h"
#include "AliTPCcalibDButil.h"
#include "AliTPCCalibVdrift.h"
#include "AliMathBase.h"
+#include "AliRelAlignerKalman.h"
+
+const Float_t kAlmost0=1.e-30;
ClassImp(AliTPCcalibDButil)
AliTPCcalibDButil::AliTPCcalibDButil() :
// Update pointers from calibDB
//
if (!fCalibDB) fCalibDB=AliTPCcalibDB::Instance();
+ fCalibDB->UpdateNonRec(); // load all infromation now
fPadNoise=fCalibDB->GetPadNoise();
fPedestals=fCalibDB->GetPedestals();
fPulserTmean=fCalibDB->GetPulserTmean();
fCalibRaw=fCalibDB->GetCalibRaw();
fDataQA=fCalibDB->GetDataQA();
UpdatePulserOutlierMap();
- SetReferenceRun();
- UpdateRefDataFromOCDB();
+// SetReferenceRun();
+// UpdateRefDataFromOCDB();
}
//_____________________________________________________________________________________
void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
- Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad *outCE)
+ Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad * const outCE)
{
//
// Process the CE data for this run
if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
Float_t valTmean=rocData->GetValue(irow,ipad);
//exclude values that are exactly 0
- if (valTmean==0) {
+ if ( !(TMath::Abs(valTmean)>kAlmost0) ) {
rocOut->SetValue(irow,ipad,1);
++noutliersCE;
}
//_____________________________________________________________________________________
void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
- Int_t &nonMaskedZero)
+ Int_t &nonMaskedZero, Int_t &nNaN)
{
//
// process noise data
vNoiseRMS.Zero();
vNoiseRMSSenRegions.Zero();
nonMaskedZero=0;
+ nNaN=0;
//counters
TVectorD c(infoSize);
TVectorD cs(infoSize);
if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
Float_t noiseVal=noiseROC->GetValue(irow,ipad);
//check if noise==0
- if (noiseVal==0) {
+ if (noiseVal<kAlmost0) {
++nonMaskedZero;
continue;
}
//check for nan
if ( !(noiseVal<10000000) ){
- printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
+ AliInfo(Form("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal));
+ ++nNaN;
continue;
}
Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
Double_t rmsSen=0;
if (c[i]>verySmall){
-// printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
+ AliInfo(Form("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]));
mean=vNoiseMean[i]/c[i];
rms=vNoiseRMS[i];
rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
}
}
+//_____________________________________________________________________________________
+void AliTPCcalibDButil::ProcessQAData(TVectorD &vQaOcc, TVectorD &vQaQtot,
+ TVectorD &vQaQmax)
+{
+ //
+ // process QA data
+ //
+ // vQaOcc/Qtot/Qmax contains the Mean occupancy/Qtot/Qmax for each sector
+ //
+
+
+ const UInt_t infoSize = 72;
+ //reset counters to error number
+ vQaOcc.ResizeTo(infoSize);
+ vQaOcc.Zero();
+ vQaQtot.ResizeTo(infoSize);
+ vQaQtot.Zero();
+ vQaQmax.ResizeTo(infoSize);
+ vQaQmax.Zero();
+ //counter
+ //retrieve pulser and ALTRO data
+
+ if (!fDataQA) {
+
+ AliInfo("No QA data");
+ return;
+ }
+ if (fDataQA->GetEventCounter()<=0) {
+
+ AliInfo("No QA data");
+ return; // no data processed
+ }
+ //
+ fDataQA->Analyse();
+
+ TVectorD normOcc(infoSize);
+ TVectorD normQ(infoSize);
+
+ for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
+
+ AliInfo(Form("Sector %d\n", isec));
+ AliTPCCalROC* occupancyROC = fDataQA->GetNoThreshold()->GetCalROC(isec);
+ AliTPCCalROC* nclusterROC = fDataQA->GetNLocalMaxima()->GetCalROC(isec);
+ AliTPCCalROC* qROC = fDataQA->GetMeanCharge()->GetCalROC(isec);
+ AliTPCCalROC* qmaxROC = fDataQA->GetMaxCharge()->GetCalROC(isec);
+ if (!occupancyROC) continue;
+ if (!nclusterROC) continue;
+ if (!qROC) continue;
+ if (!qmaxROC) continue;
+
+ const UInt_t nchannels=occupancyROC->GetNchannels();
+
+ AliInfo(Form("Nchannels %d\n", nchannels));
+
+ for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
+
+ vQaOcc[isec] += occupancyROC->GetValue(ichannel);
+ ++normOcc[isec];
+
+ Float_t nClusters = nclusterROC->GetValue(ichannel);
+ normQ[isec] += nClusters;
+ vQaQtot[isec]+=nClusters*qROC->GetValue(ichannel);
+ vQaQmax[isec]+=nClusters*qmaxROC->GetValue(ichannel);
+ }
+ }
+
+ //calculate mean values
+ for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
+
+ if (normOcc[isec]>0) vQaOcc[isec] /= normOcc[isec];
+ else vQaOcc[isec] = 0;
+
+ if (normQ[isec]>0) {
+ vQaQtot[isec] /= normQ[isec];
+ vQaQmax[isec] /= normQ[isec];
+ }else {
+
+ vQaQtot[isec] = 0;
+ vQaQmax[isec] = 0;
+ }
+ }
+}
+
//_____________________________________________________________________________________
void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
{
//don't use masked channels;
if (mROC ->GetValue(irow,ipad)) continue;
if (mRefROC->GetValue(irow,ipad)) continue;
+ if (nRefROC->GetValue(irow,ipad)==0) continue;
Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
for (Int_t i=0;i<npar;++i){
if (deviation>vThres[i])
AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
- Float_t pt_mean=ptROC->GetMean(oROC);
+ Float_t ptmean=ptROC->GetMean(oROC);
UInt_t nrows=mROC->GetNrows();
for (UInt_t irow=0;irow<nrows;++irow){
UInt_t npads=mROC->GetNPads(irow);
Float_t pt=ptROC->GetValue(irow,ipad);
// Float_t ptRef=ptRefROC->GetValue(irow,ipad);
//comparisons q
- Float_t deviation=TMath::Abs(pq/pqRef-1);
+ Float_t deviation=TMath::Abs(pqRef)>1e-20?TMath::Abs(pq/pqRef-1):-999;
for (Int_t i=0;i<npar;++i){
if (deviation>vThres[i])
++pulserQdeviations.GetMatrixArray()[i];
if (pqRef>11&&pq<11) ++npadsOffAdd;
varQMean+=pq-pqRef;
//comparisons t
- if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB;
+ if (TMath::Abs(pt-ptmean)>1) ++npadsOutOneTB;
++nActive;
}//end ipad
}//ind irow
void AliTPCcalibDButil::UpdatePulserOutlierMap()
{
//
- //
+ // Update the outlier map of the pulser data
//
PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
}
void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
{
//
- //
+ // Update the outlier map of the pulser reference data
//
PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
}
AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
Float_t mean=rocPulTmean->GetMean(rocOut);
//treat case where a whole partition is masked
- if (mean==0) mean=rocPulTmean->GetMean();
+ if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
if (model==1) {
Int_t type=isec/18;
mean=vMean[type];
//This should be the most precise guess in that case.
if (rocOut->GetValue(irow,ipad)) {
time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
- if (time==0) time=mean;
+ if ( TMath::Abs(time)<kAlmost0 ) time=mean;
}
Float_t val=time-mean;
rocTime0->SetValue(irow,ipad,val);
rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
Float_t mean=rocPulTmean->GetMean(rocOutPul);
- if (mean==0) mean=rocPulTmean->GetMean();
+ if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
UInt_t nrows=rocTime0->GetNrows();
for (UInt_t irow=0;irow<nrows;++irow){
UInt_t npads=rocTime0->GetNPads(irow);
return padTime0;
}
//_____________________________________________________________________________________
-Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
+Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *const rocOut)
{
+ //
+ // GetMeanAlto information
+ //
if (roc==0) return 0.;
const Int_t sector=roc->GetSector();
AliTPCROC *tpcRoc=AliTPCROC::Instance();
entry->SetOwner(kTRUE);
TObjArray *arr=(TObjArray*)entry->GetObject();
if (!arr){
- AliError(Form("Could not get object from entry '%s'\nPlese check!!!",entry->GetId().GetPath().Data()));
+ AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
} else {
fRefCalibRaw=(AliTPCCalibRaw*)arr->At(0)->Clone();
}
entry=GetRefEntry(cdbPath.Data());
if (entry){
entry->SetOwner(kTRUE);
- fDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
- if (!fDataQA){
- AliError(Form("Could not get object from entry '%s'\nPlese check!!!",entry->GetId().GetPath().Data()));
+ fRefDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
+ if (!fRefDataQA){
+ AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
} else {
- fRefDataQA=(AliTPCdataQA*)fDataQA->Clone();
+ fRefDataQA=(AliTPCdataQA*)fRefDataQA->Clone();
}
delete entry;
}
AliTPCCalPad *pad=0x0;
TObjArray *arr=(TObjArray*)entry->GetObject();
if (!arr){
- AliError(Form("Could not get object from entry '%s'\nPlese check!!!",entry->GetId().GetPath().Data()));
+ AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
return pad;
}
pad=(AliTPCCalPad*)arr->FindObject(objName);
if (!pad) {
- AliError(Form("Could not get '%s' from TObjArray in entry '%s'\nPlese check!!!",objName,entry->GetId().GetPath().Data()));
+ AliError(Form("Could not get '%s' from TObjArray in entry '%s'\nPlease check!!!",objName,entry->GetId().GetPath().Data()));
return pad;
}
return (AliTPCCalPad*)pad->Clone();
//
AliTPCCalPad *pad=(AliTPCCalPad*)entry->GetObject();
if (!pad) {
- AliError(Form("Could not get object from entry '%s'\nPlese check!!!",entry->GetId().GetPath().Data()));
+ AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
return 0x0;
}
pad=(AliTPCCalPad*)pad->Clone();
AliTPCCalPad* pad=0x0;
const Int_t run=GetReferenceRun(cdbPath);
if (run<0) {
- AliError(Form("Could not get reference run number for object '%s'\nPlese check availability!!!",cdbPath));
+ AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
return pad;
}
AliCDBEntry *entry=AliCDBManager::Instance()->Get("TPC/Calib/AltroConfig", run);
if (!entry) {
- AliError(Form("Could not get reference object '%s'\nPlese check availability!!!",cdbPath));
+ AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
return pad;
}
pad=GetRefCalPad(entry,"Masked");
TString cdbPath="TPC/Calib/Ref";
AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath.Data(), run);
if (!entry) {
- AliError(Form("Could not get reference object '%s'\nPlese check availability!!!",cdbPath.Data()));
+ AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath.Data()));
fRefMap=0;
return;
}
//
const Int_t run=GetReferenceRun(cdbPath);
if (run<0) {
- AliError(Form("Could not get reference run number for object '%s'\nPlese check availability!!!",cdbPath));
+ AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
return 0;
}
AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath, run);
if (!entry) {
- AliError(Form("Could not get reference object '%s'\nPlese check availability!!!",cdbPath));
+ AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
return 0;
}
return entry;
}
//_____________________________________________________________________________________
-const Int_t AliTPCcalibDButil::GetCurrentReferenceRun(const char* type){
+Int_t AliTPCcalibDButil::GetCurrentReferenceRun(const char* type) const {
//
// Get reference run number for the specified OCDB path
//
if (!fCurrentRefMap) return -2;
TObjString *str=dynamic_cast<TObjString*>(fCurrentRefMap->GetValue(type));
if (!str) return -2;
- return str->GetString().Atoi();
+ return (Int_t)str->GetString().Atoi();
}
//_____________________________________________________________________________________
-const Int_t AliTPCcalibDButil::GetReferenceRun(const char* type) const{
+Int_t AliTPCcalibDButil::GetReferenceRun(const char* type) const{
//
// Get reference run number for the specified OCDB path
//
if (!fRefMap) return -1;
TObjString *str=dynamic_cast<TObjString*>(fRefMap->GetValue(type));
if (!str) return -1;
- return str->GetString().Atoi();
+ return (Int_t)str->GetString().Atoi();
}
//_____________________________________________________________________________________
-AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad *ceOut, Float_t minSignal, Float_t cutTrmsMin, Float_t cutTrmsMax, Float_t cutMaxDistT){
+AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad * const ceOut, Float_t minSignal, Float_t cutTrmsMin, Float_t cutTrmsMax, Float_t cutMaxDistT){
//
// Author: marian.ivanov@cern.ch
//
Double_t rmsMedian = fCETrms->GetMedian();
for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
+ if (!rocData) continue;
if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
AliTPCCalROC *rocOut = out->GetCalROC(iroc);
AliTPCCalROC *rocCEQ = fCEQmean->GetCalROC(iroc);
AliTPCCalROC *rocCETrms = fCETrms->GetCalROC(iroc);
Double_t trocMedian = rocData->GetMedian();
//
- if (!rocData) {
+ if (!rocData || !rocCEQ || !rocCETrms || !rocData) {
noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
rocOut->Add(1.);
continue;
//2. exclude edge pads
if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
//exclude values that are exactly 0
- if (valTmean==0) {
+ if ( TMath::Abs(valTmean)<kAlmost0) {
rocOut->SetValue(irow,ipad,1);
++noutliersCE;
}
}
-AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad *pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
+AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad * const pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
//
// Author: marian.ivanov@cern.ch
//
Float_t valTmean=rocData->GetValue(ichannel);
Float_t valQmean=rocPulserQ->GetValue(ichannel);
Float_t valTrms =rocPulserTrms->GetValue(ichannel);
+ Float_t valMasked =0;
+ if (rocMasked) valMasked = rocMasked->GetValue(ichannel);
Int_t isOut=0;
+ if (valMasked>0.5) isOut=1;
if (TMath::Abs(valTmean-rocMedianT)>cutTime) isOut=1;
if (TMath::Abs(valQmean-rocMedianQ)>cutnRMSQ*rocRMSQ) isOut=1;
if (TMath::Abs(valTrms-rocMedianTrms)>cutnRMSrms*rocRMSTrms) isOut=1;
//
// find the closest point to xref in x direction
// return dx and value
+ dx = 0;
+ y = 0;
+
+ if(!graph) return 0;
+ if(graph->GetN() < 1) return 0;
+
Int_t index=0;
index = TMath::BinarySearch(graph->GetN(), graph->GetX(),xref);
if (index<0) index=0;
- if (index>=graph->GetN()-1) index=graph->GetN()-2;
- if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
- dx = xref-graph->GetX()[index];
+ if(graph->GetN()==1) {
+ dx = xref-graph->GetX()[index];
+ }
+ else {
+ if (index>=graph->GetN()-1) index=graph->GetN()-2;
+ if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
+ dx = xref-graph->GetX()[index];
+ }
y = graph->GetY()[index];
return index;
}
-
Double_t AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
//
// Get the correction of the trigger offset
//
//
const Float_t kLaserCut=0.0005;
- const Int_t kMaxPeriod=3600*24*30*3; // 3 month max
+ const Int_t kMaxPeriod=3600*24*30*12; // one year max
const Int_t kMinPoints=20;
//
TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
tdelta[nused]=ccosmic-claser;
nused++;
}
- if (nused<kMinPoints &&deltaT<kMaxPeriod) return AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
+ if (nused<kMinPoints &&deltaT<kMaxPeriod) {
+ delete [] tdelta;
+ return AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
+ }
+ if (nused<kMinPoints) {
+ delete [] tdelta;
+ //AliWarning("AliFatal: No time offset calibration available\n");
+ return 0;
+ }
Double_t median = TMath::Median(nused,tdelta);
Double_t mean = TMath::Mean(nused,tdelta);
- delete tdelta;
+ delete [] tdelta;
return (valType==0) ? median:mean;
}
AliTPCcalibDButil::GetNearest(cosmicAll,timeStamp,dist,grY);
Double_t t0= AliTPCcalibDButil::GetTriggerOffsetTPC(run,timeStamp, deltaT, deltaTLaser,valType);
- Double_t vcosmic= AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
+ Double_t vcosmic = AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
if (timeStamp>cosmicAll->GetX()[cosmicAll->GetN()-1]) vcosmic=cosmicAll->GetY()[cosmicAll->GetN()-1];
if (timeStamp<cosmicAll->GetX()[0]) vcosmic=cosmicAll->GetY()[0];
- return vcosmic+t0;
+ return vcosmic-t0;
/*
Example usage:
Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
//
- // Get the correction of the drift velocity using the laser tracks calbration
+ // Get the correction of the drift velocity using the offline laser tracks calbration
//
// run - run number
// timeStamp - tim stamp in seconds
// side - 0 - A side, 1 - C side, 2 - mean from both sides
// Note in case no data form both A and C side - the value from active side used
TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+
+ return GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
+}
+
+Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksOnline(Double_t &dist, Int_t /*run*/, Int_t timeStamp, Double_t deltaT, Int_t side){
+ //
+ // Get the correction of the drift velocity using the online laser tracks calbration
+ //
+ // run - run number
+ // timeStamp - tim stamp in seconds
+ // deltaT - integration period to calculate time0 offset
+ // side - 0 - A side, 1 - C side, 2 - mean from both sides
+ // Note in case no data form both A and C side - the value from active side used
+ TObjArray *array =AliTPCcalibDB::Instance()->GetCEfitsDrift();
+
+ Double_t dv = GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
+ AliTPCParam *param =AliTPCcalibDB::Instance()->GetParameters();
+ if (!param) return 0;
+
+ //the drift velocity is hard wired in the AliTPCCalibCE class, since online there is no access to OCDB
+ dv*=param->GetDriftV()/2.61301900000000000e+06;
+ if (dv>1e-20) dv=1/dv-1;
+ else return 0;
+ // T/P correction
+ TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
+
+ AliTPCSensorTempArray *temp = (AliTPCSensorTempArray*)cearray->FindObject("TempMap");
+ AliDCSSensor *press = (AliDCSSensor*)cearray->FindObject("CavernAtmosPressure");
+
+ Double_t corrPTA=0;
+ Double_t corrPTC=0;
+
+ if (temp&&press) {
+ AliTPCCalibVdrift corr(temp,press,0);
+ corrPTA=corr.GetPTRelative(timeStamp,0);
+ corrPTC=corr.GetPTRelative(timeStamp,1);
+ }
+
+ if (side==0) dv -= corrPTA;
+ if (side==1) dv -= corrPTC;
+ if (side==2) dv -= (corrPTA+corrPTC)/2;
+
+ return dv;
+}
+
+Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksCommon(Double_t &dist, Int_t timeStamp, Double_t deltaT,
+ Int_t side, TObjArray * const array){
+ //
+ // common drift velocity retrieval for online and offline method
+ //
TGraphErrors *grlaserA=0;
TGraphErrors *grlaserC=0;
Double_t vlaserA=0, vlaserC=0;
grlaserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
grlaserC=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
Double_t deltaY;
- if (grlaserA) {
+ if (grlaserA && grlaserA->GetN()>0) {
AliTPCcalibDButil::GetNearest(grlaserA,timeStamp,dist,deltaY);
if (TMath::Abs(dist)>deltaT) vlaserA= deltaY;
else vlaserA = AliTPCcalibDButil::EvalGraphConst(grlaserA,timeStamp);
}
- if (grlaserC) {
+ if (grlaserC && grlaserC->GetN()>0) {
AliTPCcalibDButil::GetNearest(grlaserC,timeStamp,dist,deltaY);
if (TMath::Abs(dist)>deltaT) vlaserC= deltaY;
else vlaserC = AliTPCcalibDButil::EvalGraphConst(grlaserC,timeStamp);
Double_t gry=0;
Double_t corrA=0, corrC=0;
Double_t timeA=0, timeC=0;
+ const Double_t kEpsilon = 0.00001;
TGraph *graphA = (TGraph*)arrT->At(72);
TGraph *graphC = (TGraph*)arrT->At(73);
if (!graphA && !graphC) return 0.;
timeA = AliTPCcalibDButil::EvalGraphConst(graphA,timeStamp);
Int_t mtime =TMath::Nint((graphA->GetX()[0]+graphA->GetX()[graphA->GetN()-1])*0.5);
ltime0A = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
+ if(ltime0A < kEpsilon) return 0;
if (driftCalib) corrPTA = driftCalib->GetPTRelative(timeStamp,0);
corrA = (param->GetZLength(36)/(timeA*param->GetTSample()*(1.-ltime0A)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
corrA-=corrPTA;
timeC=AliTPCcalibDButil::EvalGraphConst(graphC,timeStamp);
Int_t mtime=TMath::Nint((graphC->GetX()[0]+graphC->GetX()[graphC->GetN()-1])*0.5);
ltime0C = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
- if (driftCalib) corrPTC = driftCalib->GetPTRelative(timeStamp,0);
+ if(ltime0C < kEpsilon) return 0;
+if (driftCalib) corrPTC = driftCalib->GetPTRelative(timeStamp,0);
corrC = (param->GetZLength(54)/(timeC*param->GetTSample()*(1.-ltime0C)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
corrC-=corrPTC;
}
return corrM;
}
+Double_t AliTPCcalibDButil::GetVDriftTPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
+ //
+ // return drift velocity using the TPC-ITS matchin method
+ // return also distance to the closest point
+ //
+ TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+ TGraphErrors *graph=0;
+ dist=0;
+ if (!array) return 0;
+ //array->ls();
+ graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
+ if (!graph) return 0;
+ Double_t deltaY;
+ AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
+ Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
+ return value;
+}
+
+Double_t AliTPCcalibDButil::GetTime0TPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
+ //
+ // Get time dependent time 0 (trigger delay in cm) correction
+ // Arguments:
+ // timestamp - timestamp
+ // run - run number
+ //
+ // Notice - Extrapolation outside of calibration range - using constant function
+ //
+ TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
+ TGraphErrors *graph=0;
+ dist=0;
+ if (!array) return 0;
+ graph = (TGraphErrors*)array->FindObject("ALIGN_ITSM_TPC_T0");
+ if (!graph) return 0;
+ Double_t deltaY;
+ AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
+ Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
+ return value;
+}
+
+
if (!tmpRun) continue;
fRunsStart[irun]=tmpRun->GetStartTime().GetSec();
fRunsStop[irun]=tmpRun->GetEndTime().GetSec();
- // printf("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec());
+ //AliInfo(Form("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec()));
}}
return fRuns.fN;
}
for (Int_t index=index0; index<=index1; index++){
if (fRunsStart[index]<=itime && fRunsStop[index]>=itime) cindex=index;
if (debug) {
- printf("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime);
+ AliInfo(Form("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime));
}
}
if (cindex<0) cindex =(index0+index1)/2;
Int_t npoints0 = graph->GetN();
Int_t npoints=0;
Float_t rmsY=0;
- Double_t *outx=new Double_t[npoints0];
- Double_t *outy=new Double_t[npoints0];
//
//
if (npoints0<kMinPoints) return 0;
+
+ Double_t *outx=new Double_t[npoints0];
+ Double_t *outy=new Double_t[npoints0];
for (Int_t iter=0; iter<3; iter++){
npoints=0;
for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
}
TGraph *graphOut=0;
if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
+ delete [] outx;
+ delete [] outy;
return graphOut;
}
Int_t npoints0 = graph->GetN();
Int_t npoints=0;
Float_t rmsY=0;
- Double_t *outx=new Double_t[npoints0];
- Double_t *outy=new Double_t[npoints0];
//
//
if (npoints0<kMinPoints) return 0;
+
+ Double_t *outx=new Double_t[npoints0];
+ Double_t *outy=new Double_t[npoints0];
for (Int_t iter=0; iter<3; iter++){
npoints=0;
for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
}
TGraph *graphOut=0;
if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
+ delete [] outx;
+ delete [] outy;
return graphOut;
}
-TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * graph, Float_t sigmaCut,Double_t &medianY){
+TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * const graph, Float_t sigmaCut,Double_t &medianY){
//
// filter outlyer measurement
// Only points with normalized errors median +- sigmaCut filtered
Int_t npoints0 = graph->GetN();
Int_t npoints=0;
Float_t medianErr=0, rmsErr=0;
+ //
+ //
+ if (npoints0<kMinPoints) return 0;
+
Double_t *outx=new Double_t[npoints0];
Double_t *outy=new Double_t[npoints0];
Double_t *erry=new Double_t[npoints0];
Double_t *nerry=new Double_t[npoints0];
Double_t *errx=new Double_t[npoints0];
- //
- //
- if (npoints0<kMinPoints) return 0;
+
for (Int_t iter=0; iter<3; iter++){
npoints=0;
for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry);
delete []outx;
delete []outy;
- delete []errx;
delete []erry;
+ delete []nerry;
+ delete []errx;
return graphOut;
}
for (Int_t i=0;i<npoints;i++) graph->GetX()[i]=outx[i];
for (Int_t i=0;i<npoints;i++) graph->GetY()[i]=outy[i];
+ delete [] indexes;
+ delete [] outx;
+ delete [] outy;
}
void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
//
delete[] outy;
}
-Double_t AliTPCcalibDButil::EvalGraphConst(TGraph *graph, Double_t xref){
+Double_t AliTPCcalibDButil::EvalGraphConst(TGraph * const graph, Double_t xref){
//
// Use constant interpolation outside of range
//
if (!graph) {
- printf("AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
+ AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
return 0;
}
+
if (graph->GetN()<1){
- printf("AliTPCcalibDButil::EvalGraphConst: Empty graph");
+ AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph \n");
return 0;
}
+
+
if (xref<graph->GetX()[0]) return graph->GetY()[0];
if (xref>graph->GetX()[graph->GetN()-1]) return graph->GetY()[graph->GetN()-1];
+
+ // AliInfo(Form("graph->Eval(graph->GetX()[0]) %f, graph->Eval(xref) %f \n",graph->Eval(graph->GetX()[0]), graph->Eval(xref)));
+
+ if(graph->GetN()==1)
+ return graph->Eval(graph->GetX()[0]);
+
+
+ return graph->Eval(xref);
+}
+
+Double_t AliTPCcalibDButil::EvalGraphConst(AliSplineFit *graph, Double_t xref){
+ //
+ // Use constant interpolation outside of range also for spline fits
+ //
+ if (!graph) {
+ AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
+ return 0;
+ }
+ if (graph->GetKnots()<1){
+ AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph");
+ return 0;
+ }
+ if (xref<graph->GetX()[0]) return graph->GetY0()[0];
+ if (xref>graph->GetX()[graph->GetKnots()-1]) return graph->GetY0()[graph->GetKnots()-1];
return graph->Eval( xref);
}
if (naccept<1) {
delete fit;
sensor->SetFit(0);
+ delete [] yin0;
+ delete [] yin1;
return 0.;
}
for (Int_t isensor=0; isensor<nsensors; isensor++){
AliDCSSensor *sensor = tempArray->GetSensorNum(isensor);
if (!sensor) continue;
- //printf("%d\n",isensor);
FilterSensor(sensor,ymin,ymax,kMaxDy, sigmaCut);
if (sensor->GetFit()==0){
//delete sensor;
}
-void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector *pcstream){
+void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector * const pcstream){
//
// Filter CE data
// Input parameters:
//
//
AliTPCSensorTempArray *tempMapCE = (AliTPCSensorTempArray *)cearray->FindObject("TempMap");
- AliDCSSensor * cavernPressureCE = (AliDCSSensor *) cearray->FindObject("CavernPressure");
+ AliDCSSensor * cavernPressureCE = (AliDCSSensor *) cearray->FindObject("CavernAtmosPressure");
if ( tempMapCE && cavernPressureCE){
//
- Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
- FilterSensor(cavernPressureCE,960,1050,10, 5.);
- if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
+ // Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
+ // FilterSensor(cavernPressureCE,960,1050,10, 5.);
+ // if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
+ Bool_t isOK=kTRUE;
if (isOK) {
// recalculate P/T correction map for time of the CE
AliTPCCalibVdrift * driftCalib = new AliTPCCalibVdrift(tempMapCE,cavernPressureCE ,0);
for (Int_t i=0; i<72;i++){
TGraph *graph= (TGraph*)arrT->At(i);
- if (!graph) continue;
+ if (!graph) continue;
+ graph->Sort();
if (graph->GetN()<kMinPoints){
arrT->AddAt(0,i);
delete graph; // delete empty graph
Double_t median = (isec%36<18) ? medianA: medianC;
Double_t rms = (isec%36<18) ? rmsA: rmsC;
Int_t naccept=0;
- for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){
+ // for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){ //not neccessary to remove first points
+ for (Int_t ipoint=0; ipoint<graph->GetN();ipoint++){
if (TMath::Abs(graph->GetY()[ipoint]-median)>cutAbs) continue;
if (TMath::Abs(graph->GetY()[ipoint]-median)>cutSigma*rms) continue;
vecX[naccept]= graph->GetX()[ipoint];
continue;
}
TGraph* graphTS= FilterGraphMedian(graphTS0,cutSigma,medianY);
+ if (!graphTS) continue;
graphTS->Sort();
AliTPCcalibDButil::SmoothGraph(graphTS,deltaT);
if (pcstream){
"\n";
}
delete graphTS0;
- if (!graphTS) continue;
arrT->AddAt(graphTS,i);
delete graph;
}
}
-void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector *pcstream){
+void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector * const pcstream){
//
// Filter Drift velocity measurement using the tracks
// 0. remove outlyers - error based
Double_t medianY=0;
if (!arrT) return;
for (Int_t i=0; i<arrT->GetEntries();i++){
- TGraphErrors *graph= (TGraphErrors*)arrT->At(i);
+ TGraphErrors *graph= dynamic_cast<TGraphErrors*>(arrT->At(i));
if (!graph) continue;
if (graph->GetN()<kMinPoints){
delete graph;
arrT->AddAt(0,i);
continue;
}
- TGraphErrors *graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
- if (!graph2) {
- delete graph; arrT->AddAt(0,i); continue;
+ TGraphErrors *graph2 = NULL;
+ if(graph->GetN()<10) {
+ graph2 = new TGraphErrors(graph->GetN(),graph->GetX(),graph->GetY(),graph->GetEX(),graph->GetEY());
+ if (!graph2) {
+ delete graph; arrT->AddAt(0,i); continue;
+ }
+ }
+ else {
+ graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
+ if (!graph2) {
+ delete graph; arrT->AddAt(0,i); continue;
+ }
}
if (graph2->GetN()<1) {
delete graph; arrT->AddAt(0,i); continue;
//if (index1-index0 <kMinPoints) { index1+=kMinPoints; index0-=kMinPoints;}
if (index0<0) index0=0;
if (index1>=npoints-1) index1=npoints-1;
- if (index1-index0<kMinPoints) return 0;
+ if (index1-index0<kMinPoints) {
+ delete [] ylaser;
+ delete [] xlaser;
+ return 0;
+ }
//
//Double_t median = TMath::Median(index1-index0, &(ylaser[index0]));
Double_t mean = TMath::Mean(index1-index0, &(ylaser[index0]));
-void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, Double_t minVd, Double_t maxVd, TTreeSRedirector *pcstream){
+void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, Double_t minVd, Double_t maxVd, TTreeSRedirector * const pcstream){
//
// Filter Goofie data
// goofieArray - points will be filtered
AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
- printf("%d\t%f\t%f\n",isensor, median,vrmsArray[isensor]);
+ // AliInfo(Form("%d\t%f\t%f\n",isensor, median,vrmsArray[isensor]));
vmedianArray[isensor]=median;
//
}
}
+
+
+
+TMatrixD* AliTPCcalibDButil::MakeStatRelKalman(TObjArray * const array, Float_t minFraction, Int_t minStat, Float_t maxvd){
+ //
+ // Make a statistic matrix
+ // Input parameters:
+ // array - TObjArray of AliRelKalmanAlign
+ // minFraction - minimal ration of accepted tracks
+ // minStat - minimal statistic (number of accepted tracks)
+ // maxvd - maximal deviation for the 1
+ // Output matrix:
+ // columns - Mean, Median, RMS
+ // row - parameter type (rotation[3], translation[3], drift[3])
+ if (!array) return 0;
+ if (array->GetEntries()<=0) return 0;
+ // Int_t entries = array->GetEntries();
+ Int_t entriesFast = array->GetEntriesFast();
+ TVectorD state(9);
+ TVectorD *valArray[9];
+ for (Int_t i=0; i<9; i++){
+ valArray[i] = new TVectorD(entriesFast);
+ }
+ Int_t naccept=0;
+ for (Int_t ikalman=0; ikalman<entriesFast; ikalman++){
+ AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(ikalman);
+ if (!kalman) continue;
+ if (TMath::Abs(kalman->GetTPCvdCorr()-1)>maxvd) continue;
+ if (kalman->GetNUpdates()<minStat) continue;
+ if (Float_t(kalman->GetNUpdates())/Float_t(kalman->GetNTracks())<minFraction) continue;
+ kalman->GetState(state);
+ for (Int_t ipar=0; ipar<9; ipar++)
+ (*valArray[ipar])[naccept]=state[ipar];
+ naccept++;
+ }
+ //if (naccept<2) return 0;
+ if (naccept<1) return 0;
+ TMatrixD *pstat=new TMatrixD(9,3);
+ TMatrixD &stat=*pstat;
+ for (Int_t ipar=0; ipar<9; ipar++){
+ stat(ipar,0)=TMath::Mean(naccept, valArray[ipar]->GetMatrixArray());
+ stat(ipar,1)=TMath::Median(naccept, valArray[ipar]->GetMatrixArray());
+ stat(ipar,2)=TMath::RMS(naccept, valArray[ipar]->GetMatrixArray());
+ }
+ return pstat;
+}
+
+
+TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const array, const TMatrixD & stat, Bool_t direction, Float_t sigmaCut){
+ //
+ // Smooth the array of AliRelKalmanAlign - detector alignment and drift calibration)
+ // Input:
+ // array - input array
+ // stat - mean parameters statistic
+ // direction -
+ // sigmaCut - maximal allowed deviation from mean in terms of RMS
+ if (!array) return 0;
+ if (array->GetEntries()<=0) return 0;
+ if (!(&stat)) return 0;
+ // error increase in 1 hour
+ const Double_t kerrsTime[9]={
+ 0.00001, 0.00001, 0.00001,
+ 0.001, 0.001, 0.001,
+ 0.002, 0.01, 0.001};
+ //
+ //
+ Int_t entries = array->GetEntriesFast();
+ TObjArray *sArray= new TObjArray(entries);
+ AliRelAlignerKalman * sKalman =0;
+ TVectorD state(9);
+ for (Int_t i=0; i<entries; i++){
+ Int_t index=(direction)? entries-i-1:i;
+ AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(index);
+ if (!kalman) continue;
+ Bool_t isOK=kTRUE;
+ kalman->GetState(state);
+ for (Int_t ipar=0; ipar<9; ipar++){
+ if (TMath::Abs(state[ipar]-stat(ipar,1))>sigmaCut*stat(ipar,2)) isOK=kFALSE;
+ }
+ if (!sKalman &&isOK) {
+ sKalman=new AliRelAlignerKalman(*kalman);
+ sKalman->SetRejectOutliers(kFALSE);
+ sKalman->SetRunNumber(kalman->GetRunNumber());
+ sKalman->SetTimeStamp(kalman->GetTimeStamp());
+ }
+ if (!sKalman) continue;
+ Double_t deltaT=TMath::Abs(Int_t(kalman->GetTimeStamp())-Int_t(sKalman->GetTimeStamp()))/3600.;
+ for (Int_t ipar=0; ipar<9; ipar++){
+// (*(sKalman->GetStateCov()))(6,6)+=deltaT*errvd*errvd;
+// (*(sKalman->GetStateCov()))(7,7)+=deltaT*errt0*errt0;
+// (*(sKalman->GetStateCov()))(8,8)+=deltaT*errvy*errvy;
+ (*(sKalman->GetStateCov()))(ipar,ipar)+=deltaT*kerrsTime[ipar]*kerrsTime[ipar];
+ }
+ sKalman->SetRunNumber(kalman->GetRunNumber());
+ if (!isOK) sKalman->SetRunNumber(0);
+ sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
+ if (!isOK) continue;
+ sKalman->SetRejectOutliers(kFALSE);
+ sKalman->SetRunNumber(kalman->GetRunNumber());
+ sKalman->SetTimeStamp(kalman->GetTimeStamp());
+ sKalman->Merge(kalman);
+ sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
+ //sKalman->Print();
+ }
+ return sArray;
+}
+
+TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const arrayP, TObjArray * const arrayM){
+ //
+ // Merge 2 RelKalman arrays
+ // Input:
+ // arrayP - rel kalman in direction plus
+ // arrayM - rel kalman in direction minus
+ if (!arrayP) return 0;
+ if (arrayP->GetEntries()<=0) return 0;
+ if (!arrayM) return 0;
+ if (arrayM->GetEntries()<=0) return 0;
+
+ Int_t entries = arrayP->GetEntriesFast();
+ TObjArray *array = new TObjArray(arrayP->GetEntriesFast());
+
+ for (Int_t i=0; i<entries; i++){
+ AliRelAlignerKalman * kalmanP = (AliRelAlignerKalman *) arrayP->UncheckedAt(i);
+ AliRelAlignerKalman * kalmanM = (AliRelAlignerKalman *) arrayM->UncheckedAt(i);
+ if (!kalmanP) continue;
+ if (!kalmanM) continue;
+
+ AliRelAlignerKalman *kalman = NULL;
+ if(kalmanP->GetRunNumber() != 0 && kalmanM->GetRunNumber() != 0) {
+ kalman = new AliRelAlignerKalman(*kalmanP);
+ kalman->Merge(kalmanM);
+ }
+ else if (kalmanP->GetRunNumber() == 0) {
+ kalman = new AliRelAlignerKalman(*kalmanM);
+ }
+ else if (kalmanM->GetRunNumber() == 0) {
+ kalman = new AliRelAlignerKalman(*kalmanP);
+ }
+ else
+ continue;
+
+ array->AddAt(kalman,i);
+ }
+
+ return array;
+}