// ITS specific alignment class which interface to AliMillepede.
// For each track ProcessTrack calculates the local and global derivatives
// at each hit and fill the corresponding local equations. Provide methods for
-// fixing or constraining detection elements for best results.
+// fixing or constraning detection elements for best results.
//
// author M. Lunardon (thanks to J. Castillo), ruben.shahoyan@cern.ch
//-----------------------------------------------------------------------------
#include <TFile.h>
+#include <TGrid.h>
#include <TClonesArray.h>
#include <TMath.h>
#include <TVirtualFitter.h>
#include <TRandom.h>
#include <TCollection.h>
#include <TGeoPhysicalNode.h>
+#include <TMap.h>
+#include <TObjString.h>
+#include <TString.h>
#include "AliITSAlignMille2.h"
#include "AliITSgeomTGeo.h"
#include "AliGeomManager.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBEntry.h"
-
+#include "AliITSsegmentationSDD.h"
+#include "AliITSDriftSpeedArraySDD.h"
+#include "AliITSCorrectSDDPoints.h"
+#include "AliESDVertex.h"
ClassImp(AliITSAlignMille2)
const Char_t* AliITSAlignMille2::fgkRecKeys[] = {
"OCDB_PATH",
+ "OCDB_SPECIFIC",
"GEOMETRY_FILE",
"SUPERMODULE_FILE",
"CONSTRAINTS_REFERENCE_FILE",
"PREALIGNMENT_FILE",
"PRECALIBSDD_FILE",
+ "PREVDRIFTSDD_FILE",
+ "PRECORRMAPSDD_FILE",
+ "INITCORRMAPSDD_FILE",
"INITCALBSDD_FILE",
+ "INITVDRIFTSDD_FILE",
"INITDELTA_FILE",
+ "INITGEOM_FILE",
"SET_GLOBAL_DELTAS",
"CONSTRAINT_LOCAL",
"MODULE_VOLUID",
"SET_RESCUT_OTHER",
"SET_LOCALSIGMAFACTOR",
"SET_STARTFAC",
+ "SET_FINALFAC",
"SET_B_FIELD",
"SET_SPARSE_MATRIX",
"REQUIRE_POINT",
"SET_EXTRA_CLUSTERS_MODE",
"SET_USE_TPAFITTER",
"SET_USE_LOCAL_YERROR",
- "SET_MIN_POINTS_PER_MODULE"
-
+ "SET_MIN_POINTS_PER_MODULE",
+ "SET_USE_SDDVDCORRMULT",
+ "SET_WEIGHT_PT",
+ "SET_USE_DIAMOND",
+ "CORRECT_DIAMOND",
+ "SET_USE_VERTEX",
+ "SET_SAME_SDDT0"
};
const Char_t AliITSAlignMille2::fgkXYZ[] = "XYZ";
: TObject(),
fMillepede(0),
fStartFac(16.),
+ fFinalFac(1.),
fResCutInitial(100.),
fResCut(100.),
fNGlobal(0),
fConstrPT(-1),
fConstrPTErr(-1),
fConstrCharge(0),
+ fRunID(0),
//
fMinNPtsPerTrack(3),
- fInitTrackParamsMeth(1),
+ fIniTrackParamsMeth(1),
fTotBadLocEqPoints(0),
fRieman(0),
//
fCacheMatrixCurr(kMaxITSSensID+1),
//
fUseGlobalDelta(kFALSE),
- fRequirePoints(kFALSE),
fTempExcludedModule(-1),
+ fUserProvided(0),
//
- fDefCDBpath("local://$ALICE_ROOT/OCDB"),
- fInitDeltaPath(""),
- fInitSDDRespPath(""),
+ fIniUserInfo(userInfo),
+ fIniGeomPath(""),
+ fIniDeltaPath(""),
+ fIniSDDRespPath(""),
fPreCalSDDRespPath(""),
- fGeometryPath("geometry.root"),
+ fIniSDDVDriftPath(""),
+ fPreSDDVDriftPath(""),
+ fIniSDDCorrMapPath(""),
+ fPreSDDCorrMapPath(""),
+ fConvertPreDeltas(kFALSE),
+ fGeometryPath(""),
fPreDeltaPath(""),
fConstrRefPath(""),
+ fDiamondPath(""),
fGeoManager(0),
fIsConfigured(kFALSE),
fPreAlignQF(0),
//
- fCorrectSDD(0),
- fInitialRecSDD(0),
+ fIniRespSDD(0),
+ fPreRespSDD(0),
+ fIniVDriftSDD(0),
+ fPreVDriftSDD(0),
+ fIniCorrMapSDD(0),
+ fPreCorrMapSDD(0),
+ fSegmentationSDD(0),
fPrealignment(0),
fConstrRef(0),
fMilleModule(2),
fUseLocalYErr(kFALSE),
fBOn(kFALSE),
fBField(0.0),
+ fDataType(kCosmics),
fMinPntPerSens(0),
fBug(0),
fMilleVersion(2),
- fExtraClustersMode(0)
+ fExtraClustersMode(0),
+ fTrackWeight(1),
+ fWeightPt(0.),
+ fIsSDDVDriftMult(kFALSE),
+ fDiamond(),
+ fDiamondI(),
+ fUseDiamond(kFALSE),
+ fUseVertex(kFALSE),
+ fVertexSet(kFALSE),
+ fDiamondPointID(-1),
+ fDiamondModID(-1),
+ fCheckDiamondPoint(kDiamondCheckIfPrompt),
+ fFixCurvIfConstraned(kTRUE),
+ fCurvFitWasConstrained(kFALSE),
+ fConvAlgMatOld(100)
{
/// main constructor that takes input from configuration file
for (int i=3;i--;) fSigmaFactor[i] = 1.0;
//
// new RS
- for (Int_t i=0; i<6; i++) {
- fNReqLayUp[i]=0;
- fNReqLayDown[i]=0;
- fNReqLay[i]=0;
+ for (int i=0;i<3;i++) {
+ fCorrDiamond[i] = 0;
}
- for (Int_t i=0; i<3; i++) {
- fNReqDetUp[i]=0;
- fNReqDetDown[i]=0;
- fNReqDet[i]=0;
+ for (int itp=0;itp<kNDataType;itp++) {
+ fRequirePoints[itp] = kFALSE;
+ for (Int_t i=0; i<6; i++) {
+ fNReqLayUp[itp][i]=0;
+ fNReqLayDown[itp][i]=0;
+ fNReqLay[itp][i]=0;
+ }
+ for (Int_t i=0; i<3; i++) {
+ fNReqDetUp[itp][i]=0;
+ fNReqDetDown[itp][i]=0;
+ fNReqDet[itp][i]=0;
+ }
}
//
- if (ProcessUserInfo(userInfo)) exit(1);
+ // if (ProcessUserInfo(userInfo)) exit(1);
+ //
+ fDiamond.SetVolumeID(kVtxSensVID);
+ fDiamondI.SetVolumeID(kVtxSensVID);
+ float xyzd[3] = {0,0,0};
+ float covd[6] = {1,0,0,1,0,1e4};
+ fDiamond.SetXYZ(xyzd,covd); // dummy diamond
+ covd[5] = 1e-4;
+ fDiamondI.SetXYZ(xyzd,covd);
//
Int_t lc=LoadConfig(configFilename);
if (lc) {
fMillepede = new AliMillePede2();
fgInstance = this;
fgInstanceID++;
+ ResetCovIScale();
//
}
delete fRieman;
delete fPrealignment;
delete fConstrRef;
- delete fCorrectSDD;
- delete fInitialRecSDD;
+ delete fPreRespSDD;
+ delete fIniRespSDD;
+ delete fSegmentationSDD;
+ delete fIniVDriftSDD;
+ delete fPreVDriftSDD;
+ delete fIniCorrMapSDD;
+ delete fPreCorrMapSDD;
delete fTPAFitter;
fCacheMatrixOrig.Delete();
fCacheMatrixCurr.Delete();
TString record;
static TObjArray* recElems = 0;
if (recElems) {delete recElems; recElems = 0;}
+ recOpt = "";
//
TString keyws = recTitle;
if (!keyws.IsNull()) {
//________________________________________________________________________________________________________
Int_t AliITSAlignMille2::CheckConfigRecords(FILE* stream)
{
+ // check the correctness of the record
TString record,recTitle;
int lineCnt = 0;
rewind(stream);
// return 0 if success
// 1 if error in module index or voluid
//
+ AliInfo(Form("Loading MillePede2 configuration from %s",cfile));
+ AliCDBManager::Instance()->SetCacheFlag(kFALSE);
FILE *pfc=fopen(cfile,"r");
if (!pfc) return -1;
//
//
// ============= 1: we read some important records in predefined order ================
//
- recTitle = fgkRecKeys[kOCDBPath];
- if ( GetConfigRecord(pfc,recTitle,recOpt,1) && !(fDefCDBpath=recOpt).IsNull() ) {
- AliInfo(Form("Configuration sets OCDB Def.Storage to %s",fDefCDBpath.Data()));
- AliCDBManager::Instance()->SetDefaultStorage( fDefCDBpath.Data() );
+ recTitle = fgkRecKeys[kOCDBDefaultPath];
+ if ( GetConfigRecord(pfc,recTitle,recOpt,1) && !recOpt.IsNull() ) {
+ AliInfo(Form("Configuration sets OCDB default storage to %s",recOpt.Data()));
+ AliCDBManager::Instance()->SetDefaultStorage( gSystem->ExpandPathName(recOpt.Data()) );
+ TObjString* objStr = (TObjString*)AliCDBManager::Instance()->GetStorageMap()->GetValue("default");
+ if (!objStr) {stopped = kTRUE; break;}
+ objStr->SetUniqueID(1); // mark as user set
}
//
+ if (fIniUserInfo && ProcessUserInfo(fIniUserInfo)) { AliError("Failed to process intial User Info"); stopped = kTRUE; break;}
//
recTitle = fgkRecKeys[kGeomFile];
- if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) fGeometryPath = recOpt;
- if ( InitGeometry() ) { AliError("Failed to find/load Geometry"); stopped = kTRUE; break;}
+ if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) fGeometryPath = gSystem->ExpandPathName(recOpt.Data());
+ if ( LoadGeometry(fGeometryPath) ) { AliError("Failed to find/load target ideal Geometry"); stopped = kTRUE; break;}
//
+ // Do we use new TrackPointArray fitter ?
+ recTitle = fgkRecKeys[kTPAFitter];
+ if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) fTPAFitter = new AliITSTPArrayFit(kNLocal);
//
recTitle = fgkRecKeys[kSuperModileFile];
if ( !GetConfigRecord(pfc,recTitle,recOpt,1) ||
recOpt.IsNull() ||
+ gSystem->ExpandPathName(recOpt) ||
gSystem->AccessPathName(recOpt.Data()) ||
LoadSuperModuleFile(recOpt.Data()))
{ AliError("Failed to find/load SuperModules"); stopped = kTRUE; break;}
//
- //
recTitle = fgkRecKeys[kConstrRefFile]; // LOCAL_CONSTRAINTS are defined wrt these deltas
if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) ) {
if (recOpt.IsNull() || recOpt=="IDEAL") SetConstraintWrtRef( "IDEAL" );
}
}
//
+ recTitle = fgkRecKeys[kInitGeomFile];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull() ) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fIniGeomPath = recOpt;
+ gSystem->ExpandPathName(fIniGeomPath);
+ fUserProvided |= kSameInitGeomBit;
+ AliInfo(Form("Configuration sets Production Geometry to %s",fIniGeomPath.Data()));
+ }
+ if (fIniGeomPath.IsNull()) fIniGeomPath = fGeometryPath;
//
recTitle = fgkRecKeys[kInitDeltaFile];
- if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull() ) {
for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
- fInitDeltaPath = recOpt;
- AliInfo(Form("Configuration sets Production Deltas to %s",fInitDeltaPath.Data()));
+ fIniDeltaPath = recOpt;
+ gSystem->ExpandPathName(fIniDeltaPath);
+ fUserProvided |= kSameInitDeltasBit;
+ AliInfo(Form("Configuration sets Production Deltas to %s",fIniDeltaPath.Data()));
+ }
+ //
+ recTitle = fgkRecKeys[kPreDeltaFile];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) ) {
+ if (!recOpt.IsNull()) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fPreDeltaPath = recOpt;
+ gSystem->ExpandPathName(fPreDeltaPath);
+ }
+ else if (!fIniDeltaPath.IsNull()) {
+ AliInfo("PreAlignment Deltas keyword is present but empty, will set to Init Deltas of the first tree");
+ fPreDeltaPath = fIniDeltaPath;
+ if (fIniGeomPath != fGeometryPath) fConvertPreDeltas = kTRUE; // production and target geometries are different, request conversion
+ }
+ AliInfo(Form("Configuration sets PreAlignment Deltas to %s",fPreDeltaPath.Data()));
}
//
// if initial deltas were provided, load them, apply to geometry and store are "original" matrices
if (CacheMatricesOrig()) {stopped = kTRUE; break;}
//
- recTitle = fgkRecKeys[kPreDeltaFile];
- if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
- for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
- fPreDeltaPath = recOpt;
- AliInfo(Form("Configuration sets PreAlignment Deltas to %s",fPreDeltaPath.Data()));
+ // then load prealignment deltas
+ if (!fPreDeltaPath.IsNull()) {
+ if (fConvertPreDeltas) ConvertDeltas(); // Prealignment deltas are the same as production ones, but need conversion to new geometry
+ else if (LoadDeltas(fPreDeltaPath,fPrealignment)) {stopped = kTRUE; break;} // read deltas from the file
}
- if (LoadDeltas(fPreDeltaPath,fPrealignment)) {stopped = kTRUE; break;}
if (fPrealignment && ApplyToGeometry()) {stopped = kTRUE; break;}
//
+ recTitle = fgkRecKeys[ kInitCalSDDFile ];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fIniSDDRespPath = recOpt;
+ gSystem->ExpandPathName(fIniSDDRespPath);
+ fUserProvided |= kSameInitSDDRespBit;
+ AliInfo(Form("Configuration sets Production SDD Response to %s",fIniSDDRespPath.Data()));
+ }
+ if (LoadSDDResponse(fIniSDDRespPath, fIniRespSDD) ) {stopped = kTRUE; break;}
//
- recTitle = fgkRecKeys[kPreCalSDDFile];
- if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull() ) {
+ //
+ recTitle = fgkRecKeys[ kInitCorrMapSDDFile ];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
- fPreCalSDDRespPath = recOpt;
+ fIniSDDCorrMapPath = recOpt;
+ gSystem->ExpandPathName(fIniSDDCorrMapPath);
+ fUserProvided |= kSameInitSDDCorrMapBit;
+ AliInfo(Form("Configuration sets Production SDD Correction Map to %s",fIniSDDCorrMapPath.Data()));
+ }
+ if (LoadSDDCorrMap(fIniSDDCorrMapPath, fIniCorrMapSDD) ) {stopped = kTRUE; break;}
+ //
+ recTitle = fgkRecKeys[kPreCalSDDFile];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) ) {
+ if (!recOpt.IsNull()) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fPreCalSDDRespPath = recOpt;
+ gSystem->ExpandPathName(fPreCalSDDRespPath);
+ }
+ else if (!fIniSDDRespPath.IsNull()) {
+ AliInfo("PreCalibration SDD response keyword is present but empty, will set to Init SDD repsonse");
+ fPreCalSDDRespPath = fIniSDDRespPath;
+ }
AliInfo(Form("Configuration sets PreCalibration SDD Response to %s",fPreCalSDDRespPath.Data()));
}
- if (LoadSDDResponse(fPreCalSDDRespPath, fCorrectSDD) ) {stopped = kTRUE; break;}
//
- recTitle = fgkRecKeys[ kInitCalSDDFile ];
+ if (LoadSDDResponse(fPreCalSDDRespPath, fPreRespSDD) ) {stopped = kTRUE; break;}
+ //
+ recTitle = fgkRecKeys[kPreCorrMapSDDFile];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) ) {
+ if (!recOpt.IsNull()) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fPreSDDCorrMapPath = recOpt;
+ gSystem->ExpandPathName(fPreSDDCorrMapPath);
+ }
+ else if (!fIniSDDCorrMapPath.IsNull()) {
+ AliInfo("PreCalibration SDD Correction Map keyword is present but empty, will set to Init SDD Correction Map");
+ fPreSDDCorrMapPath = fIniSDDCorrMapPath;
+ }
+ AliInfo(Form("Configuration sets PreCalibration SDD Correction Map to %s",fPreSDDCorrMapPath.Data()));
+ }
+ //
+ if (LoadSDDCorrMap(fPreSDDCorrMapPath, fPreCorrMapSDD) ) {stopped = kTRUE; break;}
+ // //
+ recTitle = fgkRecKeys[ kInitVDriftSDDFile ];
if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
- fInitSDDRespPath = recOpt;
- AliInfo(Form("Configuration sets Production SDD Response to %s",fInitSDDRespPath.Data()));
+ fIniSDDVDriftPath = recOpt;
+ gSystem->ExpandPathName(fIniSDDVDriftPath);
+ fUserProvided |= kSameInitSDDVDriftBit;
+ AliInfo(Form("Configuration sets Production SDD VDrift to %s",fIniSDDVDriftPath.Data()));
}
- if (LoadSDDResponse(fInitSDDRespPath, fInitialRecSDD) ) {stopped = kTRUE; break;}
+ if (LoadSDDVDrift(fIniSDDVDriftPath, fIniVDriftSDD) ) {stopped = kTRUE; break;}
//
+ recTitle = fgkRecKeys[ kPreVDriftSDDFile ];
+ if ( (recArr = GetConfigRecord(pfc,recTitle,recOpt,1)) && !recOpt.IsNull()) {
+ for (int i=2;i<=recArr->GetLast();i++) {recOpt += " "; recOpt += recArr->At(i)->GetName();} // in case of OCDB string
+ fPreSDDVDriftPath = recOpt;
+ gSystem->ExpandPathName(fPreSDDVDriftPath);
+ AliInfo(Form("Configuration sets PreCalibration SDD VDrift to %s",fPreSDDVDriftPath.Data()));
+ if (LoadSDDVDrift(fPreSDDVDriftPath, fPreVDriftSDD) ) {stopped = kTRUE; break;}
+ }
//
recTitle = fgkRecKeys[ kGlobalDeltas ];
if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) SetUseGlobalDelta(kTRUE);
//
+ recTitle = fgkRecKeys[ kUseDiamond ];
+ if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) {
+ if (!GetUseGlobalDelta()) {
+ AliError("Diamond constraint is supported only for Global Frame mode");
+ stopped = kTRUE;
+ break;
+ }
+ fUseDiamond = kTRUE;
+ if (!recOpt.IsNull()) {
+ fDiamondPath = recOpt;
+ gSystem->ExpandPathName(fDiamondPath);
+ fUserProvided |= kSameDiamondBit;
+ AliInfo(Form("Configuration sets Diamond constraint to %s",fDiamondPath.Data()));
+ }
+ }
+ //
+ recTitle = fgkRecKeys[ kUseVertex ];
+ if ( GetConfigRecord(pfc,recTitle,recOpt,1) ) {
+ if (!GetUseGlobalDelta()) {
+ AliError("Vertex constraint is supported only for Global Frame mode");
+ stopped = kTRUE;
+ break;
+ }
+ fUseVertex = kTRUE;
+ if (fUseDiamond) {
+ AliError("Cannot use Vertex and Diamond constraints at the same time");
+ stopped = kTRUE;
+ break;
+ }
+ AliInfo("Will use Vertex constraint when available");
+ }
// =========== 2: see if there are local gaussian constraints defined =====================
// Note that they should be loaded before the modules declaration
//
// =========== 3: now read modules to align ===================================
//
rewind(pfc);
+ // create fixed modules
+ for (int j=0; j<fNSuperModules; j++) {
+ AliITSAlignMille2Module* proto = GetSuperModule(j);
+ if (!proto->IsAlignable()) continue;
+ AliITSAlignMille2Module* mod = new AliITSAlignMille2Module(*proto);
+ // the matrix might be updated in case some prealignment was applied, check
+ TGeoHMatrix* mup = AliGeomManager::GetMatrix(mod->GetName());
+ if (mup) *(mod->GetMatrix()) = *mup;
+ fMilleModule.AddAtAndExpand(mod,fNModules);
+ mod->SetGeomParamsGlobal(fUseGlobalDelta);
+ mod->SetUniqueID(fNModules++);
+ mod->SetNotInConf(kTRUE);
+ }
+ CreateVertexModule();
+ //
while( (recArr=GetConfigRecord(pfc,recTitle="",recOpt,0)) ) {
if (!(recTitle==fgkRecKeys[ kModVolID ] || recTitle==fgkRecKeys[ kModIndex ])) continue;
// Expected format: MODULE id tolX tolY tolZ tolPsi tolTh tolPhi [[sigX sigY sigZ] extra params]
AliITSAlignMille2Module* mod = 0;
//
if (voluid>=kMinITSSupeModuleID) { // custom supermodule
- for (int j=0; j<fNSuperModules; j++) {
- if (voluid==GetSuperModule(j)->GetVolumeID()) {
- mod = new AliITSAlignMille2Module(*GetSuperModule(j));
- // the matrix might be updated in case some prealignment was applied, check
- TGeoHMatrix* mup = AliGeomManager::GetMatrix(mod->GetName());
- if (mup) *(mod->GetMatrix()) = *mup;
- fMilleModule.AddAtAndExpand(mod,fNModules);
- break;
- }
+ mod = GetMilleModuleByVID(voluid);
+ if (!mod) { // need to create
+ for (int j=0; j<fNSuperModules; j++) {
+ if (voluid==GetSuperModule(j)->GetVolumeID()) {
+ mod = new AliITSAlignMille2Module(*GetSuperModule(j));
+ // the matrix might be updated in case some prealignment was applied, check
+ TGeoHMatrix* mup = AliGeomManager::GetMatrix(mod->GetName());
+ if (mup) *(mod->GetMatrix()) = *mup;
+ fMilleModule.AddAtAndExpand(mod,fNModules);
+ mod->SetGeomParamsGlobal(fUseGlobalDelta);
+ mod->SetUniqueID(fNModules++);
+ break;
+ }
+ }
}
+ mod->SetNotInConf(kFALSE);
}
else if (idx<=kMaxITSSensVID) {
mod = new AliITSAlignMille2Module(voluid);
fMilleModule.AddAtAndExpand(mod,fNModules);
+ mod->SetGeomParamsGlobal(fUseGlobalDelta);
+ mod->SetUniqueID(fNModules++);
}
if (!mod) {stopped = kTRUE; break;} // bad volid
//
}
if (stopped) break;
//
- mod->SetGeomParamsGlobal(fUseGlobalDelta);
// now comes special detectors treatment
if (mod->IsSDD()) {
double vl = 0;
}
mod->SetFreeDOF(AliITSAlignMille2Module::kDOFT0,vl);
//
- vl = 0;
- if (nrecElems>12) {
- recExt = recArr->At(12)->GetName();
- if (recExt.IsFloat()) vl = recExt.Atof();
- else {stopped = kTRUE; break;}
- irec = 12;
+ Bool_t cstLR = kFALSE;
+ for (int lr=0;lr<2;lr++) { // left right side vdrift corrections
+ vl = 0;
+ if (nrecElems>12+lr) {
+ recExt = recArr->At(12+lr)->GetName();
+ if (recExt.IsFloat()) vl = recExt.Atof();
+ else {stopped = kTRUE; break;}
+ irec = 12+lr;
+ }
+ mod->SetFreeDOF(lr==0 ? AliITSAlignMille2Module::kDOFDVL : AliITSAlignMille2Module::kDOFDVR,vl);
+ if (lr==1 && vl>=10) cstLR = kTRUE; // the right side should be constrained to left one
}
- mod->SetFreeDOF(AliITSAlignMille2Module::kDOFDV,vl);
+ if (cstLR) mod->SetVDriftLRSame();
}
//
- mod->SetUniqueID(fNModules);
mod->EvaluateDOF();
- fNModules++;
//
// now check if there are local constraints on this module
for (++irec;irec<nrecElems;irec++) {
fStartFac = recOpt.Atof();
}
//
+ else if (recTitle == fgkRecKeys[ kFinalFactor ]) { //-------------------------
+ if (recOpt.IsNull() || !recOpt.IsFloat() ) {stopped = kTRUE; break;}
+ fFinalFac = recOpt.Atof();
+ }
+ //
// pepo2708909
else if (recTitle == fgkRecKeys[ kExtraClustersMode ]) { //-------------------------
if (recOpt.IsNull() || !recOpt.IsDigit() ) {stopped = kTRUE; break;}
SetBField( recOpt.Atof() );
}
//
+ else if (recTitle == fgkRecKeys[ kSDDVDCorrMult ]) { //-------------------------
+ SetSDDVDCorrMult( recOpt.IsNull() || (recOpt.IsFloat() && (recOpt.Atof())>-0.5) );
+ }
+ //
+ else if (recTitle == fgkRecKeys[ kWeightPt ]) { //-------------------------
+ double wgh = 1;
+ if (!recOpt.IsNull()) {
+ if (!recOpt.IsFloat()) {stopped = kTRUE; break;}
+ else wgh = recOpt.Atof();
+ }
+ SetWeightPt(wgh);
+ }
+ //
else if (recTitle == fgkRecKeys[ kSparseMatrix ]) { // matrix solver type
//
AliMillePede2::SetGlobalMatSparse(kTRUE);
int lr = ((TObjString*)recArr->At(2))->GetString().Atoi() - 1;
int hb = ((TObjString*)recArr->At(3))->GetString().Atoi();
int np = ((TObjString*)recArr->At(4))->GetString().Atoi();
- fRequirePoints = kTRUE;
- if (recOpt == "LAYER") {
- if (lr<0 || lr>5) {stopped = kTRUE; break;}
- if (hb>0) fNReqLayUp[lr] = np;
- else if (hb<0) fNReqLayDown[lr] = np;
- else fNReqLay[lr] = np;
+ //
+ int rtp = -1; // use for run type
+ if (nrecElems>5) {
+ TString tpstr = ((TObjString*)recArr->At(5))->GetString();
+ if ( tpstr.Contains("cosmics",TString::kIgnoreCase) ) rtp = kCosmics;
+ else if ( tpstr.Contains("collision",TString::kIgnoreCase) ) rtp = kCollision;
+ else {stopped = kTRUE; break;}
}
- else if (recOpt == "DETECTOR") {
- if (lr<0 || lr>2) {stopped = kTRUE; break;}
- if (hb>0) fNReqDetUp[lr] = np;
- else if (hb<0) fNReqDetDown[lr] = np;
- else fNReqDet[lr] = np;
+ //
+ int tpmn= rtp<0 ? 0 : rtp;
+ int tpmx= rtp<0 ? kNDataType-1 : rtp;
+ for (int itp=tpmn;itp<=tpmx;itp++) {
+ fRequirePoints[itp]=kTRUE;
+ if (recOpt == "LAYER") {
+ if (lr<0 || lr>5) {stopped = kTRUE; break;}
+ if (hb>0) fNReqLayUp[itp][lr]=np;
+ else if (hb<0) fNReqLayDown[itp][lr]=np;
+ else fNReqLay[itp][lr]=np;
+ }
+ else if (recOpt == "DETECTOR") {
+ if (lr<0 || lr>2) {stopped = kTRUE; break;}
+ if (hb>0) fNReqDetUp[itp][lr]=np;
+ else if (hb<0) fNReqDetDown[itp][lr]=np;
+ else fNReqDet[itp][lr]=np;
+ }
+ else {stopped = kTRUE; break;}
}
- else {stopped = kTRUE; break;}
+ if (stopped) break;
}
else {stopped = kTRUE; break;}
}
}
//
else if (recTitle == fgkRecKeys[ kConstrSubunits ]) { //------------------------
- // expect ONSTRAINT_SUBUNITS MEAN/MEDIAN Value parID0 ... parID1 ... VolID1 ... VolIDn - VolIDm
+ // expect CONSTRAINT_SUBUNITS MEAN/MEDIAN Value parID0 ... parID1 ... VolID1 ... VolIDn - VolIDm
if (nrecElems<5) {stopped = kTRUE; break;}
recExt = recArr->At(2)->GetName();
if (!recExt.IsFloat()) {stopped = kTRUE; break;}
if (rangeStart>=0) stopped = kTRUE; // unfinished range
if (stopped) break;
}
- // Do we use new TrackPointArray fitter ?
- else if (recTitle == fgkRecKeys[ kTPAFitter ]) {
- // expect SET_TPAFITTER
- fTPAFitter = new AliITSTPArrayFit(kNLocal);
+ //
+ // request of the same T0 for group of SDD modules
+ else if (recTitle == fgkRecKeys[ kSameSDDT0 ]) { //------------------------
+ // expect SET_SAME_SDDT0 [SensID1 ... SensIDn - SensIDm]
+ if (nrecElems<3) {stopped = kTRUE; break;}
+ //
+ // now read the list of modules to constrain
+ int curID = -1;
+ int rangeStart = -1;
+ AliITSAlignMille2ConstrArray *cstrT0 = new AliITSAlignMille2ConstrArray("SDDT0",0,0,0,0);
+ int naddM = 0;
+ cstrT0->SetPattern(BIT(AliITSAlignMille2Module::kDOFT0));
+ for (irec=1;irec<nrecElems;irec++) { // read modules to apply this constraint
+ recExt = recArr->At(irec)->GetName();
+ if (recExt == "-") {rangeStart = curID; continue;} // range is requested
+ else if (!recExt.IsDigit()) {stopped = kTRUE; break;}
+ else curID = recExt.Atoi();
+ //
+ if (curID<kSDDoffsID || curID>=kSDDoffsID+kNSDDmod) {stopped = kTRUE; break;}
+ //
+ // this was a range start or single
+ int start;
+ if (rangeStart>=0) {start = rangeStart+1; rangeStart=-1;} // continue the range
+ else start = curID; // create constraint either for single module (or 1st in the range)
+ for (int id=start;id<=curID;id++) {
+ int vid = AliITSAlignMille2Module::GetVolumeIDFromIndex(id);
+ if (vid<=1) {AliDebug(3,Form("Undefined module index %d requested in the SAME_SDDT0 constraint, skipping",id)); continue;}
+ AliITSAlignMille2Module *md = GetMilleModuleByVID(vid);
+ if (!md) {AliDebug(3,Form("Undefined module %d requested in the Local constraint, skipping",id)); continue;}
+ cstrT0->AddModule(md,kFALSE);
+ naddM++;
+ }
+ }
+ if (rangeStart>=0) stopped = kTRUE; // unfinished range
+ if (stopped) break;
+ if (naddM<2) delete cstrT0;
+ else {
+ cstrT0->SetConstraintID(GetNConstraints());
+ fConstraints.Add(cstrT0);
+ }
}
+ //
// Do we use new local Y errors?
else if (recTitle == fgkRecKeys[ kUseLocalYErr ]) {
// expect SET_TPAFITTER
SetMinPointsPerSensor( recOpt.Atoi() );
}
//
+ else if (recTitle == fgkRecKeys[ kOCDBSpecificPath ]) { //-------------------------
+ if (recOpt.IsNull() || nrecElems<3 ) {stopped = kTRUE; break;}
+ AliCDBManager::Instance()->SetSpecificStorage(recOpt.Data(), gSystem->ExpandPathName(recArr->At(2)->GetName()));
+ AliInfo(Form("Configuration sets OCDB specific storage %s to %s",recOpt.Data(),recArr->At(2)->GetName()));
+ TObjString *pths = (TObjString*)AliCDBManager::Instance()->GetStorageMap()->GetValue(recOpt.Data());
+ if (!pths) { stopped = kTRUE; break; }
+ pths->SetUniqueID(1); // mark as set by user
+ }
+ //
+ else if (recTitle == fgkRecKeys[ kCorrectDiamond ] && fUseDiamond) { //-------------------------
+ if (nrecElems<4) {stopped = kTRUE; break;}
+ for (int i=0;i<3;i++) fCorrDiamond[i] = ((TObjString*)recArr->At(i+1))->GetString().Atof();
+ AliInfo(Form("Correction %+.4f %+.4f %+.4f will be applied to diamond",fCorrDiamond[0],fCorrDiamond[1],fCorrDiamond[2]));
+ }
+ //
else continue; // already processed record
//
} // end of while loop 4 over the various params
} // end of while(1) loop
//
fclose(pfc);
+ if (!fDiamondPath.IsNull() && IsDiamondUsed() && LoadDiamond(fDiamondPath) ) stopped = kTRUE;
if (stopped) {
AliError(Form("Failed on record %s %s ...\n",recTitle.Data(),recOpt.Data()));
return -1;
//
if (CacheMatricesCurr()) return -1;
SetUseLocalYErrors(fUseLocalYErr); // YErr used only with TPAFitter
+ fSegmentationSDD = new AliITSsegmentationSDD();
+ //
fIsConfigured = kTRUE;
return 0;
}
}
// endpepo
//________________________________________________________________________________________________________
-void AliITSAlignMille2::SetRequiredPoint(Char_t* where, Int_t ndet, Int_t updw, Int_t nreqpts)
+void AliITSAlignMille2::SetRequiredPoint(Char_t* where, Int_t ndet, Int_t updw, Int_t nreqpts,Int_t runtype)
{
// set minimum number of points in specific detector or layer
// where = LAYER or DETECTOR
// updw = 1 for Y>0, -1 for Y<0, 0 if not specified
// nreqpts = minimum number of points of that type
ndet--;
- if (strstr(where,"LAYER")) {
- if (ndet<0 || ndet>5) return;
- if (updw>0) fNReqLayUp[ndet]=nreqpts;
- else if (updw<0) fNReqLayDown[ndet]=nreqpts;
- else fNReqLay[ndet]=nreqpts;
- fRequirePoints=kTRUE;
- }
- else if (strstr(where,"DETECTOR")) {
- if (ndet<0 || ndet>2) return;
- if (updw>0) fNReqDetUp[ndet]=nreqpts;
- else if (updw<0) fNReqDetDown[ndet]=nreqpts;
- else fNReqDet[ndet]=nreqpts;
- fRequirePoints=kTRUE;
+ int tpmn= runtype<0 ? 0 : runtype;
+ int tpmx= runtype<0 ? kNDataType-1 : runtype;
+ //
+ for (int itp=tpmn;itp<=tpmx;itp++) {
+ fRequirePoints[itp]=kTRUE;
+ if (strstr(where,"LAYER")) {
+ if (ndet<0 || ndet>5) return;
+ if (updw>0) fNReqLayUp[itp][ndet]=nreqpts;
+ else if (updw<0) fNReqLayDown[itp][ndet]=nreqpts;
+ else fNReqLay[itp][ndet]=nreqpts;
+ }
+ else if (strstr(where,"DETECTOR")) {
+ if (ndet<0 || ndet>2) return;
+ if (updw>0) fNReqDetUp[itp][ndet]=nreqpts;
+ else if (updw<0) fNReqDetDown[itp][ndet]=nreqpts;
+ else fNReqDet[itp][ndet]=nreqpts;
+ }
}
}
}
//________________________________________________________________________________________________________
-Int_t AliITSAlignMille2::InitGeometry()
+Int_t AliITSAlignMille2::LoadGeometry(TString& path)
{
- /// initialize geometry
- AliInfo("Loading initial geometry");
- if (!fGeometryPath.IsNull() && gSystem->AccessPathName(fGeometryPath.Data()) ) {
- AliError(Form("Explicitly provided geometry file %s is not accessible",fGeometryPath.Data()));
+ // initialize ideal geometry
+ AliInfo(Form("Loading ideal geometry %s",path.Data()));
+ if (path.IsNull()) {
+ AliError("Path to geometry is not provided");
return -1;
}
//
- AliGeomManager::LoadGeometry(fGeometryPath.Data());
+ AliCDBEntry *entry = 0;
+ TGeoManager *gm = 0;
+ while(1) {
+ if (path.BeginsWith("path: ")) { // must load from OCDB
+ entry = GetCDBEntry(path.Data());
+ if (!entry) break;
+ gm = (TGeoManager*) entry->GetObject();
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
+ break;
+ }
+ //
+ if (gSystem->AccessPathName(path.Data())) break;
+ TFile* precf = TFile::Open(path.Data());
+ if (precf->FindKey("ALICE")) gm = (TGeoManager*)precf->Get("ALICE");
+ else if (precf->FindKey("AliCDBEntry") && (entry=(AliCDBEntry*)precf->Get("AliCDBEntry"))) {
+ gm = (TGeoManager*) entry->GetObject();
+ if (gm && gm->InheritsFrom(TGeoManager::Class())) entry->SetObject(NULL);
+ else gm = 0;
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ delete entry;
+ }
+ precf->Close();
+ delete precf;
+ break;
+ }
+ //
+ if (!gm) {AliError(Form("Failed to load geometry from %s",path.Data())); return -1;}
+ AliGeomManager::SetGeometry(gm);
fGeoManager = AliGeomManager::GetGeometry();
if (!fGeoManager) {
AliInfo("Couldn't initialize geometry");
//
// we need to reload the geometry spoiled by this reference deltas...
delete fGeoManager;
- AliInfo("Reloading initial geometry");
- return InitGeometry();
+ AliInfo("Reloading target ideal geometry");
+ return LoadGeometry(fGeometryPath);
//
}
// init millepede, decide which parameters are to be fitted explicitly
for (int imd=fNModules;imd--;) {
AliITSAlignMille2Module* mod = GetMilleModule(imd);
+ if (mod->IsNotInConf()) continue; // dummy module
int npar = mod->GetNParTot();
// the parameter may have max 1 free instance, otherwise the equations are underdefined
for (int ipar=0;ipar<npar;ipar++) {
// 2) the same applies to all of its parents
// 3) it has at least 1 unconstrained direct child
while(parent) {
+ if (parent->IsNotInConf()) {parent = parent->GetParent(); continue;}
if (!parent->IsFreeDOF(ipar)) {parent = parent->GetParent(); continue;}
nFreeInstances++;
if (IsParModConstrained(parent,ipar, cstMeanMed, cstGauss)) nFreeInstances--;
}
}
//
+ ResetCovIScale();
// Set iterations
if (fStartFac>1) fMillepede->SetIterations(fStartFac);
+ if (fFinalFac>1) fMillepede->SetChi2CutRef(fFinalFac);
+ fTrackBuff.Expand(24);
//
}
{
/// create a new AliTrackPointArray keeping only defined modules
/// move points according to a given prealignment, if any
- /// sort alitrackpoints w.r.t. global Y direction, if selected
+ /// sort alitrackpoints w.r.t. global Y direction, if cosmics
const Double_t kRad2L[6] = {5*5,10*10,18*18,30*30,40*40,60*60};
const Float_t kSensSigY2[6] = {200e-4*200e-4/12, 200e-4*200e-4/12,
300e-4*300e-4/12, 300e-4*300e-4/12,
300e-4*300e-4/12, 300e-4*300e-4/12}; // thickness^2/12
//
fTrack = NULL;
- Int_t idx[20];
- Short_t lrID[20];
+ Int_t idx[20] = {0};
+ Short_t lrID[20] = {0};
Int_t npts=atp->GetNPoints();
+ if (npts<fMinNPtsPerTrack) return NULL;
TGeoHMatrix hcov;
//
/// checks if AliTrackPoints belong to defined modules
Int_t ngoodpts=0;
Int_t intidx[20];
for (int j=0; j<npts; j++) {
- intidx[j] = IsVIDContained(atp->GetVolumeID()[j]);
+ intidx[j] = GetRequestedModID(atp->GetVolumeID()[j]);
if (intidx[j]<0) continue;
ngoodpts++;
Float_t xx=atp->GetX()[j];
// reject track if not enough points are left
if (ngoodpts<fMinNPtsPerTrack) {
- AliInfo("Track with not enough points!");
+ AliDebug(2,"Track with not enough points!");
return NULL;
}
// >> RS
AliTrackPoint p;
// check points in specific places
- if (fRequirePoints) {
+ if (fRequirePoints[fDataType]) {
Int_t nlayup[6],nlaydown[6],nlay[6];
Int_t ndetup[3],ndetdown[3],ndet[3];
for (Int_t j=0; j<6; j++) {nlayup[j]=0; nlaydown[j]=0; nlay[j]=0;}
// checks minimum values
Bool_t isok=kTRUE;
for (Int_t j=0; j<6; j++) {
- if (nlayup[j]<fNReqLayUp[j]) isok=kFALSE;
- if (nlaydown[j]<fNReqLayDown[j]) isok=kFALSE;
- if (nlay[j]<fNReqLay[j]) isok=kFALSE;
+ if (nlayup[j]<fNReqLayUp[fDataType][j]) isok=kFALSE;
+ if (nlaydown[j]<fNReqLayDown[fDataType][j]) isok=kFALSE;
+ if (nlay[j]<fNReqLay[fDataType][j]) isok=kFALSE;
}
for (Int_t j=0; j<3; j++) {
- if (ndetup[j]<fNReqDetUp[j]) isok=kFALSE;
- if (ndetdown[j]<fNReqDetDown[j]) isok=kFALSE;
- if (ndet[j]<fNReqDet[j]) isok=kFALSE;
+ if (ndetup[j]<fNReqDetUp[fDataType][j]) isok=kFALSE;
+ if (ndetdown[j]<fNReqDetDown[fDataType][j]) isok=kFALSE;
+ if (ndet[j]<fNReqDet[fDataType][j]) isok=kFALSE;
}
if (!isok) {
AliDebug(2,Form("Track does not meet all location point requirements!"));
// build a new track with (sorted) (prealigned) good points
// pepo200709
//fTrack = (AliTrackPointArray*)fTrackBuff[ngoodpts-fMinNPtsPerTrack];
- fTrack = (AliTrackPointArray*)fTrackBuff[ngoodpts];
+ Int_t addVertex = IsTypeCollision()&&((fUseDiamond&&(fCheckDiamondPoint!=kDiamondIgnore))||(fUseVertex&&fVertexSet)) ? 1 : 0;
+ fTrack = (AliTrackPointArray*)fTrackBuff[ngoodpts + addVertex ];
if (!fTrack) {
- fTrack = new AliTrackPointArray(ngoodpts);
+ fTrack = new AliTrackPointArray(ngoodpts + addVertex);
// fTrackBuff.AddAtAndExpand(fTrack,ngoodpts-fMinNPtsPerTrack);
- fTrackBuff.AddAtAndExpand(fTrack,ngoodpts);
+ fTrackBuff.AddAtAndExpand(fTrack,ngoodpts + addVertex);
}
// fTrack = new AliTrackPointArray(ngoodpts);
// endpepo200709
//
for (int i=0; i<npts; i++) idx[i]=i;
// sort track if required
- TMath::Sort(npts,atp->GetY(),idx); // sort descending...
+ if (IsTypeCosmics()) TMath::Sort(npts,atp->GetY(),idx); // sort descending...
//
Int_t npto=0;
if (fClusLoc.GetSize()<3*npts) fClusLoc.Set(3*npts);
AliITSAlignMille2Module *mod = GetMilleModule(intidx[idx[i]]);
TGeoHMatrix *svOrigMatrix = GetSensorOrigMatrixSID(sid); //mod->GetSensitiveVolumeOrigGlobalMatrix(p.GetVolumeID());
// get back real local coordinate
- Double_t *pl = fClusLoc.GetArray() + npto*3;
- Double_t *pg = fClusGlo.GetArray() + npto*3;
- Double_t *sgl = fClusSigLoc.GetArray() + npto*3;
- pg[0]=p.GetX();
- pg[1]=p.GetY();
- pg[2]=p.GetZ();
- AliDebug(3,Form("Global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]));
- svOrigMatrix->MasterToLocal(pg,pl);
- AliDebug(3,Form("Local coordinates of measured point : X=%f Y=%f Z=%f \n",pl[0],pl[1],pl[2]));
- //
- // this is a temporary code to extract the drift speed used for given point
- if (p.GetDriftTime()>0) { // RRR
- // calculate the drift speed
- fDriftTime0[npto] = fInitialRecSDD ? fInitialRecSDD->GetTimeZero(sid) : 0.;
- double tdif = p.GetDriftTime() - fDriftTime0[npto];
- if (tdif<=0) tdif = 1;
- double vdrift = (3.5085-TMath::Abs(pl[0]))/tdif;
- if (vdrift<0) vdrift = 0;
- //
- // TEMPORARY CORRECTION (if provided) -------------->>>
- if (fCorrectSDD) {
- float t0Upd = fCorrectSDD->GetTimeZero(sid);
- vdrift += fCorrectSDD->GetDeltaVDrift(sid);
- tdif = p.GetDriftTime() - t0Upd;
- // correct Xlocal
- pl[0] = TMath::Sign(3.5085 - vdrift*tdif,pl[0]);
- fDriftTime0[npto] = t0Upd;
- }
- // TEMPORARY CORRECTION (if provided) --------------<<<
- fDriftSpeed[npto] = TMath::Sign(vdrift,pl[0]);
- //
- }
+ fMeasLoc = fClusLoc.GetArray() + npto*3;
+ fMeasGlo = fClusGlo.GetArray() + npto*3;
+ fSigmaLoc = fClusSigLoc.GetArray() + npto*3;
+ fMeasGlo[0]=p.GetX();
+ fMeasGlo[1]=p.GetY();
+ fMeasGlo[2]=p.GetZ();
+ AliDebug(3,Form("Global coordinates of measured point : X=%+f Y=%+f Z=%+f \n",fMeasGlo[0],fMeasGlo[1],fMeasGlo[2]));
+ svOrigMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
+ AliDebug(3,Form("Local coordinates of measured point : X=%+f Y=%+f Z=%+f \n",fMeasLoc[0],fMeasLoc[1],fMeasLoc[2]));
+ //
+ if (p.GetDriftTime()>0) ProcessSDDPointInfo(&p,sid, npto); // for SDD points extract vdrift
+ //
// update covariance matrix
Double_t hcovel[9];
hcovel[0]=double(p.GetCov()[0]);
// now hcov is LOCAL COVARIANCE MATRIX
// apply sigma scaling
Double_t *hcovscl = hcov.GetRotationMatrix();
+ /*
+ const float *cv = p.GetCov();
+ printf("## %d %d %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e %+.3e\n",
+ sid,p.GetClusterType(),
+ fMeasGlo[0],fMeasGlo[1],fMeasGlo[2],
+ fMeasLoc[0],fMeasLoc[1],fMeasLoc[2],
+ cv[0],cv[1],cv[2],cv[3],cv[4],cv[5],
+ hcovscl[0],hcovscl[4],hcovscl[8]);
+
+ */
if (AliLog::GetGlobalDebugLevel()>=2) {
AliInfo("Original Local Cov Matrix");
printf("%+.4e %+.4e %+.4e\n%+.4e %+.4e\n%+.4e\n",hcovscl[0],hcovscl[1],hcovscl[2],hcovscl[4],hcovscl[5],hcovscl[8]);
if (ir==ic) {
if ( IsZero(hcovscl[ir*3+ic],1e-8) ) hcovscl[ir*3+ic] = 1E-8;
else hcovscl[ir*3+ic] *= mod->GetSigmaFactor(ir)*mod->GetSigmaFactor(ic); //RRR
- sgl[ir] = TMath::Sqrt(hcovscl[ir*3+ic]);
+ fSigmaLoc[ir] = TMath::Sqrt(hcovscl[ir*3+ic]);
}
else hcovscl[ir*3+ic] = 0;
}
/// get (evenctually prealigned) matrix of sens. vol.
TGeoHMatrix *svMatrix = GetSensorCurrMatrixSID(sid); //mod->GetSensitiveVolumeMatrix(p.GetVolumeID());
// modify global coordinates according with pre-aligment
- svMatrix->LocalToMaster(pl,pg);
+ svMatrix->LocalToMaster(fMeasLoc,fMeasGlo);
// now rotate in local system
hcov.Multiply(&svMatrix->Inverse());
hcov.MultiplyLeft(svMatrix); // hcov is back in GLOBAL RF
pcov[3]=hcovscl[4];
pcov[4]=hcovscl[5];
pcov[5]=hcovscl[8];
+ //
+ // make sure the matrix is positive definite
+ {
+ enum {kXX=0,kXY=1,kXZ=2,kYX=kXY,kYY=3,kYZ=4,kZX=kXZ,kZY=kYZ,kZZ=5};
+ if (pcov[kXX]*pcov[kYY]*0.999<pcov[kXY]*pcov[kXY]) pcov[kXY] = 0.999*TMath::Sign((float)TMath::Sqrt(pcov[kXX]*pcov[kYY]),pcov[kXY]);
+ if (pcov[kXX]*pcov[kZZ]*0.999<pcov[kXZ]*pcov[kXZ]) pcov[kXZ] = 0.999*TMath::Sign((float)TMath::Sqrt(pcov[kXX]*pcov[kZZ]),pcov[kXZ]);
+ if (pcov[kYY]*pcov[kZZ]*0.999<pcov[kYZ]*pcov[kYZ]) pcov[kYZ] = 0.999*TMath::Sign((float)TMath::Sqrt(pcov[kYY]*pcov[kZZ]),pcov[kYZ]);
+ }
//
- p.SetXYZ(pg[0],pg[1],pg[2],pcov);
- // printf("New Gl coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]);
- AliDebug(3,Form("New global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]));
+ p.SetXYZ(fMeasGlo[0],fMeasGlo[1],fMeasGlo[2],pcov);
+ // printf("New Gl coordinates of measured point : X=%f Y=%f Z=%f \n",fMeasGlo[0],fMeasGlo[1],fMeasGlo[2]);
+ AliDebug(3,Form("New global coordinates of measured point : X=%+f Y=%+f Z=%+f \n",fMeasGlo[0],fMeasGlo[1],fMeasGlo[2]));
fTrack->AddPoint(npto,&p);
- AliDebug(2,Form("Adding point[%d] = ( %f , %f , %f ) volid = %d",npto,fTrack->GetX()[npto],
+ AliDebug(2,Form("Adding point[%d] = ( %+f , %+f , %+f ) volid = %d",npto,fTrack->GetX()[npto],
fTrack->GetY()[npto],fTrack->GetZ()[npto],fTrack->GetVolumeID()[npto] ));
// printf("Adding %d %d %f\n",npto, p.GetVolumeID(), p.GetY());
npto++;
}
//
+ fDiamondPointID = -1;
+ if (addVertex) {
+ fTrack->AddPoint(npto,&fDiamond);
+ fMeasLoc = fClusLoc.GetArray() + npto*3;
+ fMeasGlo = fClusGlo.GetArray() + npto*3;
+ fSigmaLoc = fClusSigLoc.GetArray() + npto*3;
+ fMeasLoc[0] = fMeasGlo[0] = fDiamond.GetX();
+ fMeasLoc[1] = fMeasGlo[1] = fDiamond.GetY();
+ fMeasLoc[2] = fMeasGlo[2] = fDiamond.GetZ();
+ fSigmaLoc[0] = TMath::Sqrt(fDiamond.GetCov()[0]);
+ fSigmaLoc[1] = TMath::Sqrt(fDiamond.GetCov()[3]);
+ fSigmaLoc[2] = TMath::Sqrt(fDiamond.GetCov()[5]);
+ fDiamondPointID = npto++;
+ }
+ //
return fTrack;
}
for (int i=0; i<npts; i++) {
atp->GetPoint(p,idx[i]);
atps->AddPoint(i,&p);
- AliDebug(2,Form("Point[%d] = ( %f , %f , %f ) volid = %d",i,atps->GetX()[i],atps->GetY()[i],atps->GetZ()[i],atps->GetVolumeID()[i] ));
+ AliDebug(2,Form("Point[%d] = ( %+f , %+f , %+f ) volid = %d",i,atps->GetX()[i],atps->GetY()[i],atps->GetZ()[i],atps->GetVolumeID()[i] ));
}
return atps;
}
UShort_t voluid=fCluster.GetVolumeID();
fCurrentSensID = AliITSAlignMille2Module::GetIndexFromVolumeID(voluid);
//
- // IT IS VERY IMPORTANT: start from the end of the list, where the childs are located !!!
- Int_t k=fNModules-1;
- fCurrentModule = 0;
- // VERY IMPORTANT: if the sensors were explicitly provided, don't look in the supermodules
- while (k>=0 && ! (fCurrentModule=GetMilleModule(k))->IsIn(voluid)) k--;
- if (k<0) return -3;
+ if (fCurrentSensID==-1) { // this is a special "vertex" module
+ fCurrentModule = GetMilleModuleByVID(voluid);
+ fCurrentSensID = fCurrentModule->GetIndex();
+
+ }
+ else {
+ //
+ // IT IS VERY IMPORTANT: start from the end of the list, where the childs are located !!!
+ Int_t k=fNModules-1;
+ fCurrentModule = 0;
+ // VERY IMPORTANT: if the sensors were explicitly provided, don't look in the supermodules
+ while (k>=0 && ! (fCurrentModule=GetMilleModule(k))->IsIn(voluid)) k--;
+ if (k<0) return -3;
+ }
//
for (int i=AliITSAlignMille2Module::kMaxParTot;i--;) fModuleInitParam[i] = 0.0;
//
// set minimum value for SigmaLoc to 10 micron
if (fSigmaLoc[0]<0.0010) fSigmaLoc[0]=0.0010;
if (fSigmaLoc[2]<0.0010) fSigmaLoc[2]=0.0010;
+ if (fCurrentSensID==kVtxSensID || fUseLocalYErr) if (fSigmaLoc[1]<0.0010) fSigmaLoc[1]=0.0010;
//
- AliDebug(2,Form("Local coordinates of measured point : X=%f Y=%f Z=%f \n",fMeasLoc[0] ,fMeasLoc[1] ,fMeasLoc[2] ));
+ AliDebug(2,Form("Local coordinates of measured point : X=%+f Y=%+f Z=%+f \n",fMeasLoc[0] ,fMeasLoc[1] ,fMeasLoc[2] ));
AliDebug(2,Form("Setting StDev from CovMat : fSigmaLocX=%g fSigmaLocY=%g fSigmaLocZ=%g \n",fSigmaLoc[0] ,fSigmaLoc[1] ,fSigmaLoc[2] ));
//
return 0;
//
//
if (fBOn)
- printf(" B Field set to %f T - using helices\n",fBField);
+ printf(" B Field set to %+f T - using helices\n",fBField);
else
printf(" B Field OFF - using straight lines \n");
//
//
printf("Using local Y error due to the sensor thickness: %s\n",(fUseLocalYErr && fTPAFitter) ? "ON":"OFF");
//
- if (fRequirePoints) printf(" Required points in tracks:\n");
- for (Int_t i=0; i<6; i++) {
- if (fNReqLayUp[i]>0) printf(" Layer %d : %d points with Y>0\n",i+1,fNReqLayUp[i]);
- if (fNReqLayDown[i]>0) printf(" Layer %d : %d points with Y<0\n",i+1,fNReqLayDown[i]);
- if (fNReqLay[i]>0) printf(" Layer %d : %d points \n",i+1,fNReqLay[i]);
- }
- for (Int_t i=0; i<3; i++) {
- if (fNReqDetUp[i]>0) printf(" Detector %d : %d points with Y>0\n",i+1,fNReqDetUp[i]);
- if (fNReqDetDown[i]>0) printf(" Detector %d : %d points with Y<0\n",i+1,fNReqDetDown[i]);
- if (fNReqDet[i]>0) printf(" Detector %d : %d points \n",i+1,fNReqDet[i]);
+ for (int itp=0;itp<kNDataType;itp++) {
+ if (fRequirePoints[itp]) printf(" Required points in %s tracks:\n",itp==kCosmics? "cosmics" : "collisions");
+ for (Int_t i=0; i<6; i++) {
+ if (fNReqLayUp[itp][i]>0) printf(" Layer %d : %d points with Y>0\n",i+1,fNReqLayUp[itp][i]);
+ if (fNReqLayDown[itp][i]>0) printf(" Layer %d : %d points with Y<0\n",i+1,fNReqLayDown[itp][i]);
+ if (fNReqLay[itp][i]>0) printf(" Layer %d : %d points \n",i+1,fNReqLay[itp][i]);
+ }
+ for (Int_t i=0; i<3; i++) {
+ if (fNReqDetUp[itp][i]>0) printf(" Detector %d : %d points with Y>0\n",i+1,fNReqDetUp[itp][i]);
+ if (fNReqDetDown[itp][i]>0) printf(" Detector %d : %d points with Y<0\n",i+1,fNReqDetDown[itp][i]);
+ if (fNReqDet[itp][i]>0) printf(" Detector %d : %d points \n",i+1,fNReqDet[itp][i]);
+ }
}
+ printf(" SDD VDrift correction : %s",fIsSDDVDriftMult ? "Mult":"Add");
+ printf(" Weight acc. to pT in power : %f",fWeightPt);
//
printf("\n Millepede configuration parameters:\n");
- printf(" init value for chi2 cut : %.4f\n",fStartFac);
+ printf(" init factor for chi2 cut : %.4f\n",fStartFac);
+ printf(" final factor for chi2 cut : %.4f\n",fFinalFac);
printf(" first iteration cut value : %.4f\n",fResCutInitial);
printf(" other iterations cut value : %.4f\n",fResCut);
printf(" number of stddev for chi2 cut : %d\n",fNStdDev);
static Bool_t fullErr2D;
//
if (flag==1) fullErr2D = kFALSE;//kTRUE;
- fullErr2D = kTRUE;
+ // fullErr2D = kTRUE;
enum {kAX,kAZ,kBX,kBZ};
enum {kXX=0,kXY=1,kXZ=2,kYX=kXY,kYY=3,kYZ=4,kZX=kXZ,kZY=kYZ,kZZ=5};
//
fLocalInitParam[4] = 0.0;
// endpepo200709
- AliDebug(2,Form("X = p0gx + ugx*Y : p0gx = %f ugx = %f\n",fLocalInitParam[0],fLocalInitParam[2]));
+ AliDebug(2,Form("X = p0gx + ugx*Y : p0gx = %+f ugx = %+f\n",fLocalInitParam[0],fLocalInitParam[2]));
//
if (meth==1) return;
//
return -1;
}
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::GetRequestedModID(UShort_t voluid) const
+{
+ // checks if the sensitive module 'voluid' is contained inside a supermodule
+ // and return the internal index of the last identified supermodule
+ // return -1 if error
+ // IMPORTANT: always start from the end to start from the sensors
+ if (AliITSAlignMille2Module::GetIndexFromVolumeID(voluid)<0) return -1;
+ int k;
+ for (k=fNModules;k--;) if (GetMilleModule(k)->IsIn(voluid)) break;
+ if (k<0) return -1;
+ AliITSAlignMille2Module* md = GetMilleModule(k);
+ while (md && md->IsNotInConf()) md = md->GetParent();
+ if (md) return int(md->GetUniqueID());
+ else return -1;
+}
+
//________________________________________________________________________________________________________
Int_t AliITSAlignMille2::CheckCurrentTrack()
{
}
//________________________________________________________________________________________________________
-Int_t AliITSAlignMille2::ProcessTrack(const AliTrackPointArray *track)
+Int_t AliITSAlignMille2::ProcessTrack(const AliTrackPointArray *track, Double_t wgh)
{
/// Process track; Loop over hits and set local equations
/// here 'track' is a AliTrackPointArray
/// return 0 if success;
-
+ //
if (!fIsMilleInit) Init();
//
Int_t npts = track->GetNPoints();
// preprocessing of the input track: keep only points in defined volumes,
// move points if prealignment is set, sort by Yglo if required
-
+ fTrackWeight = wgh;
fTrack=PrepareTrack(track);
- if (!fTrack) return -1;
-
+ if (!fTrack) {
+ RemoveHelixFitConstraint();
+ RemoveVertexConstraint();
+ return -1;
+ }
npts = fTrack->GetNPoints();
if (npts>kMaxPoints) {
AliError(Form("Compiled with kMaxPoints=%d, current track has %d points",kMaxPoints,npts));
}
AliDebug(2,Form("*** Processing prepared track with %d points ***",npts));
//
+ npts = FitTrack();
+ if (npts<0) return npts;
+ //
+ // printf("Params: "); for (int i=0;i<fNLocal;i++) printf("%+.2e ",fLocalInitParam[i]); printf("\n");//RRR
+ Int_t nloceq=0;
+ Int_t ngloeq=0;
+ static Mille2Data md[kMaxPoints];
+ //
+ for (Int_t ipt=0; ipt<npts; ipt++) {
+ fTrack->GetPoint(fCluster,ipt);
+ fCluster.SetUniqueID(ipt+1);
+ AliDebug(2,Form("\n--- processing point %d --- \n",ipt));
+
+ // set geometry parameters for the the current module
+ if (InitModuleParams()) continue;
+ AliDebug(2,Form(" VolID=%d Index=%d InternalIdx=%d symname=%s\n",
+ track->GetVolumeID()[ipt], fCurrentModule->GetIndex(),
+ fCurrentModule->GetUniqueID(), AliGeomManager::SymName(track->GetVolumeID()[ipt]) ));
+ AliDebug(2,Form(" Preprocessed Point = ( %+f , %+f , %+f ) \n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ()));
+ int res = fTPAFitter ? AddLocalEquationTPA(md[nloceq]) : AddLocalEquation(md[nloceq]);
+ if (res<0) {fTotBadLocEqPoints++; nloceq = 0; break;}
+ else if (res==0) nloceq++;
+ else {nloceq++; ngloeq++;}
+ } // end loop over points
+ //
+ fTrack=NULL;
+ // not enough good points?
+ if (nloceq<fMinNPtsPerTrack || ngloeq<1) return -1;
+ //
+ // finally send local equations to millepede
+ SetLocalEquations(md,nloceq);
+ fMillepede->SaveRecordData(); // RRR
+ fCurvFitWasConstrained = kFALSE; // restore default
+ //
+ return 0;
+}
+
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::FitTrack()
+{
+ // Fit the track with selected constraints
+ //
+ const Double_t kfDiamondTolerance = 0.1; //diamond tolerance on top of the MS error
+ if (!fTrack) return -1;
+ int npts = fTrack->GetNPoints();
+ //
if (fTPAFitter) { // use dediacted fitter
//
- fTPAFitter->AttachPoints(fTrack);
- if (fBOn) fTPAFitter->SetBz(fBField);
- if (fInitTrackParamsMeth==1) fTPAFitter->SetIgnoreCov();
- double chi2 = fTPAFitter->Fit(fConstrCharge,fConstrPT,fConstrPTErr);
+ // if the diamond point is attached, for the moment don't include it in the fit
+ fTPAFitter->AttachPoints(fTrack,0, npts-1);
+ fTPAFitter->SetBz(fBField);
+ fTPAFitter->SetTypeCosmics(IsTypeCosmics());
+ if (fIniTrackParamsMeth==1) fTPAFitter->SetIgnoreCov();
+ //
+ double chi2;
+ double chi2f = 0;
+ double dca2err;
+ double dca2 = 0.;
+ Bool_t fitIsDone = kFALSE;
+ if (fUseDiamond && fDiamondPointID>0 && fCheckDiamondPoint==kDiamondCheckIfPrompt) { // diamond constraint was added, check if the track looks like prompt
+ fTPAFitter->SetFirstLast(0,fDiamondPointID-1);
+ if (IsCovIScaleTouched()) for (int i=npts;i--;) fTPAFitter->SetCovIScale(i,GetCovIScale(i));
+ //
+ chi2f = fTPAFitter->Fit(fConstrCharge,fConstrPT,fConstrPTErr);
+ if ( chi2f<0 || (chi2f>fNStdDev*fStartFac && fTPAFitter->GetNIterations()>=fTPAFitter->GetMaxIterations()) ) { //RRR
+ AliInfo(Form("Track fit failed on checking if it is prompt! skipping this track... Chi2:%+e",chi2f));
+ fTPAFitter->Reset();
+ // fTrack = NULL;
+ return -5;
+ }
+ double xyzRes[3];
+ fTPAFitter->GetResiduals(xyzRes,&fDiamondI,kTRUE);
+ dca2 = xyzRes[0]*xyzRes[0] + xyzRes[1]*xyzRes[1];
+ double pT = IsFieldON() ? fTPAFitter->GetPt() : 0.45;
+ if (pT<0.1) pT = 0.1;
+ dca2err = kfDiamondTolerance + 0.02/pT;
+ if (dca2>dca2err*dca2err) { // this is secondary
+ int* clst = (int*) fTrack->GetClusterType();
+ clst[fDiamondPointID] = -1;;
+ fDiamondPointID = -1;
+ fitIsDone = kTRUE;
+ npts--;
+ }
+ else fTPAFitter->SetFirstLast(0,fDiamondPointID); // fit with diamond
+ }
+ // fTPAFitter->SetParAxis(1);
+ if (!fitIsDone) {
+ if (IsCovIScaleTouched()) for (int i=npts;i--;) fTPAFitter->SetCovIScale(i,GetCovIScale(i));
+ chi2 = fTPAFitter->Fit(fConstrCharge,fConstrPT,fConstrPTErr);
+ }
//
- // suppress eventual constraints to not affect fit of the next track
- fConstrCharge = 0;
- fConstrPT = fConstrPTErr = -1;
+ RemoveHelixFitConstraint(); // suppress eventual constraints to not affect fit of the next track
+ RemoveVertexConstraint(); // same ...
//
- if ( chi2<0 || (fTPAFitter->GetNIterations()>=fTPAFitter->GetMaxIterations()) ) {
- AliInfo("Track fit failed! skipping this track...");
+ if ( !fitIsDone && (chi2<0 || (chi2>fNStdDev*fStartFac && fTPAFitter->GetNIterations()>=fTPAFitter->GetMaxIterations())) ) { //RRR
+ AliInfo(Form("Track fit failed! skipping this track... Chi2:%+e",chi2));
+ if (fUseDiamond && fDiamondPointID>0 && fCheckDiamondPoint==kDiamondCheckIfPrompt) AliInfo(Form("VertexFree fit gave Chi2:%+e with residual %+e",chi2f,TMath::Sqrt(dca2)));
+ /*
+ fTrack->Print("");
+ fTPAFitter->FitHelixCrude();
+ fTPAFitter->SetFitDone();
+ fTPAFitter->Print();
+ */
fTPAFitter->Reset();
- fTrack = NULL;
+ // fTrack = NULL;
return -5;
}
+ fNLocal = fTPAFitter->IsFieldON() ? 5:4; // Attention: the fitter might have decided to work in line mode
+ npts = fTPAFitter->GetLast() - fTPAFitter->GetFirst() + 1; // actual number of points
/*
- double *pr = fTPAFitter->GetParams();
- printf("FtPar: %+.5e %+.5e %+.5e %+.5e | chi2:%.3e\n",pr[2],pr[0],pr[3],pr[1],chi2); // RRR
+ double *pr = fTPAFitter->GetParams();
+ printf("FtPar: %+.5e %+.5e %+.5e %+.5e | chi2:%.3e\n",pr[2],pr[0],pr[3],pr[1],chi2); // RRR
*/
}
else {
// [1] = global z coord. of straight line intersection at y=0 plane
// [2] = px/py
// [3] = pz/py
- InitTrackParams(fInitTrackParamsMeth);
+ InitTrackParams(fIniTrackParamsMeth);
/*
double *pr = fLocalInitParam;
printf("FtPar: %+.5e %+.5e %+.5e %+.5e |\n",pr[0],pr[1],pr[2],pr[3]); // RRR
}
}
}
+ return npts;
//
- // printf("Params: "); for (int i=0;i<fNLocal;i++) printf("%+.2e ",fLocalInitParam[i]); printf("\n");//RRR
- Int_t nloceq=0;
- Int_t ngloeq=0;
- static Mille2Data md[kMaxPoints];
- //
- for (Int_t ipt=0; ipt<npts; ipt++) {
- fTrack->GetPoint(fCluster,ipt);
- fCluster.SetUniqueID(ipt+1);
- AliDebug(2,Form("\n--- processing point %d --- \n",ipt));
-
- // set geometry parameters for the the current module
- if (InitModuleParams()) continue;
- AliDebug(2,Form(" VolID=%d Index=%d InternalIdx=%d symname=%s\n",
- track->GetVolumeID()[ipt], fCurrentModule->GetIndex(),
- fCurrentModule->GetUniqueID(), AliGeomManager::SymName(track->GetVolumeID()[ipt]) ));
- AliDebug(2,Form(" Preprocessed Point = ( %f , %f , %f ) \n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ()));
- int res = fTPAFitter ? AddLocalEquationTPA(md[nloceq]) : AddLocalEquation(md[nloceq]);
- if (res<0) {fTotBadLocEqPoints++; nloceq = 0; break;}
- else if (res>0) {nloceq++; ngloeq++;}
- } // end loop over points
- //
- fTrack=NULL;
- // not enough good points?
- if (nloceq<fMinNPtsPerTrack || ngloeq<1) return -1;
- //
- // finally send local equations to millepede
- SetLocalEquations(md,nloceq);
- fMillepede->SaveRecordData(); // RRR
- //
- return 0;
}
//________________________________________________________________________________________________________
-Int_t AliITSAlignMille2::CalcIntersectionPoint(Double_t *lpar, Double_t *gpar)
+Int_t AliITSAlignMille2::CalcIntersectionPoint(const Double_t *lpar, const Double_t *gpar)
{
/// calculate track intersection point in local coordinates
/// according with a given set of parameters (local(4) and global(6))
Double_t y2g = x2t*TMath::Sin(alpha) + y2t*TMath::Cos(alpha);
Double_t z2g = z2t;
- AliDebug(3,Form("Riemann frame: fAlpha = %f = %f ",alpha,alpha*180./TMath::Pi()));
- AliDebug(3,Form(" prf_glo=( %f , %f , %f ) prf_rf=( %f , %f , %f )\n", x1g,y1g,z1g, x1t,y1t,z1t));
- AliDebug(3,Form(" mov_glo=( %f , %f , %f ) rf=( %f , %f , %f )\n",x2g,y2g,z2g, x2t,y2t,z2t));
+ AliDebug(3,Form("Riemann frame: fAlpha = %+f = %+f ",alpha,alpha*180./TMath::Pi()));
+ AliDebug(3,Form(" prf_glo=( %+f , %+f , %+f ) prf_rf=( %+f , %+f , %+f )\n", x1g,y1g,z1g, x1t,y1t,z1t));
+ AliDebug(3,Form(" mov_glo=( %+f , %+f , %+f ) rf=( %+f , %+f , %+f )\n",x2g,y2g,z2g, x2t,y2t,z2t));
if (TMath::Abs(y2g-y1g)<1e-15) {
AliInfo("DeltaY=0! Cannot proceed...");
p0g[1]=0.0;
p0g[2]=lpar[1];
}
- AliDebug(3,Form("Line vector: ( %f , %f , %f ) point:( %f , %f , %f )\n",v0g[0],v0g[1],v0g[2],p0g[0],p0g[1],p0g[2]));
+ AliDebug(3,Form("Line vector: ( %+f , %+f , %+f ) point:( %+f , %+f , %+f )\n",v0g[0],v0g[1],v0g[2],p0g[0],p0g[1],p0g[2]));
// same in local coord.
Double_t p0l[3],v0l[3];
// global intersection point
tempHMat->LocalToMaster(fPintLoc,fPintGlo);
- AliDebug(3,Form("Intesect. point: L( %f , %f , %f ) G( %f , %f , %f )\n",fPintLoc[0],fPintLoc[1],fPintLoc[2],fPintGlo[0],fPintGlo[1],fPintGlo[2]));
+ AliDebug(3,Form("Intesect. point: L( %+f , %+f , %+f ) G( %+f , %+f , %+f )\n",fPintLoc[0],fPintLoc[1],fPintLoc[2],fPintGlo[0],fPintGlo[1],fPintGlo[2]));
return 0;
}
if (CalcIntersectionPoint(fLocalInitParam, fModuleInitParam)) return -1;
for (Int_t i=0; i<3; i++) fPintLoc0[i]=fPintLoc[i];
- AliDebug(2,Form("Intersect. point: L( %f , %f , %f )",fPintLoc[0],fPintLoc[1],fPintLoc[2]));
+ AliDebug(2,Form("Intersect. point: L( %+f , %+f , %+f )",fPintLoc[0],fPintLoc[1],fPintLoc[2]));
// calculate local derivatives numerically
Bool_t zeroX = kTRUE;
if (zeroX) {AliInfo("Skipping: zero local X derivatives!"); return -1;}
if (zeroZ) {AliInfo("Skipping: zero local Z derivatives!"); return -1;}
//
+ int status = 0;
int ifill = 0;
//
AliITSAlignMille2Module* endModule = fCurrentModule;
}
//
// specific for special sensors
+ Int_t sddLR = -1;
if ( fCurrentModule->IsSDD() &&
- (fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFT0)>=0 ||
- fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFDV)>=0) ) {
+ (fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFT0)>=0 ||
+ // fCurrentModule->GetParOffset(sddLR = fMeasLoc[kX]>0 ?
+ fCurrentModule->GetParOffset(sddLR = GetVDriftSDD()>0 ?
+ AliITSAlignMille2Module::kDOFDVL : AliITSAlignMille2Module::kDOFDVR)>=0)
+ ) {
//
// assume for sensor local xloc = xloc0 + V0*dT0+dV*(T-T0)
// where V0 and T are the nominal drift velocity, time and time0
// dX/dV = dX/dxloc * dxloc/dV = dX/dxloc * (T-T0)
// IMPORTANT: the geom derivatives are over the SENSOR LOCAL parameters
//
- if (!dfDone[AliITSAlignMille2Module::kDOFT0] || !dfDone[AliITSAlignMille2Module::kDOFDV]) {
+ if (!dfDone[AliITSAlignMille2Module::kDOFT0] || !dfDone[sddLR]) {
//
double dXdxlocsens=0., dZdxlocsens=0.;
//
fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][2] = dZdxlocsens*vdrift;
dfDone[AliITSAlignMille2Module::kDOFT0] = kTRUE;
//
- fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][0] = -dXdxlocsens*TMath::Sign(tdrift,vdrift);
- fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][2] = -dZdxlocsens*TMath::Sign(tdrift,vdrift);
- dfDone[AliITSAlignMille2Module::kDOFDV] = kTRUE;
+ double mltCorr = fIsSDDVDriftMult ? TMath::Abs(vdrift) : 1;
+ fDerivativeGlo[sddLR][0] = -dXdxlocsens*mltCorr*TMath::Sign(tdrift,vdrift);
+ fDerivativeGlo[sddLR][2] = -dZdxlocsens*mltCorr*TMath::Sign(tdrift,vdrift);
+ dfDone[sddLR] = kTRUE;
//
}
//
m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFT0);
}
//
- if (fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFDV)>=0) {
- m.fDerGlo[ifill][kX] = fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][0];
- m.fDerGlo[ifill][kZ] = fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][2];
- m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFDV);
+ if (fCurrentModule->GetParOffset(sddLR)>=0) {
+ m.fDerGlo[ifill][kX] = fDerivativeGlo[sddLR][0];
+ m.fDerGlo[ifill][kZ] = fDerivativeGlo[sddLR][2];
+ m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(sddLR);
}
}
//
m.fNGlobFilled = ifill;
fCurrentModule = endModule;
//
- return Int_t(!zeroX && !zeroZ);
+ status += Int_t(!zeroX && !zeroZ); // 0 - only locals, 1 locals + globals
+ return status;
}
//________________________________________________________________________________________________________
/// 0 if no free global parameters were found but local eq is built
/// 1 if both local and global eqs are built
//
+ static int cnt = 0;
+ Bool_t dbg = kFALSE;//kTRUE;
+ if (++cnt>100000) dbg = kFALSE;
+
int curpoint = fCluster.GetUniqueID()-1;
TGeoHMatrix *tempHMat = GetSensorCurrMatrixSID(fCurrentSensID);// fCurrentModule->GetSensitiveVolumeMatrix(fCluster.GetVolumeID());
//
fTPAFitter->GetDResDParams(&fDerivativeLoc[0][0], curpoint); // resid. derivatives over the track parameters
+ if (fCurvFitWasConstrained && fFixCurvIfConstraned && !IsZero(fBField))
+ for (int i=3;i--;) fDerivativeLoc[AliITSTPArrayFit::kR0][i] = 0; //Fix curvarute
+ //
for (Int_t i=fNLocal; i--;) tempHMat->MasterToLocalVect(fDerivativeLoc[i],m.fDerLoc[i]);
//
+ int status = 0;
// derivatives over the global parameters ---------------------------------------->>>
+ Double_t dGL[3]; // derivative of global position vs local X (for SDD)
Double_t dRdP[3][3]; // derivative of local residuals vs local position
Double_t dPdG[AliITSAlignMille2Module::kMaxParGeom][3]; // derivatives of local position vs global params
fTPAFitter->GetDResDPos(&fDerivativeGlo[0][0], curpoint);
- for (int i=3;i--;) tempHMat->MasterToLocalVect(fDerivativeGlo[i],dRdP[i]);
- //
+ if (fCurrentSensID!=kVtxSensID) for (int i=3;i--;) tempHMat->MasterToLocalVect(fDerivativeGlo[i],dRdP[i]);
+ else for (int i=3;i--;) for (int j=3;j--;) dRdP[i][j] = fDerivativeGlo[i][j]; // vertex constraint is in lab
+ //
+ if (dbg) {
+ printf("\nCurrentMod: %s Sens:%d\n",fCurrentModule->GetName(),fCurrentSensID); //RRR
+ printf("Module Matrix: ");
+ fCurrentModule->GetMatrix()->Print(); //RRR
+ for (int i=0;i<3;i++) {
+ printf("dRdP[M%d][resI] ",i); for (int j=0;j<3;j++) printf(":[%d] %+.3e ",j,dRdP[i][j]); printf("\n");
+ }//RRR
+ printf("Sensor Matrix: "); tempHMat->Print();
+ }
UInt_t ifill=0, dfDone = 0;
m.fNModFilled = 0;
//
AliITSAlignMille2Module* endModule = fCurrentModule;
//
+ m.fModuleID[0] = fCurrentModule->GetUniqueID(); // always register id of the base module, even if it has no DOF
+ //
do {
if (fCurrentModule->GetNParFree()==0) continue;
+ status = 1;
if (!fUseGlobalDelta) dfDone = 0; // for local deltas the derivatives at diff. levels are different
Bool_t jacobOK = kFALSE;
//
if (fCurrentModule->GetParOffset(i)<0) continue; // this parameter is not explicitly fitted
//
if (!TestWordBit(dfDone,i)) { // need to calculate new derivative
- if (!jacobOK) {fCurrentModule->CalcDerivDPosDPar(fCluster.GetVolumeID(),fMeasLoc,&dPdG[0][0]); jacobOK = kTRUE;}
+ if (!jacobOK) {
+ if (fCurrentSensID!=kVtxSensID) {
+ fCurrentModule->CalcDerivDPosDPar(fCluster.GetVolumeID(),fMeasLoc,&dPdG[0][0]);
+ if (dbg) {
+ for (int i1=0;i1<3;i1++) {
+ printf("Jacob:dPdG[gpar%d][Mj]",i1); for (int j1=0;j1<3;j1++) printf(":[%d] %+.3e ",j1,dPdG[i1][j1]); printf("\n");//RRR
+ }
+ }
+ }
+ else {
+ // this is a vertex constraint: only lateral shifts are allowed, no rotations
+ for (int ip=AliITSAlignMille2Module::kMaxParGeom;ip--;) for (int jp=3;jp--;) dPdG[ip][jp] = (ip==jp) ? 1:0;
+ }
+ jacobOK = kTRUE;
+ }
// dRes_j/dGlo_i = \sum_{k=1:3} dRes_j/dPos_k * dPos_k/dGlo_i
fDerivativeGlo[i][kX] = dRdP[kX][kX]*dPdG[i][kX] + dRdP[kY][kX]*dPdG[i][kY] + dRdP[kZ][kX]*dPdG[i][kZ];
fDerivativeGlo[i][kY] = dRdP[kX][kY]*dPdG[i][kX] + dRdP[kY][kY]*dPdG[i][kY] + dRdP[kZ][kY]*dPdG[i][kZ];
SetWordBit(dfDone,i);
}
//
+ if (dbg) {
+ printf("Level %s DGlob[par%d][resJ] ",fCurrentModule->GetName(),i); //RRR
+ for (int k=0;k<3;k++) printf(":[%d] %+.3e ",k, fDerivativeGlo[i][k]); printf("\n");//RRR
+ }
m.fDerGlo[ifill][kX] = fDerivativeGlo[i][kX];
m.fDerGlo[ifill][kY] = fDerivativeGlo[i][kY];
m.fDerGlo[ifill][kZ] = fDerivativeGlo[i][kZ];
// assume for sensor local xloc = xloc0 + V0*dT0+dV*(T-T0)
// where V0 and T are the nominal drift velocity, time and time0
// and the dT0 and dV are the corrections:
- // dX/dT0 = dX/dxloc * dxloc/dT0 = dX/dxloc * V0
- // dX/dV = dX/dxloc * dxloc/dV = dX/dxloc * (T-T0)
+ // drloc_i/dT0 = sum_j drloc_i/dMeasGlo_j * dMeasGlo_j/dT0 =
+ // = sum_j drloc_i/dMeasGlo_j sum_k dMeasGlo_j/dMeasLoc_k * dMeasLoc_k/dT0
+ // = sum_j drloc_i/dMeasGlo_j dMeasGlo_j/dMeasLoc_X * V0
+ //
+ // drloc_i/dV0 = sum_j drloc_i/dMeasGlo_j * dMeasGlo_j/dV0 =
+ // = sum_j drloc_i/dMeasGlo_j sum_k dMeasGlo_j/dMeasLoc_k * dMeasLoc_k/dV0
+ // = sum_j drloc_i/dMeasGlo_j dMeasGlo_j/dMeasLoc_X * T0
+
// IMPORTANT: the geom derivatives are over the SENSOR LOCAL parameters
//
+ Bool_t jacOK = kFALSE;
+ //Int_t sddLR = fMeasLoc[kX]>0 ? AliITSAlignMille2Module::kDOFDVL : AliITSAlignMille2Module::kDOFDVR;
+ Int_t sddLR = GetVDriftSDD()>0 ? AliITSAlignMille2Module::kDOFDVL : AliITSAlignMille2Module::kDOFDVR;
if (fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFT0)>=0) {
if (!TestWordBit(dfDone, AliITSAlignMille2Module::kDOFT0)) {
double vdrift = GetVDriftSDD();
- fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kX] = -dRdP[kX][kX]*vdrift;
- fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kY] = -dRdP[kX][kY]*vdrift;
- fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kZ] = -dRdP[kX][kZ]*vdrift;
+ JacobianPosGloLoc(kX,dGL);
+ jacOK = kTRUE;
+ fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kX] =
+ vdrift*(dRdP[kX][kX]*dGL[kX] + dRdP[kY][kX]*dGL[kY] + dRdP[kZ][kX]*dGL[kZ]);
+ fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kY] =
+ vdrift*(dRdP[kX][kY]*dGL[kX] + dRdP[kY][kY]*dGL[kY] + dRdP[kZ][kY]*dGL[kZ]);
+ fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kZ] =
+ vdrift*(dRdP[kX][kZ]*dGL[kX] + dRdP[kY][kZ]*dGL[kY] + dRdP[kZ][kZ]*dGL[kZ]);
+ //
SetWordBit(dfDone, AliITSAlignMille2Module::kDOFT0);
}
m.fDerGlo[ifill][kX] = fDerivativeGlo[AliITSAlignMille2Module::kDOFT0][kX];
m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFT0);
}
//
- if (fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFDV)>=0) {
- if (!TestWordBit(dfDone, AliITSAlignMille2Module::kDOFDV)) {
+ if (fCurrentModule->GetParOffset(sddLR)>=0) {
+ if (!TestWordBit(dfDone, sddLR)) {
double tdrift = TMath::Sign(GetTDriftSDD(), GetVDriftSDD());
- fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kX] = dRdP[kX][kX]*tdrift;
- fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kY] = dRdP[kX][kY]*tdrift;
- fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kZ] = dRdP[kX][kZ]*tdrift;
- SetWordBit(dfDone, AliITSAlignMille2Module::kDOFDV);
+ double vdrift = fIsSDDVDriftMult ? TMath::Abs(GetVDriftSDD()) : 1;
+ if (!jacOK) JacobianPosGloLoc(kX,dGL);
+ fDerivativeGlo[sddLR][kX] =
+ -tdrift*vdrift*(dRdP[kX][kX]*dGL[kX] + dRdP[kY][kX]*dGL[kY] + dRdP[kZ][kX]*dGL[kZ]);
+ fDerivativeGlo[sddLR][kY] =
+ -tdrift*vdrift*(dRdP[kX][kY]*dGL[kX] + dRdP[kY][kY]*dGL[kY] + dRdP[kZ][kY]*dGL[kZ]);
+ fDerivativeGlo[sddLR][kZ] =
+ -tdrift*vdrift*(dRdP[kX][kZ]*dGL[kX] + dRdP[kY][kZ]*dGL[kY] + dRdP[kZ][kZ]*dGL[kZ]);
+ SetWordBit(dfDone, sddLR);
}
- m.fDerGlo[ifill][kX] = fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kX];
- m.fDerGlo[ifill][kY] = fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kY];
- m.fDerGlo[ifill][kZ] = fDerivativeGlo[AliITSAlignMille2Module::kDOFDV][kZ];
- m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(AliITSAlignMille2Module::kDOFDV);
+ m.fDerGlo[ifill][kX] = fDerivativeGlo[sddLR][kX];
+ m.fDerGlo[ifill][kY] = fDerivativeGlo[sddLR][kY];
+ m.fDerGlo[ifill][kZ] = fDerivativeGlo[sddLR][kZ];
+ m.fParMilleID[ifill++] = fCurrentModule->GetParOffset(sddLR);
}
}
//
// store first local residuals
fTPAFitter->GetResiduals(fPintLoc , curpoint); // lab residuals
for (int i=3;i--;) fPintLoc[i] = -fPintLoc[i];
- tempHMat->MasterToLocalVect(fPintLoc,m.fMeas); // local residuals
+ if (fCurrentSensID!=kVtxSensID) tempHMat->MasterToLocalVect(fPintLoc,m.fMeas); // local residuals
+ else for (int i=3;i--;) m.fMeas[i] = fPintLoc[i];
+ if (dbg) {
+ printf("res(meas-loc) "); for (int k=0;k<3;k++) printf(":[%d] %+.3e ",k,m.fMeas[k]); printf("\n");
+ printf("Fin:%s %+e %+e\n",endModule->GetName(), fDerivativeGlo[kZ][kZ], fPintLoc[kZ]);
+ }//RRR
m.fSigma[kX] = fSigmaLoc[kX];
m.fSigma[kY] = fSigmaLoc[kY];
m.fSigma[kZ] = fSigmaLoc[kZ];
m.fNGlobFilled = ifill;
fCurrentModule = endModule;
//
- return 1;
+ return status;
}
//________________________________________________________________________________________________________
/// Set local equations with data stored in m
/// return 0 if success
//
+ Bool_t locPatt[kNLocal] = {0}; // pattern of lacal eq's to account
+ for (int i=fNLocal; i--;) {
+ if (locPatt[i]) continue; // already set
+ for (Int_t j=0; j<neq; j++) for (int ic=3;ic--;) if (!IsZero(marr[j].fDerLoc[i][ic])) locPatt[i]=kTRUE;
+ }
+ //
for (Int_t j=0; j<neq; j++) {
//
const Mille2Data &m = marr[j];
//
Bool_t filled = kFALSE;
for (int ic=3;ic--;) {
- if (ic==kY && !fUseLocalYErr) continue;
+ // for the diamond point (if any) the Y residual is accounted
+ if (ic==kY && !fUseLocalYErr && !(m.fModuleID[0]==fDiamondModID)) continue;
AliDebug(2,Form("setting local equation %c with fMeas=%.6f and fSigma=%.6f",fgkXYZ[ic],m.fMeas[ic], m.fSigma[ic]));
- Bool_t zero = kTRUE;
- for (int i=fNLocal; i--;) zero &= SetLocalDerivative( i, m.fDerLoc[i][ic] );
- for (int i=m.fNGlobFilled;i--;) zero &= SetGlobalDerivative( m.fParMilleID[i] , m.fDerGlo[i][ic] );
- if (zero) { AliInfo(Form("Skipping %c residual due to the zero derivatives!",fgkXYZ[ic])); continue; }
+ Int_t nzero = 0, naddl = 0;
+ for (int i=0;i<=fNLocal;i++) if (locPatt[i]) nzero += SetLocalDerivative(naddl++,m.fDerLoc[i][ic] );
+ if (nzero==fNLocal) {
+ AliInfo(Form("Skipping %c residual due to the zero derivatives!",fgkXYZ[ic]));
+ continue;
+ }
+ for (int i=m.fNGlobFilled;i--;) SetGlobalDerivative( m.fParMilleID[i] , m.fDerGlo[i][ic] );
fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, m.fMeas[ic], m.fSigma[ic]);
filled = kTRUE;
//
//
if (filled) for (int i=m.fNModFilled;i--;) GetMilleModule(m.fModuleID[i])->IncNProcessedPoints();
}
+ //
+ double wgh = 1;
+ if (GetWeightPt() && fTPAFitter) {
+ wgh = fTPAFitter->GetPt();
+ if (wgh>10) wgh = 10.;
+ if (wgh<0) wgh = fTPAFitter->IsTypeCosmics() ? 7 : 0.5;
+ if (GetWeightPt()>0) wgh = TMath::Power(wgh,GetWeightPt());
+ }
+ fMillepede->SetRecordWeight(wgh*fTrackWeight);
+ fMillepede->SetRecordRun(fRunID);
+ //
}
//________________________________________________________________________________________________________
{
// load definitions of supermodules from a root file
// return 0 if success
-
+ AliInfo(Form("Loading SuperModule definitions from %s",sfile));
TFile *smf=TFile::Open(sfile);
if (!smf->IsOpen()) {
AliInfo(Form("Cannot open supermodule file %s",sfile));
for (Int_t i=0; i<nsma; i++) {
AliAlignObjParams *a = (AliAlignObjParams*)sma->UncheckedAt(i);
volid=a->GetVolUID();
- strcpy(st,a->GetSymName());
+ strncpy(st,a->GetSymName(),TMath::Min(sizeof(st),strlen(a->GetSymName())+1));
a->GetMatrix(m);
//
- sscanf(st,"%s",symname);
+ memset(symname,0,250*sizeof(char));
+ sscanf(st,"%249s",symname);
//
// decode module list
char *stp=strstr(st,"ModuleList:");
int idx[2200];
char spp[200]; int jp=0;
char cl[20];
- strcpy(st,stp);
+ strncpy(st,stp,TMath::Min(sizeof(st),strlen(stp)+1));
int l=strlen(st);
int j=0;
int n=0;
if (strlen(spp)) {
int k=strcspn(spp,"-");
if (k<int(strlen(spp))) { // c'e' il -
- strcpy(cl,&(spp[k+1]));
+ strncpy(cl,&(spp[k+1]), TMath::Min(sizeof(cl),strlen(&spp[k+1])+1));
spp[k]=0;
int ifrom=atoi(spp); int ito=atoi(cl);
for (int b=ifrom; b<=ito; b++) {
int nmod = cstr->GetNModules();
double jacobian[AliITSAlignMille2Module::kMaxParGeom][AliITSAlignMille2Module::kMaxParGeom];
//
+ // check if this not special SDDT0 constraint
+ if (cstr->GetPattern()==BIT(AliITSAlignMille2Module::kDOFT0)) {
+ for (int i=0;i<cstr->GetNModules()-1;i++) {
+ AliITSAlignMille2Module *mdI = GetMilleModule(cstr->GetModuleID(i));
+ if (!mdI->IsFreeDOF(AliITSAlignMille2Module::kDOFT0)) continue;
+ for (int j=i+1;j<cstr->GetNModules();j++) {
+ AliITSAlignMille2Module *mdJ = GetMilleModule(cstr->GetModuleID(j));
+ if (!mdJ->IsFreeDOF(AliITSAlignMille2Module::kDOFT0)) continue;
+ //
+ ResetLocalEquation();
+ fGlobalDerivatives[mdI->GetParOffset(AliITSAlignMille2Module::kDOFT0)] = 1;
+ fGlobalDerivatives[mdJ->GetParOffset(AliITSAlignMille2Module::kDOFT0)] =-1;
+ AddConstraint(fGlobalDerivatives, 0, 1.E-6);
+ }
+ }
+ return;
+ }
+
for (int imd=nmod;imd--;) {
int modID = cstr->GetModuleID(imd);
AliITSAlignMille2Module* mod = GetMilleModule(modID);
cstr->SetApplied(-1);
}
}
+ //
+ // do we need to tie the SDD left/right VDrift corrections
+ for (int imd=0;imd<fNModules;imd++) {
+ AliITSAlignMille2Module* mod = GetMilleModule(imd);
+ if (mod->IsSDD() && mod->IsVDriftLRSame()) TieSDDVDriftsLR(mod);
+ }
+ //
}
//________________________________________________________________________________________________________
//
if (imd>=0) {
AliITSAlignMille2Module* mod = GetMilleModule(imd);
+ if (mod->IsNotInConf()) continue;
UInt_t pattern = 0;
for (int ipar=mod->GetNParTot();ipar--;) {
if (cstr->IsApplied(ipar)) continue;
int nadd = 0;
for (int imd=fNModules;imd--;) {
AliITSAlignMille2Module* mod = GetMilleModule(imd);
- if (mod->GetParent()) continue; // this is not an orphan
+ if (mod->IsNotInConf()) continue; // dummy module
+ AliITSAlignMille2Module* par = mod->GetParent();
+ while (par && par->IsNotInConf() ) par = par->GetParent(); // use only decalred parents
+ if (par) continue; // this is not an orphan
int idpar = mod->GetParOffset(ip);
if (idpar<0) continue;
fGlobalDerivatives[idpar] = 1.0;
}
//
parent->SetParVal(ip, parent->GetParVal(ip) - shift);
- AliInfo(Form("%s constraint: added %f shift to param[%d] of %d children of module %d: %s",
+ AliInfo(Form("%s constraint: added %+f shift to param[%d] of %d children of module %d: %s",
type==AliITSAlignMille2Constraint::kTypeMean ? "MEAN" : "MEDIAN",shift,
ip,npc,idm,parent->GetName()));
}
int nc = fNModules;
//
int norph = 0;
- for (int ich=nc;ich--;) if (!GetMilleModule(ich)->GetParent()) norph ++;
+ for (int ich=nc;ich--;) {
+ AliITSAlignMille2Module *par= GetMilleModule(ich)->GetParent();
+ while (par && par->IsNotInConf()) par = par->GetParent(); // use only decalred parents
+ if (!par) norph ++;
+ }
+ //
if (!norph) return;
double *tmpArr = new double[norph];
+ for (int i=norph;i--;) tmpArr[i] = 0;
//
for (int ip=0;ip<kNParCh;ip++) {
int npc = 0;
int nfree = 0;
for (int ich=nc;ich--;) {
AliITSAlignMille2Module* child = GetMilleModule(ich);
+ if (child->IsNotInConf()) continue; // dummy module
// if (child->GetParent() || !child->IsFreeDOF(ip)) continue;
- if (child->GetParent()) continue;
+ AliITSAlignMille2Module* par = child->GetParent();
+ while (par && par->IsNotInConf()) par = par->GetParent(); // count only declared parents
+ if (par) continue;
tmpArr[nfree++] = child->GetParVal(ip);
}
double median=0,mean=0;
//
for (int ich=nc;ich--;) {
AliITSAlignMille2Module* child = GetMilleModule(ich);
+ if (child->IsNotInConf()) continue; // dummy module
// if (child->GetParent() || !child->IsFreeDOF(ip)) continue;
- if (child->GetParent()) continue;
+ AliITSAlignMille2Module* par = child->GetParent();
+ while (par && par->IsNotInConf()) par = par->GetParent(); // count only declared parents
+ if (par) continue;
child->SetParVal(ip, child->GetParVal(ip) + shift);
npc++;
}
//
- AliInfo(Form("%s constraint: added %f shift to param[%d] of %d orphan modules",
+ AliInfo(Form("%s constraint: added %+f shift to param[%d] of %d orphan modules",
type==AliITSAlignMille2Constraint::kTypeMean ? "MEAN" : "MEDIAN",shift,
ip,npc));
}
}
for (int i=0;i<fNModules;i++) {
AliITSAlignMille2Module* md = GetMilleModule(i);
+ if (md->IsNotInConf()) continue;
if (md->GetParent()==0 && md->GetNParFree()==0) return kTRUE;
}
return kFALSE;
}
//________________________________________________________________________________________________________
-void AliITSAlignMille2::ConvertParamsToGlobal()
+void AliITSAlignMille2::ConvertParamsToGlobal() const
{
// convert params in local frame to global one
double pars[AliITSAlignMille2Module::kMaxParGeom];
}
//________________________________________________________________________________________________________
-void AliITSAlignMille2::ConvertParamsToLocal()
+void AliITSAlignMille2::ConvertParamsToLocal() const
{
// convert params in global frame to local one
double pars[AliITSAlignMille2Module::kMaxParGeom];
//
TMap *cdbMap=0;
TList* cdbList=0;
- TObjString *objStr,*keyStr;
+ TObjString *objStr,*objStr1,*keyStr;
+ TString cdbStr;
AliCDBManager* man = AliCDBManager::Instance();
+ man->SetCacheFlag(kFALSE);
//
int run = userInfo->GetUniqueID();
+ if (run>0) SetRunID(run);
AliInfo(Form("UserInfo corresponds to run#%d",run));
cdbMap = (TMap*)userInfo->FindObject("cdbMap");
+ const TMap *curMap = man->GetStorageMap();
if (!cdbMap) {AliInfo("No CDB Map found in UserInfo");}
else {
- if ((objStr=(TObjString*)cdbMap->GetValue("default"))) { // first set default CDB path
- fDefCDBpath = objStr->GetString();
- if (fDefCDBpath.BeginsWith("raw://")) fDefCDBpath = "raw://";
- AliInfo(Form("Default CDB Storage from UserInfo: %s",fDefCDBpath.Data()));
+ if ((objStr=(TObjString*)cdbMap->GetValue("default"))) { // first set default CDB path
+ if ((objStr1=(TObjString*)curMap->GetValue("default")) && objStr1->GetUniqueID()) {
+ AliInfo(Form("OCDB default path from UserInfo: %s is overriden by user setting %s",objStr->GetName(),objStr1->GetName()));
+ }
+ else {
+ cdbStr = objStr->GetString();
+ man->UnsetDefaultStorage();
+ if (man->GetRaw()) man->SetRaw(kFALSE);
+ if (cdbStr.BeginsWith("raw://")) cdbStr = "raw://";
+ AliInfo(Form("Default CDB Storage from UserInfo: %s",cdbStr.Data()));
+ man->SetDefaultStorage( cdbStr.Data() ); // this may be overriden later by configuration file
+ }
}
- man->SetDefaultStorage( fDefCDBpath.Data() ); // this may be overriden later by configuration file
- man->SetRun(run);
+ if (man->GetRaw() && run>0) man->SetRun(run);
//
// set specific paths relevant for alignment
TIter itMap(cdbMap);
while( (keyStr=(TObjString*)itMap.Next()) ) {
TString keyS = keyStr->GetString();
if ( keyS == "default" ) continue;
+ //
+ TObjString* curPath = (TObjString*)curMap->GetValue(keyStr->GetName());
+ if (curPath && curPath->GetUniqueID()) {
+ AliInfo(Form("Storage for %s from UserInfo\n is overriden by user setting %s",keyS.Data(),curPath->GetName()));
+ continue;
+ }
man->SetSpecificStorage( keyS.Data(), cdbMap->GetValue(keyS)->GetName() );
}
}
cdbList = (TList*)userInfo->FindObject("cdbList");
if (!cdbList) {AliInfo("No CDB List found in UserInfo");}
else {
- // Deltas used for TrackPointArray production
- TIter itList(cdbList);
- while( (objStr=(TObjString*)itList.Next()) )
- if (objStr->GetString().Contains("ITS/Align/Data")) {
- fInitDeltaPath = objStr->GetString();
- AliInfo(Form("Production Misalignment from UserInfo: %s",fInitDeltaPath.Data()));
- break;
- }
- // SDD response (time0 and drift speed correction) used for TrackPointArray production
- itList.Reset();
- while( (objStr=(TObjString*)itList.Next()) )
- if (objStr->GetString().Contains("ITS/Calib/RespSDD")) {
- fInitSDDRespPath = objStr->GetString();
- AliInfo(Form("Production SDD Response from UserInfo: %s",fInitSDDRespPath.Data()));
- break;
- }
- //
+ // Objects used for TrackPointArray production
+ GetPathFromUserInfo(cdbList,"GRP/Geometry/Data",fIniGeomPath ,kSameInitGeomBit);
+ GetPathFromUserInfo(cdbList,"ITS/Align/Data" ,fIniDeltaPath,kSameInitDeltasBit);
+ GetPathFromUserInfo(cdbList,"ITS/Calib/RespSDD",fIniSDDRespPath,kSameInitSDDRespBit);
+ GetPathFromUserInfo(cdbList,"ITS/Calib/DriftSpeedSDD",fIniSDDVDriftPath,kSameInitSDDVDriftBit);
+ GetPathFromUserInfo(cdbList,"ITS/Calib/MapsTimeSDD",fIniSDDCorrMapPath,kSameInitSDDCorrMapBit);
+ GetPathFromUserInfo(cdbList,"GRP/Calib/MeanVertexSPD",fDiamondPath,kSameDiamondBit);
}
//
- objStr = (TObjString*)userInfo->FindObject("BzkGauss");
- if (objStr) {
+ TList *bzlst = (TList*)userInfo->FindObject("BzkGauss");
+ if (bzlst && bzlst->At(0)) {
+ objStr = (TObjString*)bzlst->At(0);
SetBField( objStr->GetString().Atof() );
- AliInfo(Form("Magentic field from UserInfo: %+.2e",GetBField()));
+ AliInfo(Form("Magnetic field from UserInfo: %+.2e",GetBField()));
}
return 0;
}
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::GetPathFromUserInfo(const TList* cdbList,const char* calib,TString& path, Int_t useBit)
+{
+ // extract the path for specific CDB path from user info. If it is the same as already loaded, set corresponing bit
+ TIter itList(cdbList);
+ if (useBit>=0) ResetBit(useBit);
+ TObjString* objStr;
+ while( (objStr=(TObjString*)itList.Next()) )
+ if (objStr->GetString().Contains(calib)) {
+ TString newpath = objStr->GetString();
+ AliInfo(Form("Found path in UserInfo: %s",newpath.Data()));
+ if ( useBit>=0 && (fUserProvided&useBit) ) {
+ AliInfo(Form("Will use the one provided in config: %s",path.Data()));
+ SetBit(useBit);
+ }
+ else if ( useBit>=0 && (newpath == path) ) {
+ AliInfo(Form("Path %s is the same as already loaded",path.Data()));
+ SetBit(useBit);
+ }
+ else path = newpath;
+ //
+ return 0;
+ }
+ AliInfo(Form("Did not find path for %s in UserInfo",calib));
+ path = "";
+ return -1;
+}
+
//________________________________________________________________________________________________________
Int_t AliITSAlignMille2::LoadSDDResponse(TString& path, AliITSresponseSDD *&resp)
{
+ // load SDD response
if (path.IsNull()) return 0;
+ AliInfo(Form("Loading SDD response from %s",path.Data()));
//
AliCDBEntry *entry = 0;
+ delete resp;
resp = 0;
+ //
while(1) {
if (path.BeginsWith("path: ")) { // must load from OCDB
- AliCDBId* cdbId = AliCDBId::MakeFromString( path.Data() );
- entry = AliCDBManager::Instance()->Get( *cdbId );
- delete cdbId;
+ entry = GetCDBEntry(path.Data());
if (!entry) break;
resp = (AliITSresponseSDD*) entry->GetObject();
entry->SetObject(NULL);
entry->SetOwner(kTRUE);
- delete entry;
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
break;
}
//
resp = (AliITSresponseSDD*) entry->GetObject();
if (resp && resp->InheritsFrom(AliITSresponseSDD::Class())) entry->SetObject(NULL);
else resp = 0;
+ entry->SetObject(NULL);
entry->SetOwner(kTRUE);
delete entry;
}
return 0;
}
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::LoadSDDVDrift(TString& path, TObjArray *&arr)
+{
+ // load VDrift object
+ if (path.IsNull()) return 0;
+ AliInfo(Form("Loading SDD VDrift from %s",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);
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
+ 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) {AliError(Form("Failed to load SDD vdrift from %s",path.Data())); return -1;}
+ arr->SetOwner(kTRUE);
+ return 0;
+}
+
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::LoadSDDCorrMap(TString& path, AliITSCorrectSDDPoints *&map)
+{
+ // Load SDD correction map
+ //
+ if (path.IsNull()) return 0;
+ AliInfo(Form("Loading SDD Correction Maps from %s",path.Data()));
+ //
+ AliCDBEntry *entry = 0;
+ delete map;
+ map = 0;
+ TObjArray* 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);
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
+ 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) {AliError(Form("Failed to load SDD Correction Map from %s",path.Data())); return -1;}
+ arr->SetOwner(kTRUE);
+ map = new AliITSCorrectSDDPoints(arr);
+
+ return 0;
+}
+
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::LoadPreSDDCalib()
+{
+ // Load SDD correction map for prealignment from current CDB
+ //
+ AliInfo(Form("Loading SDD Calibration set for run %d",fRunID));
+ AliCDBManager* man = AliCDBManager::Instance();
+ man->SetRun(fRunID);
+ AliCDBEntry *entry = man->Get("ITS/Calib/MapsTimeSDD");
+ if(!entry){
+ AliError("Error accessing OCDB: SDD maps not found");
+ return -1;
+ }
+ delete fPreCorrMapSDD;
+ TObjArray* arr = (TObjArray*) entry->GetObject();
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ arr->SetOwner(kTRUE);
+ fPreCorrMapSDD = new AliITSCorrectSDDPoints(arr);
+ //
+ entry = man->Get("ITS/Calib/RespSDD");
+ if(!entry){
+ AliError("Error accessing OCDB: SDD response not found");
+ return -1;
+ }
+ delete fPreRespSDD;
+ fPreRespSDD = (AliITSresponseSDD*) entry->GetObject();
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ //
+ entry = man->Get("ITS/Calib/DriftSpeedSDD");
+ if(!entry){
+ AliError("Error accessing OCDB: SDD Drift speed not found");
+ return -1;
+ }
+ delete fPreVDriftSDD;
+ fPreVDriftSDD = (TObjArray*) entry->GetObject();
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ delete entry;
+ //
+ return 0;
+}
+
+//________________________________________________________________________________________________________
+Int_t AliITSAlignMille2::LoadDiamond(TString& path)
+{
+ // load vertex constraint
+ if (path.IsNull()) return 0;
+ AliInfo(Form("Loading Diamond Constraint from %s",path.Data()));
+ //
+ AliCDBEntry *entry = 0;
+ AliESDVertex *vtx = 0;
+ while(1) {
+ if (path.BeginsWith("path: ")) { // must load from OCDB
+ entry = GetCDBEntry(path.Data());
+ if (!entry) break;
+ vtx = (AliESDVertex*) entry->GetObject();
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
+ break;
+ }
+ //
+ if (gSystem->AccessPathName(path.Data())) break;
+ TFile* precf = TFile::Open(path.Data());
+ if (precf->FindKey("AliESDVertex")) vtx = (AliESDVertex*)precf->Get("AliESDVertex");
+ else if (precf->FindKey("AliCDBEntry") && (entry=(AliCDBEntry*)precf->Get("AliCDBEntry"))) {
+ vtx = (AliESDVertex*) entry->GetObject();
+ if (vtx && vtx->InheritsFrom(AliESDVertex::Class())) entry->SetObject(NULL);
+ else vtx = 0;
+ entry->SetObject(NULL);
+ entry->SetOwner(kTRUE);
+ delete entry;
+ }
+ //
+ precf->Close();
+ delete precf;
+ break;
+ }
+ //
+ if (!vtx) {AliError(Form("Failed to load Diamond constraint from %s",path.Data())); return -1;}
+ //
+ double vtxXYZ[3];
+ vtx->GetXYZ(vtxXYZ);
+ for (int i=3;i--;) vtxXYZ[i] -= fCorrDiamond[i];
+ vtx->SetXYZ(vtxXYZ);
+ SetVertexConstraint(vtx);
+ AliInfo("Will use following Diamond Constraint (errors inverted):");
+ fDiamondI.Print("");
+ delete vtx;
+ return 0;
+}
+
//________________________________________________________________________________________________________
Int_t AliITSAlignMille2::LoadDeltas(TString& path, TClonesArray *&arr)
{
+ // load ITS geom deltas
if (path.IsNull()) return 0;
+ AliInfo(Form("Loading Alignment Deltas from %s",path.Data()));
//
AliCDBEntry *entry = 0;
+ delete arr;
arr = 0;
while(1) {
if (path.BeginsWith("path: ")) { // must load from OCDB
- AliCDBId *cdbId = AliCDBId::MakeFromString( path.Data() );
- entry = AliCDBManager::Instance()->Get( *cdbId );
- delete cdbId;
+ entry = GetCDBEntry(path.Data());
if (!entry) break;
arr = (TClonesArray*) entry->GetObject();
entry->SetObject(NULL);
entry->SetOwner(kTRUE);
- delete entry;
+ // AliCDBManager::Instance()->UnloadFromCache(path); // don't want cached object, read new copy
+ // delete cdbId;
+ // delete entry;
break;
}
//
arr = (TClonesArray*) entry->GetObject();
if (arr && arr->InheritsFrom(TClonesArray::Class())) entry->SetObject(NULL);
else arr = 0;
+ entry->SetObject(NULL);
entry->SetOwner(kTRUE);
delete entry;
}
}
//
if (!arr) {AliError(Form("Failed to load Deltas from %s",path.Data())); return -1;}
+ //
return 0;
}
//
}
//
+ TGeoHMatrix *mcurr = new TGeoHMatrix();
+ fCacheMatrixCurr.AddAtAndExpand(mcurr,kVtxSensID); // special unit matrix for diamond constraint
+ //
fCacheMatrixCurr.SetOwner(kTRUE);
return 0;
}
// build arrays for the fast access to sensor original matrices (used for production)
//
TGeoHMatrix mdel;
- AliInfo("Building sensors original matrices cache");
+ AliInfo(Form("Building sensors original matrices cache. InitDeltaPath: %s",fIniDeltaPath.Data()));
+ //
+ /*if (fIniGeomPath!=fGeometryPath)*/ if (LoadGeometry(fIniGeomPath)) {AliInfo("Failed to re-load ideal geometry");exit(1);}
//
fCacheMatrixOrig.Delete();
- if (!fInitDeltaPath.IsNull()) {
- if (LoadDeltas(fInitDeltaPath,fPrealignment) || ApplyToGeometry())
+ if (!fIniDeltaPath.IsNull()) {
+ TClonesArray* prealSav = fPrealignment;
+ fPrealignment = 0;
+ if (LoadDeltas(fIniDeltaPath,fPrealignment) || ApplyToGeometry())
{ AliError("Failed to load/apply initial deltas used to produce points"); return -1;}
+ delete fPrealignment;
+ fPrealignment = prealSav;
}
//
for (int idx=0;idx<=kMaxITSSensID;idx++) {
int volID = AliITSAlignMille2Module::GetVolumeIDFromIndex(idx);
TGeoHMatrix *morig = new TGeoHMatrix();
- if (fUsePreAlignment) AliITSAlignMille2Module::SensVolMatrix(volID,morig);
- else AliITSAlignMille2Module::SensVolOrigGlobalMatrix(volID,morig);
+ AliITSAlignMille2Module::SensVolMatrix(volID,morig);
fCacheMatrixOrig.AddAtAndExpand(morig,idx);
}
//
- fCacheMatrixOrig.SetOwner(kTRUE);
- if (fUsePreAlignment) { // the initial deltas were temporary attached to prealignment array, clean and reinitialize geometry
- delete fPrealignment;
- fPrealignment = 0;
- fUsePreAlignment = 0;
- InitGeometry();
+ if (fConvertPreDeltas) {
+ // in order to convert deltas from old to new geometry we need the final matrices for all alignable objects
+ int nmat = fGeoManager->GetNAlignable();
+ fConvAlgMatOld.Delete();
+ int nmatSel = 0;
+ for (int i=0;i<nmat;i++) {
+ TString nm = fGeoManager->GetAlignableEntry(i)->GetName();
+ if (!nm.BeginsWith("ITS")) continue;
+ TGeoHMatrix *mo = new TGeoHMatrix();
+ (*mo) = *(AliGeomManager::GetMatrix(nm));
+ fConvAlgMatOld.AddAtAndExpand(mo,nmatSel++);
+ mo->SetTitle(nm);
+ mo->SetName(nm);
+ }
+ ConvSortHierarchically(fConvAlgMatOld);
}
+ //
+ TGeoHMatrix *mcurr = new TGeoHMatrix();
+ fCacheMatrixOrig.AddAtAndExpand(mcurr,kVtxSensID); // special unit matrix for diamond constraint
+ //
+ fCacheMatrixOrig.SetOwner(kTRUE);
+
+ fUsePreAlignment = 0;
+ LoadGeometry(fGeometryPath); // reload target geometry
+ //
return 0;
}
+//________________________________________________________________________________________________________
+void AliITSAlignMille2::RemoveHelixFitConstraint()
+{
+ // suppress constraint
+ fConstrCharge = 0;
+ fConstrPT = fConstrPTErr = -1;
+}
+
//________________________________________________________________________________________________________
void AliITSAlignMille2::ConstrainHelixFitPT(Int_t q,Double_t pt,Double_t pterr)
{
fConstrCharge = q==0 ? q:TMath::Sign(1,q);
fConstrPT = pt;
fConstrPTErr = pterr;
+ fCurvFitWasConstrained = kTRUE;
}
//________________________________________________________________________________________________________
if (crv<0 || IsZero(crv)) {
fConstrPT = -1;
fConstrPTErr = -1;
+ fCurvFitWasConstrained = kFALSE;
}
else {
- fConstrPT = 1./crv*fBField*kCQConv;
- fConstrPTErr =fConstrPT/crv*crverr;
+ fConstrPT = TMath::Abs(1./crv*fBField*kCQConv);
+ fConstrPTErr = crverr>1e-10 ? TMath::Abs(fConstrPT/crv*crverr) : 0.;
+ fCurvFitWasConstrained = kTRUE;
}
}
//
AliITSAlignMille2Module* md = GetMilleModuleBySymName(algname); // explicitly varied?
AliITSAlignMille2Module* parent = md ? md->GetParent(): GetMilleModuleIfContained(algname);
+ if (md && parent) {
+ TString mdName = md->GetName();
+ TString prName = parent->GetName();
+ // SPD Sector -> Layer parentship is fake, need special treatment
+ if ( mdName.CountChar('/')==2 && mdName.BeginsWith("ITS/SPD") && // SPD sector
+ prName.CountChar('/')==1 && mdName.BeginsWith("ITS/SPD") ) // SPD Layer
+ parent = parent->GetParent();//: GetMilleModuleIfContained(prName.Data());
+ }
+ //
AliAlignObjParams* preob = GetPrealignedObject(algname); // was it prealigned ?
//
if (!preob && !md && (!parent || parent->IsAlignable())) continue; // noting to do
tempMatX.MultiplyLeft(&tempMatY);
tempMatX.Multiply(&tempMatY.Inverse());
//
+ if (tempMatX.IsIdentity()) continue; // do not store dummy matrices
UShort_t vid = AliITSAlignMille2Module::GetVolumeIDFromSymname(algname);
new(alobj[idx++]) AliAlignObjParams(algname,vid,tempMatX,kTRUE);
//
// eventual precalibration
//
// if there was a precalibration provided, copy it to new arrray
- AliITSresponseSDD *precal = GetSDDPrecalibration();
- if (!precal) precal = GetSDDInit();
+ AliITSresponseSDD *precal = GetSDDPrecalResp();
+ if (!precal && fIniVDriftSDD) precal = GetSDDInitResp(); // InitResp is used only when IniVDrift is provided
+ Bool_t isPreCalMult = precal&&precal->IsVDCorrMult() ? kTRUE : kFALSE;
AliITSresponseSDD *calibSDD = new AliITSresponseSDD();
- //
- for (int ind=kSDDoffsID;ind<kSDDoffsID+kNSDDmod;ind++) {
- calibSDD->SetModuleTimeZero(ind, precal? precal->GetTimeZero(ind) : 0.);
- calibSDD->SetDeltaVDrift(ind, precal? precal->GetDeltaVDrift(ind) : 0.);
+ calibSDD->SetVDCorrMult(fIsSDDVDriftMult);
+ //
+ // copy initial values to the new object
+ if (precal) {
+ calibSDD->SetTimeOffset(precal->GetTimeOffset());
+ calibSDD->SetADC2keV(precal->GetADC2keV());
+ calibSDD->SetChargevsTime(precal->GetChargevsTime());
+ for (int ind=kSDDoffsID;ind<kSDDoffsID+kNSDDmod;ind++) {
+ calibSDD->SetModuleTimeZero(ind, precal->GetTimeZero(ind));
+ calibSDD->SetDeltaVDrift(ind, precal->GetDeltaVDrift(ind,kFALSE),kFALSE); // left
+ calibSDD->SetDeltaVDrift(ind, precal->GetDeltaVDrift(ind,kTRUE ),kTRUE); // right
+ calibSDD->SetADCtokeV(ind,precal->GetADCtokeV(ind));
+ }
}
+ else for (int ind=kSDDoffsID;ind<kSDDoffsID+kNSDDmod;ind++) calibSDD->SetModuleTimeZero(ind,0);
//
Bool_t save = kFALSE;
for (int imd=GetNModules();imd--;) {
AliITSAlignMille2Module* md = GetMilleModule(imd);
if (!md->IsSDD()) continue;
- if (md->IsFreeDOF(AliITSAlignMille2Module::kDOFT0) ||
- md->IsFreeDOF(AliITSAlignMille2Module::kDOFDV)) save = kTRUE;
- //
+ if (md->IsFreeDOF(AliITSAlignMille2Module::kDOFT0) ||
+ md->IsFreeDOF(AliITSAlignMille2Module::kDOFDVL) ||
+ md->IsFreeDOF(AliITSAlignMille2Module::kDOFDVR)) save = kTRUE;
+ //
for (int is=0;is<md->GetNSensitiveVolumes();is++) {
int ind = md->GetSensVolIndex(is);
- float t0 = calibSDD->GetTimeZero(ind) + md->GetParVal(AliITSAlignMille2Module::kDOFT0);
- float dv = calibSDD->GetDeltaVDrift(ind) + md->GetParVal(AliITSAlignMille2Module::kDOFDV);
+ float t0 = calibSDD->GetTimeZero(ind) + md->GetParVal(AliITSAlignMille2Module::kDOFT0);
+ double dvL = md->GetParVal(AliITSAlignMille2Module::kDOFDVL);
+ double dvR = md->GetParVal(AliITSAlignMille2Module::kDOFDVR);
+ if (!calibSDD->IsVDCorrMult()) { // save as additive correction
+ dvL *= 1e4;
+ dvR *= 1e4;
+ //
+ double conv = 1;
+ if (isPreCalMult) conv = 6.4; // convert multiplicative precal correction to additive
+ dvL += calibSDD->GetDeltaVDrift(ind,kFALSE)*conv;
+ dvR += calibSDD->GetDeltaVDrift(ind,kTRUE)*conv;
+ }
+ else { // save as multipicative correction
+ double conv = 1;
+ if (!isPreCalMult) conv = 1./6.4; // convert additive precal correction to multiplicative
+ dvL += calibSDD->GetDeltaVDrift(ind,kFALSE)*conv;
+ dvR += calibSDD->GetDeltaVDrift(ind,kTRUE)*conv;
+ }
//
calibSDD->SetModuleTimeZero(ind, t0);
- calibSDD->SetDeltaVDrift(ind, dv);
+ calibSDD->SetDeltaVDrift(ind, dvL, kFALSE); // left side correction
+ calibSDD->SetDeltaVDrift(ind, dvR, kTRUE); // right side correction
}
}
//
//
return calibSDD;
}
+
+//_______________________________________________________________________________________
+Int_t AliITSAlignMille2::ReloadInitCalib(TList *userInfo)
+{
+ // Use provided UserInfo to
+ // load the initial calib parameters (geometry, SDD response...)
+ // Can be used if set of data was processed with different calibration
+ //
+ if (!userInfo) {
+ AliInfo("Reloading of the Calibration parameters was called with empty userInfo");
+ return 1;
+ }
+ if (ProcessUserInfo(userInfo)) {
+ AliInfo("Error in processing user info");
+ userInfo->Print();
+ exit(1);
+ }
+ return ReloadInitCalib();
+}
+
+//_______________________________________________________________________________________
+Int_t AliITSAlignMille2::ReloadInitCalib()
+{
+ // Load the initial calib parameters (geometry, SDD response...)
+ // Can be used if set of data was processed with different calibration
+ //
+ AliInfo(Form("SameInitDelta: %d | SameInitGeom: %d",TestBit(kSameInitDeltasBit), TestBit(kSameInitGeomBit)));
+ // 1st cache original matrices
+ if (!(TestBit(kSameInitDeltasBit) && TestBit(kSameInitGeomBit))) { // need to reload geometry
+ //
+ if (CacheMatricesOrig()) {
+ AliInfo("Failed to cache new initial geometry");
+ exit(1);
+ }
+ // RS : commented because we don't need to reload prealignment deltas, they are already loaded
+ // then reload the prealignment geometry
+ // if (LoadDeltas(fPreDeltaPath,fPrealignment)) {
+ // AliInfo(Form("Failed to reload the prealigned geometry %s",fPreDeltaPath.Data()));
+ // exit(1);
+ // }
+ //
+ if (fPrealignment && ApplyToGeometry()) {
+ AliInfo(Form("Failed re-apply prealigned geometry %s",fPreDeltaPath.Data()));
+ exit(1);
+ }
+ //
+ // usually no need to re-cache the prealignment geometry, it was not changed
+ if (fCacheMatrixCurr.GetEntriesFast() != fCacheMatrixOrig.GetEntriesFast()) {
+ // CacheMatricesCurr();
+ AliInfo(Form("Failed to cache the prealigned geometry %s",fPreDeltaPath.Data()));
+ exit(1);
+ }
+ }
+ else ResetBit(kSameInitDeltasBit);
+ //
+ // reload initial SDD response
+ if (!TestBit(kSameInitSDDRespBit)) {
+ if (LoadSDDResponse(fIniSDDRespPath, fIniRespSDD) ) {
+ AliInfo(Form("Failed to load new SDD response %s",fIniSDDRespPath.Data()));
+ exit(1);
+ }
+ }
+ else ResetBit(kSameInitSDDRespBit);
+ //
+ // reload initial SDD vdrift
+ if (!TestBit(kSameInitSDDVDriftBit)) {
+ if (LoadSDDVDrift(fIniSDDVDriftPath, fIniVDriftSDD) ) {
+ AliInfo(Form("Failed to load new SDD VDrift %s",fIniSDDVDriftPath.Data()));
+ exit(1);
+ }
+ }
+ else ResetBit(kSameInitSDDRespBit);
+ //
+ // reload SDD corr.map
+ if (!TestBit(kSameInitSDDCorrMapBit)) {
+ if (LoadSDDCorrMap(fIniSDDCorrMapPath, fIniCorrMapSDD) ) {
+ AliInfo(Form("Failed to load new SDD Correction Map %s",fIniSDDCorrMapPath.Data()));
+ exit(1);
+ }
+ }
+ else ResetBit(kSameInitSDDRespBit);
+ //
+ // reload diamond info
+ if (!TestBit(kSameDiamondBit)) {
+ if (LoadDiamond(fDiamondPath) ) {
+ AliInfo(Form("Failed to load new Diamond constraint %s",fDiamondPath.Data()));
+ exit(1);
+ }
+ }
+ else ResetBit(kSameInitSDDRespBit);
+ //
+ return 0;
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::JacobianPosGloLoc(int locid,double* jacobian)
+{
+ // calculate the locid row of the jacobian for transformation of the local coordinate to global at current point
+ TGeoHMatrix* mat = GetSensorCurrMatrixSID(fCurrentSensID);
+ const Double_t dpar = 1e-2;
+ double sav = fMeasLoc[locid];
+ fMeasLoc[locid] += dpar;
+ mat->LocalToMaster(fMeasLoc,jacobian);
+ fMeasLoc[locid] = sav; // recover original value
+ for (int i=3;i--;) jacobian[i] = (jacobian[i]-fMeasGlo[i])/dpar; // the transformation is linear!!!
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::TieSDDVDriftsLR(AliITSAlignMille2Module* mod)
+{
+ // impose equality of Left/Right sides VDrift correction for SDD
+ ResetLocalEquation();
+ if ( (mod->IsFreeDOF(AliITSAlignMille2Module::kDOFDVL) + mod->IsFreeDOF(AliITSAlignMille2Module::kDOFDVR))==1) {
+ AliError("Left/Right VDrift equality is requested for SDD module with only one side VDrift free");
+ mod->Print();
+ return;
+ }
+ if (mod->GetParOffset(AliITSAlignMille2Module::kDOFDVL)>=0) SetGlobalDerivative(mod->GetParOffset(AliITSAlignMille2Module::kDOFDVL), 1.);
+ if (mod->GetParOffset(AliITSAlignMille2Module::kDOFDVR)>=0) SetGlobalDerivative(mod->GetParOffset(AliITSAlignMille2Module::kDOFDVR), -1.);
+ AddConstraint(fGlobalDerivatives, 0, 1e-12);
+ //
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::ProcessSDDPointInfo(const AliTrackPoint* pnt,Int_t sID, Int_t pntID)
+{
+ // extract the drift information from SDD track point
+ //
+ fDriftTime0[pntID] = fIniRespSDD ? fIniRespSDD->GetTimeZero(sID) : 0.;
+ double tdif = pnt->GetDriftTime() - fDriftTime0[pntID];
+ if (tdif<0) tdif = 1;
+ //
+ // VDrift extraction
+ double vdrift=0,vdrift0=0;
+ Bool_t sddSide = kFALSE;
+ int sID0 = 2*(sID-kSDDoffsID);
+ double zanode = -999;
+ //
+ if (fIniVDriftSDD) { // SDD VDrift object is provided, use the vdrift from it
+ AliITSDriftSpeedArraySDD* drarr;
+ double vdR,vdL,xlR,xlL;
+ // sometimes xlocal on right side is negative due to the wrong calibration, need to test both hypothesis
+ double xlabs = TMath::Abs(fMeasLoc[kX]);
+ drarr = (AliITSDriftSpeedArraySDD*)fIniVDriftSDD->At(sID0); // left side, xloc>0
+ zanode = fSegmentationSDD->GetAnodeFromLocal(xlabs,fMeasLoc[kZ]);
+ vdL = drarr->GetDriftSpeed(0, zanode);
+ if (fIniRespSDD) {
+ double corr = fIniRespSDD->GetDeltaVDrift(sID, kFALSE);
+ if (fIniRespSDD->IsVDCorrMult()) vdL *= (1+corr);
+ else vdL += corr;
+ }
+ xlL = (fSegmentationSDD->Dx() - vdL*tdif)*1e-4;
+ //
+ drarr = (AliITSDriftSpeedArraySDD*)fIniVDriftSDD->At(sID0+1); // right side, xloc<0
+ zanode = fSegmentationSDD->GetAnodeFromLocal(-xlabs,fMeasLoc[kZ]) - 256;
+ vdR = drarr->GetDriftSpeed(0, zanode);
+ if (fIniRespSDD) {
+ double corr = fIniRespSDD->GetDeltaVDrift(sID, kTRUE);
+ if (fIniRespSDD->IsVDCorrMult()) vdR *= (1+corr);
+ else vdR += corr;
+ }
+ xlR = -(fSegmentationSDD->Dx() - vdR*tdif)*1e-4;
+ //
+ if (TMath::Abs(xlL-fMeasLoc[kX])<TMath::Abs(xlR-fMeasLoc[kX])) {
+ sddSide = 0; // left side
+ vdrift = vdL*1e-4;
+ }
+ else { // right side
+ sddSide = 1;
+ vdrift = vdR*1e-4;
+ }
+ //
+ }
+ else { // try to determine the vdrift from the xloc
+ vdrift = (fSegmentationSDD->Dx()*1e-4 - TMath::Abs(fMeasLoc[kX]))/tdif;
+ sddSide = fMeasLoc[kX]<0; // 0 = left (xloc>0) ; 1 = right (xloc<1)
+ }
+ //
+ if (fPreVDriftSDD) { // use imposed vdrift as a starting point
+ zanode = fSegmentationSDD->GetAnodeFromLocal(0.5-sddSide,fMeasLoc[kZ]);
+ if (sddSide) zanode -= 256;
+ vdrift = ((AliITSDriftSpeedArraySDD*)fPreVDriftSDD->At(sID0+sddSide))->GetDriftSpeed(0, zanode)*1e-4;
+ }
+ //
+ if (vdrift<0) vdrift = 0;
+ vdrift0 = vdrift;
+ // at this point we have vdrift and t0 used to create the original point.
+ // see if precalibration was provided
+ if (fPreRespSDD) {
+ float t0Upd = fPreRespSDD->GetTimeZero(sID);
+ double corr = fPreRespSDD->GetDeltaVDrift(sID, sddSide);
+ if (fPreRespSDD->IsVDCorrMult()) vdrift *= 1+corr; // right side (xloc<0) may have different correction
+ else vdrift += corr*1e-4;
+ //
+ // if IniRespSDD was used, it should be subtracted back, since it is accounted in the PreResp
+ if (fIniVDriftSDD&&fIniRespSDD && (fPreVDriftSDD==0)) {
+ double corr1 = fIniRespSDD->GetDeltaVDrift(sID, sddSide);
+ if (fIniRespSDD->IsVDCorrMult()) vdrift *= (1-corr1);
+ else vdrift -= corr1*1e-4;
+ }
+ tdif = pnt->GetDriftTime() - t0Upd;
+ // correct Xlocal
+ fMeasLoc[0] = fSegmentationSDD->Dx()*1e-4 - vdrift*tdif;
+ if (sddSide) fMeasLoc[0] = -fMeasLoc[0];
+ fDriftTime0[pntID] = t0Upd;
+ }
+ //
+ if (fPreCorrMapSDD) { // apply correction map
+ fMeasLoc[0] += fPreCorrMapSDD->GetCorrection(sID,fMeasLoc[2],fMeasLoc[0]);
+ }
+
+ // TEMPORARY CORRECTION (if provided) --------------<<<
+ fDriftSpeed[pntID] = sddSide ? -vdrift : vdrift;
+ fDriftSpeed0[pntID] = sddSide ? -vdrift0 : vdrift0;
+ //
+ // printf("#%d: t:%+e x:%+e v:%+e: side:%d\n",pntID,fDriftTime0[pntID],fMeasLoc[0],fDriftSpeed[pntID],sddSide);
+}
+
+//_______________________________________________________________________________________
+AliITSAlignMille2Module* AliITSAlignMille2::CreateVertexModule()
+{
+ // creates dummy module for vertex constraint
+ TGeoHMatrix mt;
+ AliITSAlignMille2Module* mod = new AliITSAlignMille2Module(kVtxSensID,kVtxSensVID,"VTX",&mt,0,0);
+ fMilleModule.AddAtAndExpand(mod,fNModules);
+ mod->SetGeomParamsGlobal(fUseGlobalDelta);
+ fDiamondModID = fNModules;
+ mod->SetUniqueID(fNModules++);
+ mod->SetNotInConf(kTRUE);
+ return mod;
+ //
+}
+
+//_______________________________________________________________________________________
+AliCDBEntry* AliITSAlignMille2::GetCDBEntry(const char* path)
+{
+ // return object from the OCDB
+ AliCDBEntry *entry = 0;
+ AliInfo(Form("Loading object %s",path));
+ AliCDBManager* man = AliCDBManager::Instance();
+ AliCDBId* cdbId = AliCDBId::MakeFromString(path);
+ if (!cdbId) {
+ AliError("Failed to create cdbId");
+ return 0;
+ }
+ //
+ AliCDBStorage* stor = man->GetDefaultStorage();
+ if (!stor && !man->GetRaw()) man->SetDefaultStorage("raw://");
+ if (man->GetRaw()) man->SetRun(fRunID>0 ? fRunID : 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;
+ //
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::SetVertexConstraint(const AliESDVertex* vtx)
+{
+ // set vertex for constraint
+ if (!vtx) return;
+ //
+ double cmat[6];
+ float cmatF[6];
+ vtx->GetCovMatrix(cmat);
+ AliITSAlignMille2Module* diamMod = GetMilleModuleByVID(kVtxSensVID);
+ if (diamMod) {
+ cmat[0] *= diamMod->GetSigmaXFactor()*diamMod->GetSigmaXFactor();
+ cmat[2] *= diamMod->GetSigmaYFactor()*diamMod->GetSigmaYFactor();
+ cmat[5] *= diamMod->GetSigmaZFactor()*diamMod->GetSigmaZFactor();
+ cmat[1] *= diamMod->GetSigmaXFactor()*diamMod->GetSigmaYFactor();
+ cmat[3] *= diamMod->GetSigmaXFactor()*diamMod->GetSigmaZFactor();
+ cmat[4] *= diamMod->GetSigmaYFactor()*diamMod->GetSigmaZFactor();
+ }
+ cmatF[0] = cmat[0]; // xx
+ cmatF[1] = cmat[1]; // xy
+ cmatF[2] = cmat[3]; // xz
+ cmatF[3] = cmat[2]; // yy
+ cmatF[4] = cmat[4]; // yz
+ cmatF[5] = cmat[5]; // zz
+
+ fDiamond.SetXYZ(vtx->GetX(),vtx->GetY(),vtx->GetZ(), cmatF);
+ //
+ Double_t t0 = cmat[2]*cmat[5] - cmat[4]*cmat[4];
+ Double_t t1 = cmat[1]*cmat[5] - cmat[3]*cmat[4];
+ Double_t t2 = cmat[1]*cmat[4] - cmat[2]*cmat[3];
+ Double_t det = cmat[0]*t0 - cmat[1]*t1 + cmat[3]*t2;
+ if (TMath::Abs(det)<1e-36) {
+ vtx->Print();
+ AliFatal("Vertex constraint cov.matrix is singular");
+ }
+ cmatF[0] = t0/det;
+ cmatF[1] = -t1/det;
+ cmatF[2] = t2/det;
+ cmatF[3] = (cmat[0]*cmat[5] - cmat[3]*cmat[3])/det;
+ cmatF[4] = (cmat[1]*cmat[3] - cmat[0]*cmat[4])/det;
+ cmatF[5] = (cmat[0]*cmat[2] - cmat[1]*cmat[1])/det;
+ fDiamondI.SetXYZ(vtx->GetX(),vtx->GetY(),vtx->GetZ(), cmatF);
+ fVertexSet = kTRUE;
+ //
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::ConvertDeltas()
+{
+ // convert prealignment deltas from old geometry to new one
+ // NOTE: the target geometry must be loaded at time this method is called
+ //
+ // NOTE: This method can be ONLY used when as a prealignment deltas those used for the production
+ // of trackpoints (e.g. extracted from the UserInfo).
+ // The prealignment deltas provided by user via config file must be already converted to target geometry:
+ // this can be done externally using the macro ConvertDeltas.C
+ //
+ // delta_j_new = delta_j_old * Xj_old * Xj_new^-1
+ // where X = Prod{delta_i,i=j-1:0} M_j
+ // with j - the level of the alignable volume in the hierarchy, M - corresponding ideal matrix
+ // Note that delta_j * Xj is equal to final (misaligned) matrix of corresponding geometry, G_j.
+ // Since this method is used ONLY in the case where the prealignment deltas are equal to production deltas,
+ // we have already loaded G_j_old in the fConvAlgMatOld (filled in the CacheMatricesOrig)
+ // Hence, delta_j_new = G_j_old * Xj_new^-1
+ //
+ AliInfo("Converting deltas from initial to target geometry");
+ int nMatOld = fConvAlgMatOld.GetEntriesFast(); // number of alignable matrices
+ TClonesArray* deltArrNew = new TClonesArray("AliAlignObjParams",10);
+ //
+ TGeoHMatrix dmPar;
+ int nDelNew = 0;
+ //
+ for (int im=0;im<nMatOld;im++) {
+ TGeoHMatrix* mtGjold = (TGeoHMatrix*)fConvAlgMatOld[im];
+ TString algname = mtGjold->GetTitle();
+ UShort_t vID = AliITSAlignMille2Module::GetVolumeIDFromSymname(algname.Data());
+ //
+ // build X_new >>>
+ TGeoHMatrix* parent = mtGjold;
+ TGeoHMatrix xNew;
+ int parID;
+ while ( (parID=parent->GetUniqueID()-1)>=0 ) {
+ parent = (TGeoHMatrix*)fConvAlgMatOld[parID];
+ AliAlignObjParams* deltaPar = ConvFindDelta(deltArrNew,parent->GetTitle());
+ if (deltaPar) deltaPar->GetMatrix(dmPar); xNew *= dmPar;
+ }
+ AliGeomManager::GetOrigGlobalMatrix(algname,dmPar); // ideal matrix of new geometry
+ xNew *= dmPar;
+ // build X_new <<<
+ //
+ dmPar = *mtGjold;
+ dmPar *= xNew.Inverse();
+ new((*deltArrNew)[nDelNew++]) AliAlignObjParams(algname.Data(),vID,dmPar,kTRUE);
+ //
+ }
+ delete fPrealignment;
+ fPrealignment = deltArrNew;
+ //
+ // we don't need anymore old matrices
+ fConvAlgMatOld.Delete();
+ //
+}
+
+//_______________________________________________________________________________________
+void AliITSAlignMille2::ConvSortHierarchically(TObjArray& matArr)
+{
+ // Used only for the deltas conversion from one geometry to another
+ // Sort the matrices according to hiearachy (coarse -> fine)
+ //
+ int nmat = matArr.GetEntriesFast();
+ //
+ for (int i=0;i<nmat;i++) {
+ for (int j=i+1;j<nmat;j++) {
+ TGeoHMatrix* matI = (TGeoHMatrix*) matArr[i];
+ TGeoHMatrix* matJ = (TGeoHMatrix*) matArr[j];
+ if (ConvIsJParentOfI(matI,matJ)) { // swap
+ matArr[i] = matJ;
+ matArr[j] = matI;
+ }
+ }
+ }
+ //
+ // set direct parent id's in the UniqueID's
+ for (int i=nmat;i--;) {
+ TGeoHMatrix* matI = (TGeoHMatrix*) matArr[i];
+ matI->SetUniqueID(0);
+ for (int j=i;j--;) {
+ TGeoHMatrix* matJ = (TGeoHMatrix*) matArr[j];
+ if (ConvIsJParentOfI(matI,matJ)) { matI->SetUniqueID(j+1); break; }
+ }
+ }
+}
+
+//_______________________________________________________________________________________
+Bool_t AliITSAlignMille2::ConvIsJParentOfI(const TGeoHMatrix* matI,const TGeoHMatrix* matJ) const
+{
+ // Used only for the deltas conversion from one geometry to another
+ // True if matJ is higher in hierarchy than
+ //
+ TString nmI = matI->GetTitle();
+ TString nmJ = matJ->GetTitle();
+ //
+ int nlrI = nmI.CountChar('/');
+ int nlrJ = nmJ.CountChar('/');
+ if (nlrJ>=nlrI) return kFALSE;
+ //
+ // special case of SPD sectors
+ if (nmI.BeginsWith("ITS/SPD1") && nmJ.BeginsWith("ITS/SPD0") && nlrJ==2) nmJ.ReplaceAll("SPD0","SPD1");
+ return (nmI.BeginsWith(nmJ)) ? kTRUE:kFALSE;
+ //
+}
+
+//_______________________________________________________________________________________
+AliAlignObjParams* AliITSAlignMille2::ConvFindDelta(const TClonesArray* arrDelta,const TString& algname) const
+{
+ // find the delta for given module
+ if (!arrDelta) return 0;
+ AliAlignObjParams* delta = 0;
+ int nDeltas = arrDelta->GetEntries();
+ for (int id=0;id<nDeltas;id++) {
+ delta = (AliAlignObjParams*)arrDelta->At(id);
+ if (algname==delta->GetSymName()) break;
+ delta = 0;
+ }
+ return delta;
+}