/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ //----------------------------------------------------------------- // Implementation of the alignment object class through the abstract // class AliAlignObj. From it two derived concrete representation of // alignment object class (AliAlignObjAngles, AliAlignObjMatrix) are // derived in separate files. //----------------------------------------------------------------- /***************************************************************************** * AliAlignObjAngles: derived alignment class storing alignment information * * for a single volume in form of three doubles for the translation * * and three doubles for the rotation expressed with the euler angles * * in the xyz-convention (http://mathworld.wolfram.com/EulerAngles.html), * * also known as roll, pitch, yaw. PLEASE NOTE THE ANGLES SIGNS ARE * * INVERSE WITH RESPECT TO THIS REFERENCE!!! In this way the representation* * is fully consistent with the TGeo Rotation methods. * *****************************************************************************/ #include "AliAlignObj.h" //#include "AliLog.h" ClassImp(AliAlignObj) Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = { 80, 160, // ITS SPD 84, 176, // ITS SDD 748, 950, // ITS SSD 36, 36, // TPC 90, 90, 90, 90, 90, 90, // TRD 1, // TOF ?? 1, 1, // PHOS ?? 1, // RICH ?? 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", "?","?", "?", "?" }; //_____________________________________________________________________________ AliAlignObj::AliAlignObj(): fVolUID(0) { // dummy constructor } //_____________________________________________________________________________ AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) : TObject(theAlignObj) { //copy constructor fVolPath = theAlignObj.GetVolPath(); fVolUID = theAlignObj.GetVolUID(); } //_____________________________________________________________________________ AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj) { // assignment operator if(this==&theAlignObj) return *this; fVolPath = theAlignObj.GetVolPath(); fVolUID = theAlignObj.GetVolUID(); return *this; } //_____________________________________________________________________________ AliAlignObj::~AliAlignObj() { // dummy destructor } //_____________________________________________________________________________ void AliAlignObj::SetVolUID(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); } //_____________________________________________________________________________ void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const { // 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). // layerId = VolUIDToLayer(fVolUID,modId); } //_____________________________________________________________________________ void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const { // Calculates the rotation matrix using the // Euler angles in "x y z" notation Double_t degrad = TMath::DegToRad(); Double_t sinpsi = TMath::Sin(degrad*angles[0]); Double_t cospsi = TMath::Cos(degrad*angles[0]); Double_t sinthe = TMath::Sin(degrad*angles[1]); Double_t costhe = TMath::Cos(degrad*angles[1]); Double_t sinphi = TMath::Sin(degrad*angles[2]); Double_t cosphi = TMath::Cos(degrad*angles[2]); rot[0] = costhe*cosphi; rot[1] = -costhe*sinphi; rot[2] = sinthe; rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi; rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi; rot[5] = -costhe*sinpsi; rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi; rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi; rot[8] = costhe*cospsi; } //_____________________________________________________________________________ Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const { // Calculates the Euler angles in "x y z" notation // using the rotation matrix if(rot[0]<1e-7 || rot[8]<1e-7) return kFALSE; Double_t raddeg = TMath::RadToDeg(); angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]); angles[1]=raddeg*TMath::ASin(rot[2]); angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]); return kTRUE; } //_____________________________________________________________________________ void AliAlignObj::Print(Option_t *) const { // Print the contents of the // alignment object in angles and // matrix representations Double_t tr[3]; GetTranslation(tr); Double_t angles[3]; GetAngles(angles); TGeoHMatrix m; GetMatrix(m); const Double_t *rot = m.GetRotationMatrix(); // printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID()); ELayerID layerId; Int_t modId; GetVolUID(layerId,modId); printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),layerId,modId); printf("%12.6f%12.6f%12.6f Tx = %12.6f Psi = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]); printf("%12.6f%12.6f%12.6f Ty = %12.6f Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]); printf("%12.6f%12.6f%12.6f Tz = %12.6f Phi = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]); } //_____________________________________________________________________________ UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId) { // From detector (layer) 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 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 detector (layer) 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 layerID (32 possible values), // remaining 11 for module ID inside det (2048 possible values). // modId = voluid & 0x7ff; return VolUIDToLayer(voluid); } //_____________________________________________________________________________ AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid) { // From detector (layer) 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 layerID (32 possible values), // remaining 11 for module ID inside det (2048 possible values). // return ELayerID((voluid >> 11) & 0x1f); }