\r
#define CORHW_\r
\r
-AliAlignObjParams AliITSAlignMille2Module::fgTempAlignObj;\r
+\r
+const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1e-2;//1.E3;\r
\r
//-------------------------------------------------------------\r
AliITSAlignMille2Module::AliITSAlignMille2Module() : \r
TNamed(), \r
fNSensVol(0), \r
fIndex(-1), \r
+ fDetType(-1),\r
fVolumeID(0),\r
+ fNParTot(0),\r
+ fNParFree(0),\r
+ fParOffs(0),\r
fNProcPoints(0),\r
+ fParVals(0),\r
+ fParErrs(0),\r
+ fParCstr(0),\r
fSensVolIndex(0),\r
fSensVolVolumeID(0),\r
fMatrix(NULL),\r
fSensVolMatrix(NULL),\r
fSensVolModifMatrix(NULL),\r
- fParent(NULL)\r
+ fParent(NULL),\r
+ fChildren(0)\r
{ \r
/// void constructor \r
fMatrix = new TGeoHMatrix; \r
} \r
\r
//-------------------------------------------------------------\r
-AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index,UShort_t volid,char* symname,TGeoHMatrix *m,Int_t nsv,UShort_t *volidsv) : \r
+AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,\r
+ const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) : \r
TNamed(), \r
fNSensVol(0), \r
fIndex(-1), \r
+ fDetType(-1), \r
fVolumeID(0),\r
+ fNParTot(0),\r
+ fNParFree(0),\r
+ fParOffs(kMaxParGeom),\r
fNProcPoints(0),\r
+ fParVals(0),\r
+ fParErrs(0),\r
+ fParCstr(0),\r
fSensVolIndex(0),\r
fSensVolVolumeID(0), \r
fMatrix(NULL),\r
fSensVolMatrix(NULL),\r
fSensVolModifMatrix(NULL),\r
- fParent(NULL)\r
+ fParent(NULL),\r
+ fChildren(0)\r
{ \r
/// void constructor \r
fMatrix = new TGeoHMatrix; \r
fSensVolMatrix = new TGeoHMatrix; \r
fSensVolModifMatrix = new TGeoHMatrix; \r
fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
+ for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;\r
if (Set(index,volid,symname,m,nsv,volidsv)) {\r
AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");\r
}\r
+ AssignDetType();\r
} \r
\r
//-------------------------------------------------------------\r
AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) : \r
TNamed(), \r
fNSensVol(0), \r
- fIndex(-1), \r
+ fIndex(-1), \r
+ fDetType(-1),\r
fVolumeID(0),\r
+ fNParTot(0),\r
+ fNParFree(0),\r
+ fParOffs(kMaxParGeom),\r
fNProcPoints(0),\r
+ fParVals(0),\r
+ fParErrs(0),\r
+ fParCstr(0), \r
fSensVolIndex(0),\r
fSensVolVolumeID(0),\r
fMatrix(NULL),\r
fSensVolMatrix(NULL),\r
fSensVolModifMatrix(NULL),\r
- fParent(NULL)\r
+ fParent(NULL),\r
+ fChildren(0)\r
{ \r
/// simple constructor building a supermodule from a single sensitive volume \r
fMatrix = new TGeoHMatrix; \r
fSensVolIndex.Set(1);\r
fSensVolVolumeID.Set(1);\r
fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
+ for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;\r
//\r
fIndex = GetIndexFromVolumeID(volid); \r
if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded\r
SetName(AliGeomManager::SymName(volid));\r
fVolumeID = volid;\r
AddSensitiveVolume(volid);\r
+ SetSensorsProvided(kTRUE);\r
if (SensVolMatrix(volid, fMatrix))\r
AliInfo("Matrix not defined");\r
}\r
else {\r
AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");\r
}\r
+ AssignDetType();\r
} \r
\r
\r
AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :\r
TNamed(m),\r
fNSensVol(m.fNSensVol),\r
- fIndex(m.fIndex),\r
+ fIndex(m.fIndex), \r
+ fDetType(m.fDetType),\r
fVolumeID(m.fVolumeID),\r
+ fNParTot(m.fNParTot),\r
+ fNParFree(m.fNParFree),\r
+ fParOffs(m.fNParTot),\r
fNProcPoints(0),\r
+ fParVals(0),\r
+ fParErrs(0),\r
+ fParCstr(0), \r
fSensVolIndex(m.fSensVolIndex),\r
fSensVolVolumeID(m.fSensVolVolumeID),\r
fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r
fSensVolMatrix(new TGeoHMatrix),\r
fSensVolModifMatrix(new TGeoHMatrix),\r
- fParent(m.fParent)\r
+ fParent(m.fParent),\r
+ fChildren(0)\r
{\r
// Copy constructor\r
fSensVolIndex = m.fSensVolIndex;\r
fSensVolVolumeID = m.fSensVolVolumeID;\r
+ for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];\r
for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
+ if (fNParTot) {\r
+ fParVals = new Float_t[fNParTot];\r
+ fParErrs = new Float_t[fNParTot];\r
+ fParCstr = new Float_t[fNParTot];\r
+ for (int i=fNParTot;i--;) {\r
+ fParVals[i] = m.fParVals[i];\r
+ fParErrs[i] = m.fParErrs[i];\r
+ fParCstr[i] = m.fParCstr[i];\r
+ }\r
+ }\r
}\r
\r
//_____________________________________________________________________________\r
// operator =\r
//\r
if(this==&m) return *this;\r
- ((TNamed *)this)->operator=(m);\r
+ this->TNamed::operator=(m);\r
//\r
fNSensVol=m.fNSensVol;\r
fIndex=m.fIndex;\r
+ fDetType = m.fDetType;\r
fVolumeID=m.fVolumeID;\r
- for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
+ fNParTot = m.fNParTot;\r
+ fNParFree = m.fNParFree; \r
+ fNProcPoints = m.fNProcPoints; \r
+ delete[] fParVals; fParVals = 0;\r
+ delete[] fParErrs; fParErrs = 0;\r
+ delete[] fParCstr; fParCstr = 0;\r
+ //\r
+ if (fNParTot) {\r
+ fParVals = new Float_t[fNParTot];\r
+ fParErrs = new Float_t[fNParTot];\r
+ fParCstr = new Float_t[fNParTot];\r
+ for (int i=m.GetNParTot();i--;) {\r
+ fParVals[i] = m.fParVals[i];\r
+ fParErrs[i] = m.fParErrs[i];\r
+ fParCstr[i] = m.fParCstr[i];\r
+ }\r
+ }\r
+ //\r
+ fParOffs.Set(fNParTot);\r
+ for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];\r
+ for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];\r
if (fMatrix) delete fMatrix;\r
fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
+ if(fSensVolMatrix) delete fSensVolMatrix;\r
+ fSensVolMatrix = new TGeoHMatrix(*m.fSensVolMatrix);\r
+ if(fSensVolModifMatrix) delete fSensVolModifMatrix;\r
+ fSensVolModifMatrix = new TGeoHMatrix(*m.fSensVolModifMatrix);\r
fSensVolIndex = m.fSensVolIndex;\r
fSensVolVolumeID = m.fSensVolVolumeID;\r
fParent = m.fParent;\r
+ fChildren.Clear();\r
+ for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));\r
return *this;\r
}\r
\r
delete fMatrix; \r
delete fSensVolMatrix; \r
delete fSensVolModifMatrix; \r
+ delete[] fParVals;\r
+ delete[] fParErrs;\r
+ delete[] fParCstr;\r
+ fChildren.Clear();\r
} \r
\r
//-------------------------------------------------------------\r
-Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) \r
+Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname, \r
+ const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) \r
{\r
// initialize a custom supermodule\r
// index, volid, symname and matrix must be given\r
return 0;\r
}\r
\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)\r
+{\r
+ if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0; // fixed parameter\r
+ else if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained\r
+ else fParCstr[dof] = -cstr; // the parameter is free but constrained\r
+}\r
+\r
+//-------------------------------------------------------------\r
+Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid) \r
+{\r
+ // Does this volid correspond to sensor ?\r
+ AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);\r
+ if (layId>0 && layId<7) {\r
+ Int_t mId = Int_t(voluid & 0x7ff);\r
+ if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;\r
+ }\r
+ return kFALSE;\r
+}\r
+\r
//-------------------------------------------------------------\r
Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {\r
/// index from volume ID\r
if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r
//\r
// in principle, the correct size of fSensVol... arrays was set outside but check anyway\r
- if (fSensVolVolumeID.GetSize()<fNSensVol) {\r
+ if (fSensVolVolumeID.GetSize()<fNSensVol+1) {\r
fSensVolVolumeID.Set(fNSensVol+1);\r
fSensVolIndex.Set(fNSensVol+1);\r
}\r
}\r
\r
//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)\r
+TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)\r
{\r
// modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
// with a delta transform. applied to the supermodule matrix\r
ang[1]=delta[4]; // theta (Y)\r
ang[2]=delta[5]; // phi (Z)\r
//\r
- fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
- fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
+ static AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
+ tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
TGeoHMatrix hm;\r
- fgTempAlignObj.GetMatrix(hm);\r
+ tempAlignObj.GetMatrix(hm);\r
//printf("\n0: delta matrix\n");hm.Print();\r
\r
// 1) start setting fSensVolModif = fSensVol\r
}\r
\r
//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r
+AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
{\r
// calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
// of the mother volume. The misalignment is returned as AliAlignObjParams object\r
ang[1]=deltalocal[4]; // theta (Y)\r
ang[2]=deltalocal[5]; // phi (Z)\r
//\r
- fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
- fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
+ static AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
+ tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
//\r
- return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);\r
+ return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);\r
}\r
\r
//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r
+AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)\r
{\r
// return the misalignment of the sens. vol. 'voluid' corresponding with \r
// a misalignment 'a' in the mother volume\r
// << RS\r
\r
// reset align object (may not be needed...)\r
- fgTempAlignObj.SetVolUID(0);\r
- fgTempAlignObj.SetSymName("");\r
- fgTempAlignObj.SetTranslation(0,0,0);\r
- fgTempAlignObj.SetRotation(0,0,0);\r
+ static AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetVolUID(0);\r
+ tempAlignObj.SetSymName("");\r
+ tempAlignObj.SetTranslation(0,0,0);\r
+ tempAlignObj.SetRotation(0,0,0);\r
//\r
// >> RS\r
#ifdef CORHW_\r
}\r
#endif\r
// << RS\r
- if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
- fgTempAlignObj.SetVolUID(voluid);\r
- fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
+ if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
+ tempAlignObj.SetVolUID(voluid);\r
+ tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
//\r
- return &fgTempAlignObj;\r
+ return &tempAlignObj;\r
}\r
\r
// >> RS\r
//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
+AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
{\r
// calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
// of the mother volume. The misalignment is returned as AliAlignObjParams object including\r
ang[2]=deltalocal[5]; // phi (Z)\r
\r
// reset align object (may not be needed...)\r
- fgTempAlignObj.SetVolUID(0);\r
- fgTempAlignObj.SetSymName("");\r
- fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
- fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
+ static AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetVolUID(0);\r
+ tempAlignObj.SetSymName("");\r
+ tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
+ tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
\r
// Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
\r
// prepare the Delta matrix Dg\r
TGeoHMatrix dg;\r
- fgTempAlignObj.GetMatrix(dg);\r
+ tempAlignObj.GetMatrix(dg);\r
//dg.Print();\r
\r
// 1) start setting fSensVolModif = Gsv\r
//printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
\r
// reset align object (may not be needed...)\r
- fgTempAlignObj.SetVolUID(0);\r
- fgTempAlignObj.SetSymName("");\r
- fgTempAlignObj.SetTranslation(0,0,0);\r
- fgTempAlignObj.SetRotation(0,0,0);\r
+ tempAlignObj.SetVolUID(0);\r
+ tempAlignObj.SetSymName("");\r
+ tempAlignObj.SetTranslation(0,0,0);\r
+ tempAlignObj.SetRotation(0,0,0);\r
\r
#ifdef CORHW_\r
// correction for SPD y-shift\r
fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
}\r
#endif\r
- if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
- fgTempAlignObj.SetVolUID(voluid);\r
- fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
+ if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
+ tempAlignObj.SetVolUID(voluid);\r
+ tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
\r
\r
- //fgTempAlignObj.Print("");\r
+ //tempAlignObj.Print("");\r
\r
- return &fgTempAlignObj;\r
+ return &tempAlignObj;\r
}\r
//-------------------------------------------------------------\r
\r
//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
+AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
{\r
// calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
// of the mother volume. The misalignment is returned as AliAlignObjParams object\r
ang[2]=deltalocal[5]; // phi (Z)\r
\r
// reset align object (may not be needed...)\r
- fgTempAlignObj.SetTranslation(0,0,0);\r
- fgTempAlignObj.SetRotation(0,0,0);\r
+ static AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(0,0,0);\r
+ tempAlignObj.SetRotation(0,0,0);\r
\r
- fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
- fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
+ tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
+ tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
\r
// Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
\r
// prepare the Delta matrix Dg\r
TGeoHMatrix dg;\r
- fgTempAlignObj.GetMatrix(dg);\r
+ tempAlignObj.GetMatrix(dg);\r
//dg.Print();\r
\r
dg.MultiplyLeft( fMatrix );\r
dg.Multiply( &fMatrix->Inverse() );\r
\r
// reset align object (may not be needed...)\r
- fgTempAlignObj.SetTranslation(0,0,0);\r
- fgTempAlignObj.SetRotation(0,0,0);\r
+ tempAlignObj.SetTranslation(0,0,0);\r
+ tempAlignObj.SetRotation(0,0,0);\r
\r
- fgTempAlignObj.SetVolUID(voluid);\r
- fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
+ tempAlignObj.SetVolUID(voluid);\r
+ tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
\r
- if (!fgTempAlignObj.SetMatrix(dg)) return NULL;\r
+ if (!tempAlignObj.SetMatrix(dg)) return NULL;\r
\r
- //fgTempAlignObj.Print("");\r
+ //tempAlignObj.Print("");\r
\r
- return &fgTempAlignObj;\r
+ return &tempAlignObj;\r
}\r
// << RS\r
\r
Int_t idx=GetIndexFromVolumeID(volid);\r
if (idx<0) return -1;\r
TGeoHMatrix mo;\r
- if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));\r
+ if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;\r
(*m)=mo;\r
-\r
+ //\r
#ifdef CORHW_\r
// SPD y-shift by 81 mu\r
if (volid<5000) { \r
//-------------------------------------------------------------\r
void AliITSAlignMille2Module::Print(Option_t*) const \r
{\r
- ///\r
+ // print data\r
+ //\r
+ const char* typeName[] = {"SPD","SDD","SSD"};\r
printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
- printf("symname : %s\n",GetName());\r
- printf("parent : %s\n",fParent ? fParent->GetName() : "N/A");\r
- printf("volumeID : %4d | index : %4d\n",fVolumeID,fIndex);\r
- printf("Factors : X=%.2f Y=%.2f Z=%.2f | DOF: Tx:%d Ty:%d Tz:%d Phi:%d Theta:%d Psi:%d\n",\r
+ printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);\r
+ printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());\r
+ printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,\r
+ GeomParamsGlobal() ? "Global":"Local");\r
+ printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"\r
+ "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",\r
fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],\r
- IsFreeDOF(AliITSAlignMille2::kDOFTX),IsFreeDOF(AliITSAlignMille2::kDOFTY),\r
- IsFreeDOF(AliITSAlignMille2::kDOFTZ),IsFreeDOF(AliITSAlignMille2::kDOFPH),\r
- IsFreeDOF(AliITSAlignMille2::kDOFTH),IsFreeDOF(AliITSAlignMille2::kDOFPS));\r
+ IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),\r
+ IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),\r
+ IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));\r
+ if (IsSDD()) {\r
+ printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),\r
+ IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));\r
+ if (IsVDriftLRSame()) printf("(dVL=dVR)");\r
+ }\r
+ printf("\n");\r
fMatrix->Print();\r
printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r
for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r
//-------------------------------------------------------------\r
Bool_t AliITSAlignMille2Module::IsAlignable() const\r
{\r
+ // it it alignable?\r
TGeoManager* geoManager = AliGeomManager::GetGeometry();\r
if (!geoManager) {\r
AliInfo("Couldn't initialize geometry");\r
mat = *fMatrix;\r
if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r
}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::AssignDetType()\r
+{\r
+ // assign the detector type\r
+ TString tp = GetName();\r
+ if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;\r
+ else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;\r
+ else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;\r
+ else fDetType = -1;\r
+ fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;\r
+ fNParFree = 0;\r
+ fParVals = new Float_t[fNParTot];\r
+ fParErrs = new Float_t[fNParTot]; \r
+ fParCstr = new Float_t[fNParTot]; \r
+ if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);\r
+ for (int i=fNParTot;i--;) {\r
+ fParVals[i] = fParErrs[i] = 0.; \r
+ fParCstr[i] = 0.;\r
+ fParOffs[i] = -1;\r
+ }\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::EvaluateDOF()\r
+{\r
+ // count d.o.f.\r
+ fNParFree = 0;\r
+ for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)\r
+{\r
+ // return global parameters of the sensor volid\r
+ for (int i=3;i--;) t[i] = r[i] = 0.;\r
+ if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetMatrix(*fSensVolMatrix);\r
+ tempAlignObj.GetPars(t,r);\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)\r
+{\r
+ // return parameters of the sensor volid in the current module\r
+ for (int i=3;i--;) t[i] = r[i] = 0.;\r
+ if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
+ fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
+ AliAlignObjParams tempAlignObj; \r
+ tempAlignObj.SetMatrix(*fSensVolMatrix);\r
+ tempAlignObj.GetPars(t,r);\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)\r
+{\r
+ // return global parameters of the sensor volid modified by the localDelta params\r
+ for (int i=3;i--;) t[i] = r[i] = 0.;\r
+ if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
+ tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
+ //\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
+ fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
+ tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
+ tempAlignObj.GetPars(t,r); // obtain global params\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)\r
+{\r
+ // return parameters of the sensor volid (modified by the localDelta params) in the current volume\r
+ for (int i=3;i--;) t[i] = r[i] = 0.;\r
+ if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
+ tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
+ //\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
+ fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
+ fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume\r
+ tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
+ tempAlignObj.GetPars(t,r); // obtain params\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)\r
+{\r
+ // set parameters\r
+ for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)\r
+{\r
+ // recompute parameters from local to global frame\r
+ //\r
+ // is there anything to do?\r
+ if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
+ //\r
+ // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
+ // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
+ // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
+ // of the modules array.\r
+ //\r
+ // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1 \r
+ //\r
+ *fSensVolMatrix = *fMatrix; // current global matrix\r
+ AliAlignObjParams tempAlignObj;\r
+ AliITSAlignMille2Module* parent = GetParent();\r
+ while (parent) {\r
+ if (parent->GeomParamsGlobal()) {\r
+ AliError("Cannot convert params to Global when the parents are already Global\n");\r
+ for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
+ return;\r
+ }\r
+ fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix\r
+ Float_t *parpar = parent->GetParVals();\r
+ tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
+ tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
+ fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);\r
+ fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications\r
+ parent = parent->GetParent();\r
+ }\r
+ //\r
+ tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
+ tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix\r
+ fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );\r
+ fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );\r
+ tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix\r
+ tempAlignObj.GetPars(pars,pars+3);\r
+ //\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)\r
+{\r
+ // recompute parameters from global to local frame\r
+ //\r
+ // is there anything to do?\r
+ if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
+ //\r
+ // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
+ // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
+ // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
+ // of the modules array.\r
+ //\r
+ // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)\r
+ //\r
+ AliITSAlignMille2Module* parent = GetParent();\r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(0.,0.,0.);\r
+ tempAlignObj.SetRotation(0.,0.,0.);\r
+ tempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix\r
+ //\r
+ while (parent) { // accumulate the product of parents global modifications\r
+ if (!parent->GeomParamsGlobal()) {\r
+ AliError("Cannot convert params to Local when the parents are already Local\n");\r
+ for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
+ return;\r
+ }\r
+ Float_t *parpar = parent->GetParVals();\r
+ tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
+ tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
+ fSensVolMatrix->Multiply(fSensVolModifMatrix); \r
+ parent = parent->GetParent();\r
+ }\r
+ // global matrix after parents modifications\r
+ fSensVolMatrix->Multiply(fMatrix);\r
+ //\r
+ tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
+ tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix\r
+ fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );\r
+ fSensVolModifMatrix->Multiply( fSensVolMatrix );\r
+ tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix\r
+ tempAlignObj.GetPars(pars,pars+3);\r
+ //\r
+}\r
+\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)\r
+{\r
+ // calculate jacobian of the global position vs Parameters (dPos/dParam) \r
+ // for the point in the sensor sensVol\r
+ const double kDel = 0.01;\r
+ double pos0[3],pos1[3],pos2[3],pos3[3];\r
+ double delta[kMaxParGeom];\r
+ //\r
+ for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;\r
+ //\r
+ for (int ip=kMaxParGeom;ip--;) {\r
+ //\r
+ delta[ip] -= kDel;\r
+ GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0); \r
+ delta[ip] += kDel/2;\r
+ GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1); \r
+ delta[ip] += kDel;\r
+ GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2); \r
+ delta[ip] += kDel/2;\r
+ GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3); \r
+ //\r
+ delta[ip] = 0;\r
+ double *curd = deriv + ip*3;\r
+ for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;\r
+ }\r
+ //\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)\r
+{\r
+ // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]\r
+ Double_t lpar[kMaxParGeom];\r
+ for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
+ // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
+ Double_t par1[kMaxParGeom]; // f(x-h)\r
+ Double_t par2[kMaxParGeom]; // f(x-h/2)\r
+ Double_t par3[kMaxParGeom]; // f(x+h/2)\r
+ Double_t par4[kMaxParGeom]; // f(x+h)\r
+ //\r
+ const Double_t dpar = 1e-3;\r
+ //\r
+ // first values\r
+ lpar[idx] -= dpar;\r
+ GetGlobalParams(lpar,lpar+3, par1,par1+3);\r
+ //\r
+ // second values\r
+ lpar[idx] += dpar/2;\r
+ GetGlobalParams(lpar,lpar+3, par2,par2+3);\r
+ //\r
+ // third values\r
+ lpar[idx] += dpar;\r
+ GetGlobalParams(lpar,lpar+3, par3,par3+3);\r
+ //\r
+ // fourth values\r
+ lpar[idx] += dpar/2;\r
+ GetGlobalParams(lpar,lpar+3, par4,par4+3);\r
+ //\r
+ Double_t h2 = 1./(2.*dpar);\r
+ for (int i=kMaxParGeom;i--;) {\r
+ Double_t d0 = par4[i]-par1[i];\r
+ Double_t d2 = 2.*(par3[i]-par2[i]);\r
+ deriv[i] = h2*(4*d2 - d0)/3.;\r
+ if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;\r
+ }\r
+ //\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)\r
+{\r
+ // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]\r
+ Double_t gpar[kMaxParGeom];\r
+ for (int i=kMaxParGeom;i--;) gpar[i] = 0.;\r
+ // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
+ Double_t par1[kMaxParGeom]; // f(x-h)\r
+ Double_t par2[kMaxParGeom]; // f(x-h/2)\r
+ Double_t par3[kMaxParGeom]; // f(x+h/2)\r
+ Double_t par4[kMaxParGeom]; // f(x+h)\r
+ //\r
+ const Double_t dpar = 1e-3;\r
+ //\r
+ for (int ig=kMaxParGeom;ig--;) {\r
+ // first values\r
+ gpar[ig] -= dpar;\r
+ GetLocalParams(gpar,gpar+3, par1,par1+3);\r
+ //\r
+ // second values\r
+ gpar[ig] += dpar/2;\r
+ GetLocalParams(gpar,gpar+3, par2,par2+3);\r
+ //\r
+ // third values\r
+ gpar[ig] += dpar;\r
+ GetLocalParams(gpar,gpar+3, par3,par3+3);\r
+ //\r
+ // fourth values\r
+ gpar[ig] += dpar/2;\r
+ GetLocalParams(gpar,gpar+3, par4,par4+3);\r
+ //\r
+ Double_t h2 = 1./(2.*dpar);\r
+ for (int i=kMaxParGeom;i--;) {\r
+ Double_t d0 = par4[i]-par1[i];\r
+ Double_t d2 = 2.*(par3[i]-par2[i]);\r
+ int idig = i*kMaxParGeom + ig;\r
+ deriv[idig] = h2*(4*d2 - d0)/3.;\r
+ if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;\r
+ }\r
+ }\r
+ //\r
+}\r
+\r
+//________________________________________________________________________________________________________\r
+void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)\r
+{\r
+ /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx\r
+ //\r
+ Double_t lpar[kMaxParGeom];\r
+ for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
+ // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
+ Double_t par1[kMaxParGeom]; // f(x-h)\r
+ Double_t par2[kMaxParGeom]; // f(x-h/2)\r
+ Double_t par3[kMaxParGeom]; // f(x+h/2)\r
+ Double_t par4[kMaxParGeom]; // f(x+h)\r
+ //\r
+ const Double_t dpar = 1e-3;\r
+ //\r
+ // first values\r
+ lpar[paridx] -= dpar;\r
+ GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
+ //\r
+ // second values\r
+ lpar[paridx] += dpar/2;\r
+ GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
+ //\r
+ // third values\r
+ lpar[paridx] += dpar;\r
+ GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
+ //\r
+ // fourth values\r
+ lpar[paridx] += dpar/2;\r
+ GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
+ //\r
+ Double_t h2 = 1./(2.*dpar);\r
+ for (int i=kMaxParGeom;i--;) {\r
+ Double_t d0 = par4[i]-par1[i];\r
+ Double_t d2 = 2.*(par3[i]-par2[i]);\r
+ derivative[i] = h2*(4*d2 - d0)/3.;\r
+ if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
+ }\r
+ //\r
+}\r
+\r
+//________________________________________________________________________________________________________\r
+void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative) \r
+{\r
+ /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx\r
+ //\r
+ Double_t lpar[kMaxParGeom];\r
+ for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
+ // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
+ Double_t par1[kMaxParGeom]; // f(x-h)\r
+ Double_t par2[kMaxParGeom]; // f(x-h/2)\r
+ Double_t par3[kMaxParGeom]; // f(x+h/2)\r
+ Double_t par4[kMaxParGeom]; // f(x+h)\r
+ //\r
+ const Double_t dpar = 1e-3;\r
+ //\r
+ // first values\r
+ lpar[paridx] -= dpar;\r
+ GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
+ //\r
+ // second values\r
+ lpar[paridx] += dpar/2;\r
+ GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
+ //\r
+ // third values\r
+ lpar[paridx] += dpar;\r
+ GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
+ //\r
+ // fourth values\r
+ lpar[paridx] += dpar/2;\r
+ GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
+ //\r
+ Double_t h2 = 1./(2.*dpar);\r
+ for (int i=kMaxParGeom;i--;) {\r
+ Double_t d0 = par4[i]-par1[i];\r
+ Double_t d2 = 2.*(par3[i]-par2[i]);\r
+ derivative[i] = h2*(4*d2 - d0)/3.;\r
+ if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
+ }\r
+ //\r
+}\r
+\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const\r
+{\r
+ // global parameters of the module\r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetMatrix( *fMatrix );\r
+ tempAlignObj.GetPars(t,r);\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)\r
+{\r
+ // global parameters of the module after the modification by local loct,locr\r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
+ tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
+ tempAlignObj.GetMatrix(*fSensVolModifMatrix); \r
+ *fSensVolMatrix = *fMatrix;\r
+ fSensVolMatrix->Multiply(fSensVolModifMatrix);\r
+ tempAlignObj.SetMatrix(*fSensVolMatrix);\r
+ tempAlignObj.GetPars(t,r);\r
+}\r
+\r
+//-------------------------------------------------------------\r
+void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)\r
+{\r
+ // obtain local delta parameters from global delta params\r
+ AliAlignObjParams tempAlignObj;\r
+ tempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);\r
+ tempAlignObj.SetRotation(glor[0],glor[1],glor[2]);\r
+ tempAlignObj.GetMatrix(*fSensVolMatrix); \r
+ fSensVolMatrix->Multiply( fMatrix );\r
+ fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
+ tempAlignObj.SetMatrix(*fSensVolMatrix);\r
+ tempAlignObj.GetPars(t,r);\r
+}\r