// // $Id: GeometryElement.cpp,v 1.17 2004/02/27 02:57:35 mikeh Exp $ // // File: GeometryElement.cc // Purpose: Implement the building block for the run II D0 geometry. // Created: 02-SEP-1997 John Hobbs // // $Revision: 1.17 $ // //$Log: GeometryElement.cpp,v $ //Revision 1.17 2004/02/27 02:57:35 mikeh //version 02-07-00 // - Added method which pass references to GeometryXforms in // GeometryElement to save on copying objects // - Switched to using this method in CylindricalSurface // - Added PureCylindricalCoordinate to allow a coordinate that // always stays in polar coordinates, i.e., no trig calls // - Modified HelicalCoordinate to use new Cylindrical coords where // appropriate // - Needs coordinated release of spacegeom! // //Revision 1.16 2002/08/25 20:24:27 melanson //gcc patches from Scott // //Revision 1.15 2001/01/30 21:22:05 hobbs //See ReleaseNotes for v02-04-00 // // Include files #include #include #include #include #include #include #include using namespace std; using namespace dgs; // Define the current schema version for persistance. int GeometryElement::_cvers = 0; GeometryElement::~GeometryElement() // // Purpose: Destructor. Watch for memory leaks. // { if( _distortion ) delete(_distortion); _distortion = 0; } //----------------------------------------------------------------------------- // // Reco support // //----------------------------------------------------------------------------- SpacePoint GeometryElement::local_to_global(const SpacePoint& lpt) const // // Purpose: Transform a point to global D0 space // { return (_distortion==0) ? _global_position.apply(lpt) : _global_position.apply(*(_distortion->distort(lpt)) ); } SpacePoint GeometryElement::global_to_local(const SpacePoint& gpt) const // // Purpose: Transform a point to global D0 space // { SpacePoint lpt = get_positionptr().invert(gpt); if( _distortion!=0) lpt=*(_distortion->undo(lpt)); return lpt; } MatrixD GeometryElement::local_to_global(const MatrixD& errorMatrix) const // // Purpose: Transform the 3x3 matrix in local Cartesian coordinate basis // to the corresponding matrix in global coordinates. Because this // is a transformation from cartesian to cartesian, the transformation // matrix is independent of position and no point is needed... // { // Make sure the matrix is the correct form if( errorMatrix.rows()!=3 || errorMatrix.columns()!=3 ) { ostringstream smsg; smsg << errorMatrix.rows() << "x" << errorMatrix.columns(); throw XGSIllegalDimension(smsg.str().c_str()); } // Build a MatrixD from the rotation portion of the GeometryXform Rotation r = _global_position.get_rotation(); double data[9]={r.xx(),r.xy(),r.xz(),r.yx(),r.yy(),r.yz(),r.zx(),r.zy(),r.zz()}; MatrixD T(3,data); MatrixD Tinv = T.inverse(); return T*errorMatrix*Tinv; } //----------------------------------------------------------------------------- // // The alignment method // //----------------------------------------------------------------------------- bool GeometryElement::move(const GeometryXform& origin_correction) // // Purpose: Change my relative origin, and propagate the effects to my // dependents. // { GeometryXform ref_point = _global_position.apply(origin_correction); set_position(ref_point); //For simplicity, do it this way. return true; } //---------------------------------------------------------------------------- // // The rest... // //---------------------------------------------------------------------------- bool GeometryElement::set_position(const GeometryXform& new_origin) // // Purpose: Calculate a geometry elements position in global space given the // reference point. Reposition all children. // States: // { // Move my children list children = get_children(); list::iterator kid = children.begin(); while ( kid != children.end() ) { GeometryXform kid_relative = (*kid)->get_relative_position(_global_position); (*kid)->set_relative_position(new_origin,kid_relative); kid++; } // Move myself _global_position = new_origin; // This always succeeds, or does it? return true; } GeometryXform GeometryElement::get_relative_position( const GeometryXform& parent) const // // Purpose: Compute the support point on a parent. Return the answer in // parent local coordinates. // { return _global_position.diff(parent); return parent.invert(_global_position); } bool GeometryElement::set_relative_position(const GeometryXform& parent, const GeometryXform& delta_position) // // Purpose: Set the position relative to a specified position. // { // Convert to generic set_position form and call GeometryXform global_position = parent.apply(delta_position); return set_position(global_position); } absGeometryDistortion* GeometryElement::get_distortion() const // // Purpose: Return a copy of the distortion // { if( !_distortion ) return 0; else return _distortion->clone(); } bool GeometryElement::set_distortion(const absGeometryDistortion* distortion) // // Purpose: Set the distortion to a copy of the given distortion // { bool retval=distortion; if( !distortion ) _distortion=0; else _distortion = distortion->clone(); return retval; } std::ostream& dgs::operator<<(std::ostream& os, const GeometryElement& me) // // Purpose: Printable output. // { os << "at " << me._global_position << endl; return(os); }