X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STEER%2FAliAlignObj.cxx;h=669a950f041de56782433d7d1b7e4367acc63d59;hb=1fb480e4317e2c7e3a508360e3f3134f8e61cb88;hp=7d3a9f08570a1e8008403d108599a7b322823652;hpb=5c03260fb98a6fd3b8c441fc97bbbf038a530013;p=u%2Fmrichter%2FAliRoot.git diff --git a/STEER/AliAlignObj.cxx b/STEER/AliAlignObj.cxx index 7d3a9f08570..669a950f041 100644 --- a/STEER/AliAlignObj.cxx +++ b/STEER/AliAlignObj.cxx @@ -19,78 +19,30 @@ // Implementation of the alignment object class, holding the alignment // constants for a single volume, through the abstract class AliAlignObj. // From it two derived concrete representation of alignment object class -// (AliAlignObjAngles, AliAlignObjMatrix) are derived in separate files. +// (AliAlignObjParams, AliAlignObjMatrix) are derived in separate files. //----------------------------------------------------------------- + #include +#include #include +#include #include -#include "TObjString.h" #include "AliAlignObj.h" #include "AliTrackPointArray.h" #include "AliLog.h" -#include "AliAlignObjAngles.h" ClassImp(AliAlignObj) -Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = { - 80, 160, // ITS SPD first and second layer - 84, 176, // ITS SDD first and second layer - 748, 950, // ITS SSD first and second layer - 36, 36, // TPC inner and outer chambers - 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers - 1638, // TOF - 1, 1, // PHOS ?? - 7, // HMPID ?? - 1 // MUON ?? -}; - -const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = { - "ITS inner pixels layer", "ITS outer pixels layer", - "ITS inner drifts layer", "ITS outer drifts layer", - "ITS inner strips layer", "ITS outer strips layer", - "TPC inner chambers layer", "TPC outer chambers layer", - "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3", - "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6", - "TOF layer", - "?","?", - "HMPID layer", - "?" -}; - -TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = { - 0x0,0x0, - 0x0,0x0, - 0x0,0x0, - 0x0,0x0, - 0x0,0x0,0x0, - 0x0,0x0,0x0, - 0x0, - 0x0,0x0, - 0x0, - 0x0 -}; - -AliAlignObj** AliAlignObj::fgAlignObjs[kLastLayer - kFirstLayer] = { - 0x0,0x0, - 0x0,0x0, - 0x0,0x0, - 0x0,0x0, - 0x0,0x0,0x0, - 0x0,0x0,0x0, - 0x0, - 0x0,0x0, - 0x0, - 0x0 -}; - //_____________________________________________________________________________ AliAlignObj::AliAlignObj(): + TObject(), fVolPath(), fVolUID(0) { // default constructor - InitSymNames(); + for(Int_t i=0; i<6; i++) fDiag[i]=-999.; + for(Int_t i=0; i<15; i++) fODia[i]=-999.; } //_____________________________________________________________________________ @@ -101,6 +53,19 @@ AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid) : { // standard constructor // + for(Int_t i=0; i<6; i++) fDiag[i]=-999.; + for(Int_t i=0; i<15; i++) fODia[i]=-999.; +} + +//_____________________________________________________________________________ +AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid, Double_t* cmat) : + TObject(), + fVolPath(symname), + fVolUID(voluid) +{ + // standard constructor + // + SetCorrMatrix(cmat); } //_____________________________________________________________________________ @@ -110,6 +75,8 @@ AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) : fVolUID(theAlignObj.GetVolUID()) { //copy constructor + for(Int_t i=0; i<6; i++) fDiag[i]=theAlignObj.fDiag[i]; + for(Int_t i=0; i<15; i++) fODia[i]=theAlignObj.fODia[i]; } //_____________________________________________________________________________ @@ -119,6 +86,8 @@ AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj) if(this==&theAlignObj) return *this; fVolPath = theAlignObj.GetSymName(); fVolUID = theAlignObj.GetVolUID(); + for(Int_t i=0; i<6; i++) fDiag[i]=theAlignObj.fDiag[i]; + for(Int_t i=0; i<15; i++) fODia[i]=theAlignObj.fODia[i]; return *this; } @@ -134,6 +103,11 @@ AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj) theAlignObj.GetMatrix(m2); m1.MultiplyLeft(&m2); SetMatrix(m1); + // temporary solution: the covariance matrix of the resulting combined object + // is set equal to the covariance matrix of the right operand + // (not to be used for combining alignment objects for different levels) + for(Int_t i=0; i<6; i++) fDiag[i] = theAlignObj.fDiag[i]; + for(Int_t i=0; i<15; i++) fODia[i] = theAlignObj.fODia[i]; return *this; } @@ -144,18 +118,18 @@ AliAlignObj::~AliAlignObj() } //_____________________________________________________________________________ -void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId) +void AliAlignObj::SetVolUID(AliGeomManager::ELayerID detId, Int_t modId) { // From detector name and module number (according to detector numbering) // build fVolUID, unique numerical identity of that volume inside ALICE // fVolUID is 16 bits, first 5 reserved for detID (32 possible values), // remaining 11 for module ID inside det (2048 possible values). // - fVolUID = LayerToVolUID(detId,modId); + fVolUID = AliGeomManager::LayerToVolUID(detId,modId); } //_____________________________________________________________________________ -void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const +void AliAlignObj::GetVolUID(AliGeomManager::ELayerID &layerId, Int_t &modId) const { // From the fVolUID, unique numerical identity of that volume inside ALICE, // (voluid is 16 bits, first 5 reserved for layerID (32 possible values), @@ -164,7 +138,7 @@ void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const // belongs and sets the argument modId to the identity of that volume // internally to the layer. // - layerId = VolUIDToLayer(fVolUID,modId); + layerId = AliGeomManager::VolUIDToLayer(fVolUID,modId); } //_____________________________________________________________________________ @@ -182,7 +156,7 @@ Int_t AliAlignObj::GetLevel() const // slashes in the corresponding volume path // if(!gGeoManager){ - AliWarning("gGeoManager doesn't exist or it is still opened: unable to return meaningful level value."); + AliWarning("gGeoManager doesn't exist or it is still open: unable to return meaningful level value."); return (-1); } const char* symname = GetSymName(); @@ -194,9 +168,9 @@ Int_t AliAlignObj::GetLevel() const path = symname; } - TString path_str = path; - if(path_str[0]!='/') path_str.Prepend('/'); - return path_str.CountChar('/'); + TString pathStr = path; + if(pathStr[0]!='/') pathStr.Prepend('/'); + return pathStr.CountChar('/'); } //_____________________________________________________________________________ @@ -216,6 +190,311 @@ Int_t AliAlignObj::Compare(const TObject *obj) const return ((level > level2) ? 1 : -1); } +//______________________________________________________________________________ +void AliAlignObj::GetCovMatrix(Double_t *cmat) const +{ + // Fills the cmat argument with the coefficients of the external cov matrix (21 elements) + // calculating them from the correlation matrix data member + // + + for(Int_t i=0; i<6; ++i) { + // Off diagonal elements + for(Int_t j=0; j= 0. && fDiag[i] >= 0.) ? fODia[(i-1)*i/2+j]*fDiag[j]*fDiag[i]: -999.; + } + + // Diagonal elements + cmat[i*(i+1)/2+i] = (fDiag[i] >= 0.) ? fDiag[i]*fDiag[i] : -999.; + } + + return; +} + +//______________________________________________________________________________ +void AliAlignObj::GetCovMatrix(TMatrixDSym& mcov) const +{ + // Fills the matrix m passed as argument as the covariance matrix calculated + // from the coefficients of the reduced covariance matrix data members + // + + for(Int_t i=0; i<6; ++i) { + // Off diagonal elements + for(Int_t j=0; j= 0. && fDiag[i] >= 0.) ? fODia[(i-1)*i/2+j]*fDiag[j]*fDiag[i]: -999.; + } + + // Diagonal elements + mcov(i,i) = (fDiag[i] >= 0.) ? fDiag[i]*fDiag[i] : -999.; + } + +} + +//______________________________________________________________________________ +Bool_t AliAlignObj::GetLocalCovMatrix(TMatrixDSym& lCov) const +{ + // Calculates the covariance matrix (6x6) associated to the six parameters + // defining the current alignment in the global coordinates system (and sets + // in the internal data members) from the covariance matrix (6x6) for the six + // parameters defining the alignment transformation in the local coordinates + // system, passed as an argument. + // + TMatrixD mJ(6,6);// the jacobian of the transformation from local to global parameters + if(!GetJacobian(mJ)) return kFALSE; + + TMatrixDSym gCov(6); + GetCovMatrix(gCov); + + // Compute the local covariance matrix lcov = mJ^T gcov mJ + TMatrixD gcovJ(gCov,TMatrixD::kMult,mJ); + TMatrixD lCovM(mJ,TMatrixD::kTransposeMult,gcovJ); + // To be done: somehow check that lCovM is close enough to be symmetric + for(Int_t i=0; i<6; i++) + { + lCov(i,i) = lCovM(i,i); + for(Int_t j=i+1; j<6; j++) + { + lCov(i,j)=lCovM(i,j); + lCov(j,i)=lCovM(i,j); + } + } + + return kTRUE; + +} + +//______________________________________________________________________________ +Bool_t AliAlignObj::GetLocalCovMatrix(Double_t *lCov) const +{ + // Calculates the covariance matrix (6x6) associated to the six parameters + // defining the current alignment in the global coordinates system (and sets + // in the internal data members) from the covariance matrix (6x6) for the six + // parameters defining the alignment transformation in the local coordinates + // system, passed as an argument. + // + TMatrixDSym lCovMatrix(6); + GetLocalCovMatrix(lCovMatrix); + + Int_t k=0; + for(Int_t i=0; i<6; i++) + for(Int_t j=i; j<6; j++) + { + lCov[k++] = lCovMatrix(i,j); + } + + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t AliAlignObj::GetJacobian(TMatrixD& mJ) const +{ + // Compute the jacobian J of the transformation of the six local to the six global delta parameters + // + // R00 R01 R02 | (R01Rk2 - R02Rk1)Tk (R02Rk0 - R00Rk2)Tk (R00Rk1 - R01Rk0)Tk + // R00 R01 R02 | (R11Rk2 - R12Rk1)Tk (R12Rk0 - R10Rk2)Tk (R10Rk1 - R11Rk0)Tk + // R00 R01 R02 | (R21Rk2 - R22Rk1)Tk (R22Rk0 - R20Rk2)Tk (R20Rk1 - R21Rk0)Tk + // - - - - - - - - - - - - - - - - - - - - - - - + // 0 0 0 | R11R22 - R12R21 R12R20 - R10R22 R10R21 - R11R20 + // 0 0 0 | R21R02 - R22R01 R22R00 - R20R02 R20R01 - R21R00 + // 0 0 0 | R01R12 - R02R11 R02R10 - R00R12 R00R11 - R01R10 + // + if (!gGeoManager || !gGeoManager->IsClosed()) { + AliError("Can't compute the global covariance matrix from the local one without an open geometry!"); + return kFALSE; + } + + const char* symname = GetSymName(); + TGeoPhysicalNode* node; + TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); + if(pne){ + if(!pne->GetPhysicalNode()){ + node = gGeoManager->MakeAlignablePN(pne); + }else{ + node = pne->GetPhysicalNode(); + } + }else{ + AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); + node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); + } + + if (!node) { + AliError(Form("Volume name or path %s not valid!",symname)); + return kFALSE; + } + + TGeoHMatrix gm; //global matrix + gm = *node->GetMatrix(); + Double_t *tr = gm.GetTranslation(); + Double_t *rot = gm.GetRotationMatrix(); + + TGeoHMatrix m; // global delta transformation matrix + GetMatrix(m); + // We should probably check that it's sufficinetly close to identity + // if it's not return because the "small angles" approximation cannot hold + + // 3x3 upper left part (global shifts derived w.r.t. local shifts) + for(Int_t i=0; i<3; i++) + { + for(Int_t j=0; j<3; j++) + { + mJ(i,j) = rot[i+3*j]; + } + } + + // 3x3 lower left part (global angles derived w.r.t. local shifts) + for(Int_t i=0; i<3; i++) + { + for(Int_t j=0; j<3; j++) + { + mJ(i+3,j) = 0.; + } + } + + // 3x3 upper right part (global shifts derived w.r.t. local angles) + for(Int_t i=0; i<3; i++) + { + for(Int_t j=0; j<3; j++) + { + Double_t mEl = 0.; + Int_t b = (j+1)%3; + Int_t d = (j+2)%3; + for(Int_t k=0; k<3; k++) + { + mEl += (rot[3*i+b]*rot[3*k+d])*tr[k]-(rot[3*i+d]*rot[3*k+b])*tr[k]; + } + mJ(i,j+3) = mEl; + } + } + + // 3x3 lower right part (global angles derived w.r.t. local angles) + for(Int_t i=0; i<3; i++) + for(Int_t j=0; j<3; j++) + { + Int_t a = (i+1)%3; + Int_t b = (j+1)%3; + Int_t c = (i+2)%3; + Int_t d = (j+2)%3; + mJ(i+3,j+3) = rot[3*a+b]*rot[3*c+d]-rot[3*a+d]*rot[3*c+b]; + } + + return kTRUE; + +} + +//______________________________________________________________________________ +Bool_t AliAlignObj::SetFromLocalCov(TMatrixDSym& lCov) +{ + // Calculates the covariance matrix (6x6) associated to the six parameters + // defining the current alignment in the global coordinates system (and sets + // in the internal data members) from the covariance matrix (6x6) for the six + // parameters defining the alignment transformation in the local coordinates + // system, passed as an argument. + // + TMatrixD mJ(6,6);// the jacobian of the transformation from local to global parameters + if(!GetJacobian(mJ)) return kFALSE; + + // Compute the global covariance matrix gcov = mJ lcov mJ' + TMatrixD trJ(TMatrixD::kTransposed, mJ); + TMatrixD lcovTrJ(lCov,TMatrixD::kMult,trJ); + TMatrixD gCovM(mJ,TMatrixD::kMult,lcovTrJ); + // To be done: somehow check that gCovM is close enough to be symmetric + TMatrixDSym gCov(6); + for(Int_t i=0; i<6; i++) + { + gCov(i,i) = gCovM(i,i); + for(Int_t j=i+1; j<6; j++) + { + gCov(i,j)=gCovM(i,j); + gCov(j,i)=gCovM(i,j); + } + } + SetCorrMatrix(gCov); + + return kTRUE; + +} + +//______________________________________________________________________________ +Bool_t AliAlignObj::SetFromLocalCov(Double_t *lCov) +{ + // Calculates the covariance matrix (6x6) associated to the six parameters + // defining the current alignment in the global coordinates system, and sets + // in the internal data members, from the 21 coefficients, passed as argument, + // of the covariance matrix (6x6) for the six parameters defining the + // alignment transformation in the local coordinates system. + // + TMatrixDSym lCovMatrix(6); + + Int_t k=0; + for(Int_t i=0; i<6; i++) + for(Int_t j=i; j<6; j++) + { + lCovMatrix(i,j) = lCov[k++]; + if(j!=i) lCovMatrix(j,i) = lCovMatrix(i,j); + } + + return SetFromLocalCov(lCovMatrix); + +} + + +//______________________________________________________________________________ +void AliAlignObj::SetCorrMatrix(Double_t *cmat) +{ + // Sets the correlation matrix data member from the coefficients of the external covariance + // matrix (21 elements passed as argument). + // + if(cmat) { + + // Diagonal elements first + for(Int_t i=0; i<6; ++i) { + fDiag[i] = (cmat[i*(i+1)/2+i] >= 0.) ? TMath::Sqrt(cmat[i*(i+1)/2+i]) : -999.; + } + + // ... then the ones off diagonal + for(Int_t i=0; i<6; ++i) + // Off diagonal elements + for(Int_t j=0; j 0. && fDiag[j] > 0.) ? cmat[i*(i+1)/2+j]/(fDiag[j]*fDiag[i]) : 0.; // check for division by zero (due to diagonal element of 0) and for fDiag != -999. (due to negative input diagonal element). + if (fODia[(i-1)*i/2+j]>1.) fODia[(i-1)*i/2+j] = 1.; // check upper boundary + if (fODia[(i-1)*i/2+j]<-1.) fODia[(i-1)*i/2+j] = -1.; // check lower boundary + } + } else { + for(Int_t i=0; i< 6; ++i) fDiag[i]=-999.; + for(Int_t i=0; i< 6*(6-1)/2; ++i) fODia[i]=0.; + } + + return; +} + +//______________________________________________________________________________ +void AliAlignObj::SetCorrMatrix(TMatrixDSym& mcov) +{ + // Sets the correlation matrix data member from the covariance matrix mcov passed + // passed as argument. + // + if(mcov.IsValid()) { + + // Diagonal elements first + for(Int_t i=0; i<6; ++i) { + fDiag[i] = (mcov(i,i) >= 0.) ? TMath::Sqrt(mcov(i,i)) : -999.; + } + + // ... then the ones off diagonal + for(Int_t i=0; i<6; ++i) + // Off diagonal elements + for(Int_t j=0; j 0. && fDiag[j] > 0.) ? mcov(i,j)/(fDiag[j]*fDiag[i]) : 0.; // check for division by zero (due to diagonal element of 0) and for fDiag != -999. (due to negative input diagonal element). + if (fODia[(i-1)*i/2+j]>1.) fODia[(i-1)*i/2+j] = 1.; // check upper boundary + if (fODia[(i-1)*i/2+j]<-1.) fODia[(i-1)*i/2+j] = -1.; // check lower boundary + } + } else { + for(Int_t i=0; i< 6; ++i) fDiag[i]=-999.; + for(Int_t i=0; i< 6*(6-1)/2; ++i) fODia[i]=0.; + } + + return; +} + //_____________________________________________________________________________ void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const { @@ -261,12 +540,12 @@ Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const } //______________________________________________________________________________ -void AliAlignObj::Transform(AliTrackPoint &p) const +void AliAlignObj::Transform(AliTrackPoint &p, Bool_t copycov) const { // The method transforms the space-point coordinates using the // transformation matrix provided by the AliAlignObj - // The covariance matrix is not affected since we assume - // that the transformations are sufficiently small + // In case the copycov flag is set to kTRUE, the covariance matrix + // of the alignment object is copied into the space-point // if (fVolUID != p.GetVolumeID()) AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); @@ -284,6 +563,12 @@ void AliAlignObj::Transform(AliTrackPoint &p) const xyzin[1]*rot[3*i+1]+ xyzin[2]*rot[3*i+2]; p.SetXYZ(xyzout); + + if(copycov){ + TMatrixDSym covmat(6); + GetCovMatrix(covmat); + p.SetAlignCovMatrix(covmat); + } } @@ -318,10 +603,10 @@ void AliAlignObj::Print(Option_t *) const printf("Volume=%s\n",GetSymName()); if (GetVolUID() != 0) { - ELayerID layerId; + AliGeomManager::ELayerID layerId; Int_t modId; GetVolUID(layerId,modId); - printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,LayerName(layerId),modId); + printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,AliGeomManager::LayerName(layerId),modId); } printf("%12.8f%12.8f%12.8f Tx = %12.8f Psi = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]); printf("%12.8f%12.8f%12.8f Ty = %12.8f Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]); @@ -329,85 +614,6 @@ void AliAlignObj::Print(Option_t *) const } -//_____________________________________________________________________________ -Int_t AliAlignObj::LayerSize(Int_t layerId) -{ - // Get the layer size for layer corresponding to layerId. - // Implemented only for ITS,TPC,TRD,TOF and HMPID - // - if (layerId < kFirstLayer || layerId >= kLastLayer) { - AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer)); - return 0; - } - else { - return fgLayerSize[layerId - kFirstLayer]; - } -} - -//_____________________________________________________________________________ -const char* AliAlignObj::LayerName(Int_t layerId) -{ - // Get the layer name corresponding to layerId. - // Implemented only for ITS,TPC,TRD,TOF and HMPID - // - if (layerId < kFirstLayer || layerId >= kLastLayer) { - AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer)); - return "Invalid Layer!"; - } - else { - return fgLayerName[layerId - kFirstLayer]; - } -} - -//_____________________________________________________________________________ -UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId) -{ - // From detector (layer) name and module number (according to detector - // internal numbering) build the unique numerical identity of that volume - // inside ALICE - // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values), - // remaining 11 for module ID inside det (2048 possible values). - // - return ((UShort_t(layerId) << 11) | UShort_t(modId)); -} - -//_____________________________________________________________________________ -UShort_t AliAlignObj::LayerToVolUID(Int_t layerId, Int_t modId) -{ - // From detector (layer) name and module number (according to detector - // internal numbering) build the unique numerical identity of that volume - // inside ALICE - // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values), - // remaining 11 for module ID inside det (2048 possible values). - // - return ((UShort_t(layerId) << 11) | UShort_t(modId)); -} - -//_____________________________________________________________________________ -AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId) -{ - // From voluid, unique numerical identity of that volume inside ALICE, - // (voluid is 16 bits, first 5 reserved for layerID (32 possible values), - // remaining 11 for module ID inside det (2048 possible values)), return - // the identity of the layer to which that volume belongs and sets the - // argument modId to the identity of that volume internally to the layer. - // - modId = voluid & 0x7ff; - - return VolUIDToLayer(voluid); -} - -//_____________________________________________________________________________ -AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid) -{ - // From voluid, unique numerical identity of that volume inside ALICE, - // (voluid is 16 bits, first 5 reserved for layerID (32 possible values), - // remaining 11 for module ID inside det (2048 possible values)), return - // the identity of the layer to which that volume belongs - // - return ELayerID((voluid >> 11) & 0x1f); -} - //_____________________________________________________________________________ void AliAlignObj::SetPars(Double_t x, Double_t y, Double_t z, Double_t psi, Double_t theta, Double_t phi) @@ -517,35 +723,39 @@ Bool_t AliAlignObj::SetLocalMatrix(const TGeoMatrix& m) // returns false and the object parameters are not set. // if (!gGeoManager || !gGeoManager->IsClosed()) { - AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!"); + AliError("Can't set the local alignment object parameters! gGeoManager doesn't exist or it is still open!"); return kFALSE; } const char* symname = GetSymName(); - TGeoPhysicalNode* node; + TGeoHMatrix gprime,gprimeinv; + TGeoPhysicalNode* pn = 0; TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); - if(pne){ - node = gGeoManager->MakeAlignablePN(pne); + if(pne) + { + pn = pne->GetPhysicalNode(); + if(pn){ + if (pn->IsAligned()) + AliWarning(Form("Volume %s has been misaligned already!",symname)); + gprime = *pn->GetMatrix(); + }else{ + gprime = pne->GetGlobalOrig(); + } }else{ AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); - node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); - } - - if (!node) { - AliError(Form("Volume name or path %s not valid!",symname)); - return kFALSE; + if(!gGeoManager->cd(symname)) { + AliError(Form("Volume name or path %s not valid!",symname)); + return kFALSE; + } + gprime = *gGeoManager->GetCurrentMatrix(); } - if (node->IsAligned()) - AliWarning(Form("Volume %s has been already misaligned!",symname)); - TGeoHMatrix m1; + TGeoHMatrix m1; // the TGeoHMatrix copy of the local delta "m" const Double_t *tr = m.GetTranslation(); m1.SetTranslation(tr); const Double_t* rot = m.GetRotationMatrix(); m1.SetRotation(rot); - TGeoHMatrix align,gprime,gprimeinv; - gprime = *node->GetMatrix(); gprimeinv = gprime.Inverse(); m1.Multiply(&gprimeinv); m1.MultiplyLeft(&gprime); @@ -615,7 +825,7 @@ Bool_t AliAlignObj::GetLocalMatrix(TGeoHMatrix& m) const // returns false and the object parameters are not set. // if (!gGeoManager || !gGeoManager->IsClosed()) { - AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!"); + AliError("Can't get the local alignment object parameters! gGeoManager doesn't exist or it is still open!"); return kFALSE; } @@ -623,7 +833,11 @@ Bool_t AliAlignObj::GetLocalMatrix(TGeoHMatrix& m) const TGeoPhysicalNode* node; TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); if(pne){ - node = gGeoManager->MakeAlignablePN(pne); + if(!pne->GetPhysicalNode()){ + node = gGeoManager->MakeAlignablePN(pne); + }else{ + node = pne->GetPhysicalNode(); + } }else{ AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); @@ -633,8 +847,8 @@ Bool_t AliAlignObj::GetLocalMatrix(TGeoHMatrix& m) const AliError(Form("Volume name or path %s not valid!",symname)); return kFALSE; } - if (node->IsAligned()) - AliWarning(Form("Volume %s has been already misaligned!",symname)); +// if (node->IsAligned()) +// AliWarning(Form("Volume %s has been misaligned already!",symname)); GetMatrix(m); TGeoHMatrix gprime,gprimeinv; @@ -647,17 +861,22 @@ Bool_t AliAlignObj::GetLocalMatrix(TGeoHMatrix& m) const } //_____________________________________________________________________________ -Bool_t AliAlignObj::ApplyToGeometry() +Bool_t AliAlignObj::ApplyToGeometry(Bool_t ovlpcheck) { // Apply the current alignment object to the TGeo geometry // This method returns FALSE if the symname of the object was not // valid neither to get a TGeoPEntry nor as a volume path // if (!gGeoManager || !gGeoManager->IsClosed()) { - AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!"); + AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still open!"); return kFALSE; } - + + if (gGeoManager->IsLocked()){ + AliError("Can't apply the alignment object! Geometry is locked!"); + return kFALSE; + } + const char* symname = GetSymName(); const char* path; TGeoPhysicalNode* node; @@ -666,14 +885,14 @@ Bool_t AliAlignObj::ApplyToGeometry() path = pne->GetTitle(); node = gGeoManager->MakeAlignablePN(pne); }else{ - AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); + AliDebug(1,Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); path=symname; if (!gGeoManager->CheckPath(path)) { - AliError(Form("Volume path %s not valid!",path)); + AliDebug(1,Form("Volume path %s not valid!",path)); return kFALSE; } if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) { - AliError(Form("Volume %s has already been misaligned!",path)); + AliError(Form("Volume %s has been misaligned already!",path)); return kFALSE; } node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(path); @@ -684,6 +903,8 @@ Bool_t AliAlignObj::ApplyToGeometry() return kFALSE; } + // Double_t threshold = 0.001; + TGeoHMatrix align,gprime; gprime = *node->GetMatrix(); GetMatrix(align); @@ -692,482 +913,28 @@ Bool_t AliAlignObj::ApplyToGeometry() TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1); *ginv = g->Inverse(); *ginv *= gprime; - AliAlignObj::ELayerID layerId; // unique identity for layer in the alobj + AliGeomManager::ELayerID layerId; // unique identity for layer in the alobj Int_t modId; // unique identity for volume inside layer in the alobj GetVolUID(layerId, modId); AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",symname,layerId,modId)); - node->Align(ginv); - - return kTRUE; -} - -//_____________________________________________________________________________ -Bool_t AliAlignObj::GetFromGeometry(const char *symname, AliAlignObj &alobj) -{ - // Get the alignment object which corresponds to the symbolic volume name - // symname (in case equal to the TGeo volume path) - // The method is extremely slow due to the searching by string. - // Therefore it should be used with great care!! - // This method returns FALSE if the symname of the object was not - // valid neither to get a TGeoPEntry nor as a volume path, or if the path - // associated to the TGeoPNEntry was not valid. - // - - // Reset the alignment object - alobj.SetPars(0,0,0,0,0,0); - alobj.SetSymName(symname); - - if (!gGeoManager || !gGeoManager->IsClosed()) { - AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!"); - return kFALSE; - } - - if (!gGeoManager->GetListOfPhysicalNodes()) { - AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!"); - return kFALSE; - } - - const char *path; - TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); - if(pne){ - path = pne->GetTitle(); - }else{ - AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); - path = symname; - } - TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes(); - TGeoPhysicalNode* node = NULL; - for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) { - TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode); - const char *nodePath = tempNode->GetName(); - if (strcmp(path,nodePath) == 0) { - node = tempNode; - break; - } - } - - if (!node) { - if (!gGeoManager->cd(path)) { - AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path)); - return kFALSE; - } - else { - AliWarningClass(Form("Volume (%s) has not been misaligned!",path)); - return kTRUE; - } - } - - TGeoHMatrix align,gprime,g,ginv,l; - gprime = *node->GetMatrix(); - l = *node->GetOriginalMatrix(); - g = *node->GetMatrix(node->GetLevel()-1); - g *= l; - ginv = g.Inverse(); - align = gprime * ginv; - - return alobj.SetMatrix(align); -} - -//_____________________________________________________________________________ -Bool_t AliAlignObj::GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m) -{ - // The method returns global matrix for the ideal detector geometry - // Symname identifies either the corresponding TGeoPNEntry or directly - // the volume path. The output global matrix is stored in 'm'. - // Returns kFALSE in case, TGeo has not been initialized or the symname - // is invalid. - // - - if (!gGeoManager || !gGeoManager->IsClosed()) { - AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!"); - return kFALSE; - } - - if (!gGeoManager->GetListOfPhysicalNodes()) { - AliWarningClass("gGeoManager doesn't contain any aligned nodes!"); - if (!gGeoManager->cd(symname)) { - AliErrorClass(Form("Volume path %s not valid!",symname)); - return kFALSE; - } - else { - m = *gGeoManager->GetCurrentMatrix(); - return kTRUE; - } - } - - const char* path = NULL; - TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); - if(pne){ - path = pne->GetTitle(); + if(ovlpcheck){ + node->Align(ginv,0,kTRUE); //(trunk of root takes threshold as additional argument) }else{ - AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); - path=symname; - } - - if (!gGeoManager->CheckPath(path)) { - AliErrorClass(Form("Volume path %s not valid!",path)); - return kFALSE; + node->Align(ginv,0,kFALSE); } - - TString pathStr = path; - TObjArray *pathArr = pathStr.Tokenize('/'); - TIter iter(pathArr); - TString nodeStr = ""; - m.Clear(); - - TObjString *str = NULL; - while((str = (TObjString*) iter.Next())){ - nodeStr.Append("/"); - nodeStr.Append(str->String()); - - TGeoMatrix *lm = NULL; - TGeoPhysicalNode *physNode = NULL; - if ((physNode = (TGeoPhysicalNode *)gGeoManager->GetListOfPhysicalNodes()->FindObject(nodeStr.Data()))) { - lm = physNode->GetOriginalMatrix(); - if (!lm) lm = physNode->GetNode()->GetMatrix(); - } else { - gGeoManager->cd(nodeStr.Data()); - TGeoNode *node = gGeoManager->GetCurrentNode(); - lm = node->GetMatrix(); + if(ovlpcheck) + { + TObjArray* ovlpArray = gGeoManager->GetListOfOverlaps(); + Int_t nOvlp = ovlpArray->GetEntriesFast(); + if(nOvlp) + { + AliInfo(Form("Misalignment of node %s generated the following overlaps/extrusions:",node->GetName())); + for(Int_t i=0; iUncheckedAt(i))->PrintInfo(); } - m.Multiply(lm); } - - pathArr->Delete(); - delete pathArr; - + return kTRUE; } -//_____________________________________________________________________________ -void AliAlignObj::InitAlignObjFromGeometry() -{ - // Loop over all alignable volumes and extract - // the corresponding alignment objects from - // the TGeo geometry - - if(fgAlignObjs[0]) return; - - InitSymNames(); - - for (Int_t iLayer = kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) { - fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)]; - for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) { - UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule); - fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE); - const char *symname = SymName(volid); - if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule])) - AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname)); - } - } - -} - -//_____________________________________________________________________________ -AliAlignObj* AliAlignObj::GetAlignObj(UShort_t voluid) { - // Returns the alignment object for given volume ID - // - Int_t modId; - ELayerID layerId = VolUIDToLayer(voluid,modId); - return GetAlignObj(layerId,modId); -} - -//_____________________________________________________________________________ -AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId) -{ - // Returns pointer to alignment object given its layer and module ID - // - if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){ - AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1)); - return NULL; - } - InitAlignObjFromGeometry(); - - return fgAlignObjs[layerId-kFirstLayer][modId]; -} - -//_____________________________________________________________________________ -const char* AliAlignObj::SymName(UShort_t voluid) { - // Returns the symbolic volume name for given volume ID - // - Int_t modId; - ELayerID layerId = VolUIDToLayer(voluid,modId); - return SymName(layerId,modId); -} - -//_____________________________________________________________________________ -const char* AliAlignObj::SymName(ELayerID layerId, Int_t modId) -{ - // Returns the symbolic volume name given for a given layer - // and module ID - // - if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){ - AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1)); - return NULL; - } - InitSymNames(); - - return fgVolPath[layerId-kFirstLayer][modId].Data(); -} - -//_____________________________________________________________________________ -void AliAlignObj::InitSymNames() -{ - // Initialize the LUTs which associate the symbolic volume names - // for each alignable volume with their unique numerical identity. - // The LUTs are static, so they are created during the instantiation - // of the first intance of AliAlignObj - // - if (fgVolPath[0]) return; - - for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++) - fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]]; - - TString symname; - Int_t modnum; // in the following, set it to 0 at the start of each layer - - /********************* ITS layers ***********************/ - TString strSPD = "ITS/SPD"; - TString strSDD = "ITS/SDD"; - TString strSSD = "ITS/SSD"; - TString strStave = "/Stave"; - TString strLadder = "/Ladder"; - TString strSector = "/Sector"; - TString strSensor = "/Sensor"; - TString strEntryName1; - TString strEntryName2; - - /********************* SPD layer1 ***********************/ - { - modnum = 0; - - for(Int_t c1 = 1; c1<=10; c1++){ - strEntryName1 = strSPD; - strEntryName1 += 0; - strEntryName1 += strSector; - strEntryName1 += (c1-1); - for(Int_t c2 =1; c2<=2; c2++){ - strEntryName2 = strEntryName1; - strEntryName2 += strStave; - strEntryName2 += (c2-1); - for(Int_t c3 =1; c3<=4; c3++){ - symname = strEntryName2; - symname += strLadder; - symname += (c3-1); - fgVolPath[kSPD1-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - } - - /********************* SPD layer2 ***********************/ - { - modnum = 0; - - for(Int_t c1 = 1; c1<=10; c1++){ - strEntryName1 = strSPD; - strEntryName1 += 1; - strEntryName1 += strSector; - strEntryName1 += (c1-1); - for(Int_t c2 =1; c2<=4; c2++){ - strEntryName2 = strEntryName1; - strEntryName2 += strStave; - strEntryName2 += (c2-1); - for(Int_t c3 =1; c3<=4; c3++){ - symname = strEntryName2; - symname += strLadder; - symname += (c3-1); - fgVolPath[kSPD2-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - } - - /********************* SDD layer1 ***********************/ - { - modnum=0; - - for(Int_t c1 = 1; c1<=14; c1++){ - strEntryName1 = strSDD; - strEntryName1 += 2; - strEntryName1 +=strLadder; - strEntryName1 += (c1-1); - for(Int_t c2 =1; c2<=6; c2++){ - symname = strEntryName1; - symname += strSensor; - symname += (c2-1); - fgVolPath[kSDD1-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - - /********************* SDD layer2 ***********************/ - { - modnum=0; - - for(Int_t c1 = 1; c1<=22; c1++){ - strEntryName1 = strSDD; - strEntryName1 += 3; - strEntryName1 +=strLadder; - strEntryName1 += (c1-1); - for(Int_t c2 = 1; c2<=8; c2++){ - symname = strEntryName1; - symname += strSensor; - symname += (c2-1); - fgVolPath[kSDD2-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - - /********************* SSD layer1 ***********************/ - { - modnum=0; - - for(Int_t c1 = 1; c1<=34; c1++){ - strEntryName1 = strSSD; - strEntryName1 += 4; - strEntryName1 +=strLadder; - strEntryName1 += (c1-1); - for(Int_t c2 = 1; c2<=22; c2++){ - symname = strEntryName1; - symname += strSensor; - symname += (c2-1); - fgVolPath[kSSD1-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - - /********************* SSD layer2 ***********************/ - { - modnum=0; - - for(Int_t c1 = 1; c1<=38; c1++){ - strEntryName1 = strSSD; - strEntryName1 += 5; - strEntryName1 +=strLadder; - strEntryName1 += (c1-1); - for(Int_t c2 = 1; c2<=25; c2++){ - symname = strEntryName1; - symname += strSensor; - symname += (c2-1); - fgVolPath[kSSD2-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - - - /*************** TPC inner and outer layers ****************/ - TString sAsector="TPC/EndcapA/Sector"; - TString sCsector="TPC/EndcapC/Sector"; - TString sInner="/InnerChamber"; - TString sOuter="/OuterChamber"; - - /*************** TPC inner chambers' layer ****************/ - { - modnum = 0; - - for(Int_t cnt=1; cnt<=18; cnt++){ - symname = sAsector; - symname += cnt; - symname += sInner; - fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - for(Int_t cnt=1; cnt<=18; cnt++){ - symname = sCsector; - symname += cnt; - symname += sInner; - fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - - /*************** TPC outer chambers' layer ****************/ - { - modnum = 0; - - for(Int_t cnt=1; cnt<=18; cnt++){ - symname = sAsector; - symname += cnt; - symname += sOuter; - fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - for(Int_t cnt=1; cnt<=18; cnt++){ - symname = sCsector; - symname += cnt; - symname += sOuter; - fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - - /********************* TOF layer ***********************/ - { - modnum=0; - - Int_t nstrA=15; - Int_t nstrB=19; - Int_t nstrC=19; - Int_t nSectors=18; - Int_t nStrips=nstrA+2*nstrB+2*nstrC; - - TString snSM = "TOF/sm"; - TString snSTRIP = "/strip"; - - for (Int_t isect = 0; isect < nSectors; isect++) { - for (Int_t istr = 1; istr <= nStrips; istr++) { - symname = snSM; - symname += Form("%02d",isect); - symname += snSTRIP; - symname += Form("%02d",istr); - fgVolPath[kTOF-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - - /********************* HMPID layer ***********************/ - { - TString str = "/HMPID/Chamber"; - - for (modnum=0; modnum < 7; modnum++) { - symname = str; - symname += modnum; - fgVolPath[kHMPID-kFirstLayer][modnum] = symname.Data(); - } - } - - /********************* TRD layers 1-6 *******************/ - //!! 6 layers with index increasing in outwards direction - { - Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6}; - - TString snStr = "TRD/sm"; - TString snApp1 = "/st"; - TString snApp2 = "/pl"; - - for(Int_t layer=0; layer<6; layer++){ - modnum=0; - for (Int_t isect = 0; isect < 18; isect++) { - for (Int_t icham = 0; icham < 5; icham++) { - symname = snStr; - symname += Form("%02d",isect); - symname += snApp1; - symname += icham; - symname += snApp2; - symname += layer; - fgVolPath[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data(); - modnum++; - } - } - } - } -}