Namespaces | |
namespace | tec |
namespace | tib |
namespace | tid |
namespace | tob |
namespace | tpb |
namespace | tpe |
Typedefs | |
typedef std::vector< Alignable * > | Alignables |
typedef math::Vector< 6 >::type | AlignParams |
typedef std::map< std::pair < Alignable *, Alignable * >, AlgebraicMatrix > | Correlations |
typedef unsigned int(* | Counter )(align::ID) |
typedef AlgebraicMatrix | Derivatives |
typedef math::Error< 6 >::type | ErrorMatrix |
typedef AlgebraicVector | EulerAngles |
typedef Point3DBase< Scalar, GlobalTag > | GlobalPoint |
typedef std::vector< GlobalPoint > | GlobalPoints |
typedef Vector3DBase< Scalar, GlobalTag > | GlobalVector |
typedef std::vector< GlobalVector > | GlobalVectors |
typedef uint32_t | ID |
typedef Point3DBase< Scalar, LocalTag > | LocalPoint |
typedef std::vector< LocalPoint > | LocalPoints |
typedef Vector3DBase< Scalar, LocalTag > | LocalVector |
typedef std::vector< LocalVector > | LocalVectors |
typedef std::vector < AlignmentParameters * > | Parameters |
typedef Point3DBase< Scalar, GlobalTag > | PositionType |
typedef TkRotation< Scalar > | RotationType |
typedef double | Scalar |
typedef std::vector< Scalar > | Scalars |
Enumerations | |
enum | StructureType { invalid = 0, AlignableDetUnit, AlignableDet, TPBModule, TPBLadder, TPBLayer, TPBHalfBarrel, TPBBarrel, TPEModule, TPEPanel, TPEBlade, TPEHalfDisk, TPEHalfCylinder, TPEEndcap, TIBModule, TIBString, TIBSurface, TIBHalfShell, TIBLayer, TIBHalfBarrel, TIBBarrel, TIDModule, TIDSide, TIDRing, TIDDisk, TIDEndcap, TOBModule, TOBRod, TOBLayer, TOBHalfBarrel, TOBBarrel, TECModule, TECRing, TECPetal, TECSide, TECDisk, TECEndcap, Pixel, Strip, Tracker, AlignableDTBarrel = 100, AlignableDTWheel, AlignableDTStation, AlignableDTChamber, AlignableDTSuperLayer, AlignableDTLayer, AlignableCSCEndcap, AlignableCSCStation, AlignableCSCRing, AlignableCSCChamber, AlignableCSCLayer, AlignableMuon, Detector } |
Enumerate the types of structure an alignable can be. More... | |
Functions | |
GlobalVector | centerOfMass (const GlobalVectors &theVs) |
Find the CM of a set of points. | |
void | createPoints (GlobalVectors *Vs, Alignable *ali, const std::string &weightBy, bool weightById, const std::vector< unsigned int > &weightByIdVector) |
Creates the points which are used in diffAlignables A set of points corresponding to lowest daughters. | |
const AlignTransform & | DetectorGlobalPosition (const Alignments &allGlobals, const DetId &id) |
AlgebraicVector | diffAlignables (Alignable *refAli, Alignable *curAli, const std::string &weightBy, bool weightById, const std::vector< unsigned int > &weightByIdVector) |
Finds the TR between two alignables - first alignable is reference. | |
GlobalVector | diffR (const GlobalVectors ¤t, const GlobalVectors &nominal) |
RotationType | diffRot (const GlobalVectors ¤t, const GlobalVectors &nominal) |
Find matrix to rotate from nominal to current vectors. | |
PositionType | motherPosition (const std::vector< const PositionType * > &dauPos) |
Find mother's position from the average of its daughters' positions. | |
void | moveAlignable (Alignable *ali, AlgebraicVector diff) |
Finds the TR between 2 sets of alignables For example, if TIB/TID were to move as one unit. | |
bool | readModuleList (unsigned int, unsigned int, const std::vector< unsigned int > &) |
void | rectify (RotationType &) |
Correct a rotation matrix for rounding errors. | |
EulerAngles | toAngles (const RotationType &) |
Convert rotation matrix to angles about x-, y-, z-axes (frame rotation). | |
RotationType | toMatrix (const EulerAngles &) |
Convert rotation angles about x-, y-, z-axes to matrix. |
Namespace for common type definitions used in alignment.
Namespace for common calculations in alignment.
typedef std::vector<Alignable*> align::Alignables |
Definition at line 28 of file Utilities.h.
typedef math::Vector<6>::type align::AlignParams |
Definition at line 38 of file Definitions.h.
typedef std::map<std::pair<Alignable*, Alignable*>, AlgebraicMatrix> align::Correlations |
Definition at line 31 of file Utilities.h.
typedef unsigned int(* align::Counter)(align::ID) |
Definition at line 26 of file Counters.h.
typedef AlgebraicMatrix align::Derivatives |
Definition at line 37 of file Definitions.h.
typedef math::Error<6>::type align::ErrorMatrix |
Definition at line 39 of file Definitions.h.
typedef AlgebraicVector align::EulerAngles |
Definition at line 36 of file Definitions.h.
typedef Point3DBase<Scalar, GlobalTag> align::GlobalPoint |
Definition at line 31 of file Definitions.h.
typedef std::vector<GlobalPoint> align::GlobalPoints |
Definition at line 23 of file Utilities.h.
typedef Vector3DBase<Scalar, GlobalTag> align::GlobalVector |
Definition at line 33 of file Definitions.h.
typedef std::vector<GlobalVector> align::GlobalVectors |
Definition at line 24 of file Utilities.h.
typedef uint32_t align::ID |
Definition at line 26 of file Definitions.h.
typedef Point3DBase<Scalar, LocalTag> align::LocalPoint |
Definition at line 32 of file Definitions.h.
typedef std::vector<LocalPoint> align::LocalPoints |
Definition at line 25 of file Utilities.h.
typedef Vector3DBase<Scalar, LocalTag> align::LocalVector |
Definition at line 34 of file Definitions.h.
typedef std::vector< LocalVector > align::LocalVectors |
Definition at line 26 of file Utilities.h.
typedef std::vector<AlignmentParameters*> align::Parameters |
Definition at line 29 of file Utilities.h.
typedef Point3DBase<Scalar, GlobalTag> align::PositionType |
Definition at line 30 of file Definitions.h.
typedef TkRotation<Scalar> align::RotationType |
Definition at line 29 of file Definitions.h.
typedef double align::Scalar |
Definition at line 27 of file Definitions.h.
typedef std::vector<Scalar> align::Scalars |
Definition at line 22 of file Utilities.h.
enum align::StructureType |
Enumerate the types of structure an alignable can be.
Basically list the levels in the detector's hierarchy.
Definition at line 17 of file StructureType.h.
00018 { 00019 invalid = 0, 00020 AlignableDetUnit, 00021 AlignableDet, 00022 00023 // Barrel Pixel 00024 TPBModule, 00025 TPBLadder, 00026 TPBLayer, // = 5 00027 TPBHalfBarrel, 00028 TPBBarrel, 00029 00030 // Forward Pixel 00031 TPEModule, 00032 TPEPanel, 00033 TPEBlade, // = 10 00034 TPEHalfDisk, 00035 TPEHalfCylinder, 00036 TPEEndcap, 00037 00038 // Tracker Inner Barrel 00039 TIBModule, 00040 TIBString, // = 15 00041 TIBSurface, 00042 TIBHalfShell, 00043 TIBLayer, 00044 TIBHalfBarrel, 00045 TIBBarrel, // = 20 00046 00047 // Tracker Inner Disks 00048 TIDModule, 00049 TIDSide, 00050 TIDRing, 00051 TIDDisk, 00052 TIDEndcap, // = 25 00053 00054 // Tracker Outer Barrel 00055 TOBModule, 00056 TOBRod, 00057 TOBLayer, 00058 TOBHalfBarrel, 00059 TOBBarrel, // = 30 00060 00061 // Tracker Endcaps 00062 TECModule, 00063 TECRing, 00064 TECPetal, 00065 TECSide, 00066 TECDisk, // = 35 00067 TECEndcap, 00068 00069 Pixel, 00070 Strip, 00071 Tracker, // = 39 00072 00073 // Muon Detector, not touching these now 00074 AlignableDTBarrel = 100, 00075 AlignableDTWheel, 00076 AlignableDTStation, 00077 AlignableDTChamber, 00078 AlignableDTSuperLayer, 00079 AlignableDTLayer, // = 105 00080 AlignableCSCEndcap, 00081 AlignableCSCStation, 00082 AlignableCSCRing, 00083 AlignableCSCChamber, 00084 AlignableCSCLayer, // = 110 00085 AlignableMuon, 00086 00087 Detector // = 112 (what for?) 00088 };
align::GlobalVector align::centerOfMass | ( | const GlobalVectors & | theVs | ) |
Find the CM of a set of points.
Definition at line 181 of file Utilities.cc.
References j.
Referenced by diffAlignables().
00182 { 00183 unsigned int nPoints = theVs.size(); 00184 00185 GlobalVector CM(0,0,0); 00186 00187 for (unsigned int j = 0; j < nPoints; ++j) CM += theVs[j]; 00188 00189 return CM /= static_cast<Scalar>(nPoints); 00190 }
void align::createPoints | ( | align::GlobalVectors * | Vs, | |
Alignable * | ali, | |||
const std::string & | weightBy, | |||
bool | weightById, | |||
const std::vector< unsigned int > & | weightByIdVector | |||
) |
Creates the points which are used in diffAlignables A set of points corresponding to lowest daughters.
Definition at line 81 of file AlignTools.cc.
References AlignableDet, AlignableDetUnit, Alignable::alignableObjectId(), Alignable::components(), dummy, e, error, i, Alignable::id(), j, SurveyDet::localPoints(), Alignable::mother(), readModuleList(), Alignable::setSurvey(), Alignable::surface(), Alignable::survey(), AlignableSurface::toGlobal(), x, y, and z.
Referenced by diffAlignables().
00081 { 00082 00083 00084 const align::Alignables& comp = ali->components(); 00085 unsigned int nComp = comp.size(); 00086 for (unsigned int i = 0; i < nComp; ++i) align::createPoints(Vs, comp[i], weightBy, weightById, weightByIdVector); 00087 // double the weight for SS modules if weight by Det 00088 if ((ali->alignableObjectId() == align::AlignableDet)&&(weightBy == "Det")){ 00089 for (unsigned int i = 0; i < nComp; ++i) align::createPoints(Vs, comp[i], weightBy, weightById, weightByIdVector); 00090 } 00091 00092 //only create points for lowest hiearchical level 00093 if (ali->alignableObjectId() == align::AlignableDetUnit){ 00094 //check if the raw id or the mother's raw id is on the list 00095 bool createPointsForDetUnit = true; 00096 if (weightById) createPointsForDetUnit = align::readModuleList( ali->id(), ali->mother()->id(), weightByIdVector); 00097 if (createPointsForDetUnit){ 00098 //if no survey information, create local points 00099 if(!(ali->survey())){ 00100 align::ErrorMatrix error; 00101 ali->setSurvey( new SurveyDet (ali->surface(), error*1e-6) ); 00102 } 00103 const align::GlobalPoints& points = ali->surface().toGlobal(ali->survey()->localPoints()); 00104 for (unsigned int j = 0; j < points.size(); ++j){ 00105 align::GlobalVector dummy(points[j].x(),points[j].y(),points[j].z()); 00106 Vs->push_back(dummy); 00107 } 00108 } 00109 } 00110 00111 }
const AlignTransform & align::DetectorGlobalPosition | ( | const Alignments & | allGlobals, | |
const DetId & | id | |||
) |
Definition at line 10 of file DetectorGlobalPosition.cc.
References lat::endl(), Exception, iter, and Alignments::m_align.
Referenced by TrackerGeometryIntoNtuples::beginJob(), MuonGeometryIntoNtuples::beginJob(), AlignmentMonitorAsAnalyzer::beginJob(), AlignmentProducer::beginOfJob(), TrackerGeometryCompare::createROOTGeometry(), MuonAlignmentInputDB::newAlignableMuon(), TrackerDigiGeometryESModule::produce(), CSCGeometryESModule::produce(), and DTGeometryESModule::produce().
00010 { 00011 for (std::vector<AlignTransform>::const_iterator iter = allGlobals.m_align.begin(); 00012 iter != allGlobals.m_align.end(); 00013 ++iter) { 00014 if (iter->rawId() == id.rawId()) { 00015 return *iter; 00016 } 00017 } 00018 00019 throw cms::Exception("RecordNotFound") 00020 << "DetId(" << id.rawId() << ") not found in GlobalPositionRcd" << std::endl; 00021 }
AlgebraicVector align::diffAlignables | ( | Alignable * | refAli, | |
Alignable * | curAli, | |||
const std::string & | weightBy, | |||
bool | weightById, | |||
const std::vector< unsigned int > & | weightByIdVector | |||
) |
Finds the TR between two alignables - first alignable is reference.
Definition at line 10 of file AlignTools.cc.
References Alignable::alignableObjectId(), centerOfMass(), createPoints(), diffR(), diffRot(), Exception, Alignable::globalPosition(), Alignable::id(), k, TkRotation< T >::multiplyInverse(), rot, toAngles(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().
Referenced by TrackerGeometryCompare::compareGeometries(), and TrackerGeometryCompare::diffCommonTrackerSystem().
00010 { 00011 00012 //check they are the same 00013 if (refAli->alignableObjectId() != curAli->alignableObjectId()){ 00014 if (refAli->id() != curAli->id()){ 00015 throw cms::Exception("Geometry Error") 00016 << "[AlignTools] Error, Alignables do not match"; 00017 } 00018 } 00019 00020 //create points 00021 align::GlobalVectors refVs; 00022 align::GlobalVectors curVs; 00023 align::createPoints(&refVs, refAli, weightBy, weightById, weightByIdVector); 00024 align::createPoints(&curVs, curAli, weightBy, weightById, weightByIdVector); 00025 00026 //redefine the set of points 00027 //find the translational difference 00028 align::GlobalVector theR = align::diffR(curVs,refVs); 00029 00030 //CM difference (needed below in rotational transformation) 00031 align::GlobalVector pointsCM = align::centerOfMass(curVs); 00032 align::PositionType alignableCM = curAli->globalPosition(); 00033 align::GlobalVector cmdiff(alignableCM.x()-pointsCM.x(), alignableCM.y()-pointsCM.y(), alignableCM.z()-pointsCM.z()); 00034 00035 00036 //readjust points before finding rotation 00037 align::GlobalVector CMref = align::centerOfMass(refVs); 00038 align::GlobalVector CMcur = align::centerOfMass(curVs); 00039 for (unsigned int k = 0; k < refVs.size(); ++k){ 00040 refVs[k] -= CMref; 00041 curVs[k] -= CMcur; 00042 } 00043 00044 //find rotational difference 00045 align::RotationType rot = align::diffRot(curVs, refVs); 00046 align::EulerAngles theW = align::toAngles( rot ); 00047 00048 //adjust translational difference factoring in different rotational CM 00049 //needed because rotateInGlobalFrame is about CM of alignable, not points 00050 align::GlobalVector::BasicVectorType lpvgf = cmdiff.basicVector(); 00051 align::GlobalVector moveV( rot.multiplyInverse(lpvgf) - lpvgf); 00052 align::GlobalVector theRprime(theR + moveV); 00053 00054 AlgebraicVector deltaRW(6); 00055 deltaRW(1) = theRprime.x(); 00056 deltaRW(2) = theRprime.y(); 00057 deltaRW(3) = theRprime.z(); 00058 deltaRW(4) = theW(1); 00059 deltaRW(5) = theW(2); 00060 deltaRW(6) = theW(3); 00061 00062 refVs.clear(); 00063 curVs.clear(); 00064 00065 return deltaRW; 00066 00067 }
align::GlobalVector align::diffR | ( | const GlobalVectors & | current, | |
const GlobalVectors & | nominal | |||
) |
Definition at line 162 of file Utilities.cc.
References j.
Referenced by diffAlignables().
00164 { 00165 GlobalVector nCM(0,0,0); 00166 GlobalVector cCM(0,0,0); 00167 00168 unsigned int nPoints = nominal.size(); 00169 00170 for (unsigned int j = 0; j < nPoints; ++j) 00171 { 00172 nCM += nominal[j]; 00173 cCM += current[j]; 00174 } 00175 00176 nCM -= cCM; 00177 00178 return nCM /= static_cast<Scalar>(nPoints); 00179 }
align::RotationType align::diffRot | ( | const GlobalVectors & | current, | |
const GlobalVectors & | nominal | |||
) |
Find matrix to rotate from nominal to current vectors.
Assume both sets of vectors have the same size and order.
Definition at line 71 of file Utilities.cc.
References c, e, I, j, TkRotation< T >::multiplyInverse(), r, solve(), toMatrix(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().
Referenced by SurveyResidual::calculate(), diffAlignables(), and SurveyResidual::sensorResidual().
00073 { 00074 // Find the matrix needed to rotate the nominal surface to the current one 00075 // using small angle approximation through the equation: 00076 // 00077 // I * dOmega = dr * r (sum over points) 00078 // 00079 // where dOmega is a vector of small rotation angles about (x, y, z)-axes, 00080 // and I is the inertia tensor defined as 00081 // 00082 // I_ij = delta_ij * r^2 - r_i * r_j (sum over points) 00083 // 00084 // delta_ij is the identity matrix. i, j are indices for (x, y, z). 00085 // 00086 // On the rhs of the first eq, r * dr is the cross product of r and dr. 00087 // In this case, r is the nominal vector and dr is the displacement of the 00088 // current point from its nominal point (current vector - nominal vector). 00089 // 00090 // Since the solution of dOmega (by inverting I) gives angles that are small, 00091 // we rotate the current surface by -dOmega and repeat the process until the 00092 // dOmega^2 is less than a certain tolerance value. 00093 // (In other words, we move the current surface by small angular steps till 00094 // it matches the nominal surface.) 00095 // The full rotation is found by adding up the rotations (given by dOmega) 00096 // in each step. (More precisely, the product of all the matrices.) 00097 // 00098 // Note that, in some cases, if the angular displacement between current and 00099 // nominal is pi, the algorithm can return an identity (no rotation). 00100 // This is because dr = -r and r * dr is all zero. 00101 // This is not a problem since we are dealing with small angles in alignment. 00102 00103 static const double tolerance = 1e-12; 00104 00105 RotationType rot; // rotation from nominal to current; init to identity 00106 00107 // Initial values for dr and I; I is always the same in each step 00108 00109 AlgebraicSymMatrix I(3); // inertia tensor 00110 00111 GlobalVectors rotated = current; // rotated current vectors in each step 00112 00113 unsigned int nPoints = nominal.size(); 00114 00115 for (unsigned int j = 0; j < nPoints; ++j) 00116 { 00117 const GlobalVector& r = nominal[j]; 00118 00119 // Inertial tensor: I_ij = delta_ij * r^2 - r_i * r_j (sum over points) 00120 00121 I.fast(1, 1) += r.y() * r.y() + r.z() * r.z(); 00122 I.fast(2, 2) += r.x() * r.x() + r.z() * r.z(); 00123 I.fast(3, 3) += r.y() * r.y() + r.x() * r.x(); 00124 I.fast(2, 1) -= r.x() * r.y(); // row index must be >= col index 00125 I.fast(3, 1) -= r.x() * r.z(); 00126 I.fast(3, 2) -= r.y() * r.z(); 00127 } 00128 00129 while (true) 00130 { 00131 AlgebraicVector rhs(3); // sum of dr * r 00132 00133 for (unsigned int j = 0; j < nPoints; ++j) 00134 { 00135 const GlobalVector& r = nominal[j]; 00136 const GlobalVector& c = rotated[j]; 00137 00138 // Cross product of dr * r = c * r (sum over points) 00139 00140 rhs(1) += c.y() * r.z() - c.z() * r.y(); 00141 rhs(2) += c.z() * r.x() - c.x() * r.z(); 00142 rhs(3) += c.x() * r.y() - c.y() * r.x(); 00143 } 00144 00145 EulerAngles dOmega = CLHEP::solve(I, rhs); 00146 00147 rot *= toMatrix(dOmega); // add to rotation 00148 00149 if (dOmega.normsq() < tolerance) break; // converges, so exit loop 00150 00151 // Not yet converge; move current vectors to new positions and find dr 00152 00153 for (unsigned int j = 0; j < nPoints; ++j) 00154 { 00155 rotated[j] = GlobalVector( rot.multiplyInverse( current[j].basicVector() ) ); 00156 } 00157 } 00158 00159 return rot; 00160 }
PositionType align::motherPosition | ( | const std::vector< const PositionType * > & | dauPos | ) |
Find mother's position from the average of its daughters' positions.
Referenced by SurveyResidual::calculate().
void align::moveAlignable | ( | Alignable * | ali, | |
AlgebraicVector | diff | |||
) |
Finds the TR between 2 sets of alignables For example, if TIB/TID were to move as one unit.
Moves the alignable by the AlgebraicVector
Definition at line 70 of file AlignTools.cc.
References Alignable::move(), Alignable::rotateInGlobalFrame(), and toMatrix().
Referenced by TrackerGeometryCompare::compareGeometries(), TrackerGeometryCompare::diffCommonTrackerSystem(), and TrackerGeometryCompare::setCommonTrackerSystem().
00070 { 00071 00072 GlobalVector dR(diff[0],diff[1],diff[2]); 00073 align::EulerAngles dOmega(3); dOmega[0] = diff[3]; dOmega[1] = diff[4]; dOmega[2] = diff[5]; 00074 align::RotationType dRot = align::toMatrix(dOmega); 00075 ali->move(dR); 00076 ali->rotateInGlobalFrame(dRot); 00077 00078 }
bool align::readModuleList | ( | unsigned int | aliId, | |
unsigned int | motherId, | |||
const std::vector< unsigned int > & | weightByIdVector | |||
) |
Definition at line 114 of file AlignTools.cc.
References i.
Referenced by createPoints().
00114 { 00115 00116 bool foundId = false; 00117 00118 unsigned int sizeVector = weightByIdVector.size(); 00119 00120 for (unsigned int i = 0; i < sizeVector; ++i){ 00121 00122 unsigned int listId = weightByIdVector[i]; 00123 00124 if (listId == aliId){ foundId = true; break; } 00125 if (listId == motherId){ foundId = true; break; } 00126 } 00127 00128 return foundId; 00129 }
void align::rectify | ( | RotationType & | rot | ) |
Correct a rotation matrix for rounding errors.
Referenced by AlignmentParameterStore::applyAlignableAbsolutePositions(), AlignmentParameterStore::applyParameters(), MuonAlignmentInputXML::set_one_position(), and SurveyAlignment::shiftSensors().
EulerAngles align::toAngles | ( | const RotationType & | rot | ) |
Convert rotation matrix to angles about x-, y-, z-axes (frame rotation).
Referenced by AlignmentParameterStore::acquireRelativeParameters(), diffAlignables(), RigidBodyAlignmentParameters::displacementFromAlignable(), KalmanAlignmentUserVariables::extractTrueParameters(), TrackerGeometryCompare::fillTree(), SurveyResidual::sensorResidual(), AlignableSurface::toGlobal(), AlignableSurface::toLocal(), SurveyOutput::write(), and MuonAlignmentOutputXML::writeComponents().
align::RotationType align::toMatrix | ( | const EulerAngles & | angles | ) |
Convert rotation angles about x-, y-, z-axes to matrix.
Definition at line 40 of file Utilities.cc.
References c1, c2, c3, funct::cos(), s1, s2, s3, and funct::sin().
Referenced by AlignmentParameterStore::applyParameters(), PedeSteerer::correctToReferenceSystem(), diffRot(), MuonAlignmentInputXML::do_setposition(), KalmanAlignmentAlgorithm::initializeAlignmentParameters(), moveAlignable(), AlignmentParameterStore::setAlignmentPositionError(), TrackerGeometryCompare::setCommonTrackerSystem(), SurveyAlignment::shiftSensors(), AlignmentProducer::simpleMisalignment_(), AlignableSurface::toGlobal(), and AlignableSurface::toLocal().
00041 { 00042 Scalar s1 = std::sin(angles[0]), c1 = std::cos(angles[0]); 00043 Scalar s2 = std::sin(angles[1]), c2 = std::cos(angles[1]); 00044 Scalar s3 = std::sin(angles[2]), c3 = std::cos(angles[2]); 00045 00046 return RotationType( c2 * c3, c1 * s3 + s1 * s2 * c3, s1 * s3 - c1 * s2 * c3, 00047 -c2 * s3, c1 * c3 - s1 * s2 * s3, s1 * c3 + c1 * s2 * s3, 00048 s2, -s1 * c2, c1 * c2); 00049 }