20#include "GeoModelKernel/GeoVolumeCursor.h"
21#include "GeoModelKernel/GeoLogVol.h"
22#include "GeoModelKernel/GeoTrd.h"
23#include "GeoModelKernel/GeoShapeShift.h"
24#include "GeoModelKernel/GeoShapeUnion.h"
25#include "GeoModelKernel/GeoShapeIntersection.h"
26#include "GeoModelKernel/GeoShapeSubtraction.h"
73 double& x1,
double& z1 );
77 double& x0,
double& y0,
double& x1,
double& y1 );
86 if (shape->typeID()==GeoTrd::getClassTypeID())
87 return static_cast<const GeoTrd*
>(shape);
88 if (shape->typeID() == GeoShapeShift::getClassTypeID() ) {
89 const GeoShapeShift* theShift =
static_cast<const GeoShapeShift*
>(shape);
92 if (shape->typeID() == GeoShapeSubtraction::getClassTypeID() ) {
93 const GeoShapeSubtraction* theSubtraction =
static_cast<const GeoShapeSubtraction*
>(shape);
97 if (shape->typeID() == GeoShapeUnion::getClassTypeID() ) {
98 const GeoShapeUnion* theUnion =
static_cast<const GeoShapeUnion*
>(shape);
102 if (shape->typeID() == GeoShapeIntersection::getClassTypeID() ) {
103 const GeoShapeIntersection* theIntersection =
static_cast<const GeoShapeIntersection*
>(shape);
119 message(
"ERROR: Received NULL detectorstore");
127 message(
"ERROR: Received NULL system pointer (and thus can't get detector store pointer");
128 else if (!
m_d->detectorStore)
129 message(
"ERROR: Could not get detectorStore pointer from system pointer");
136 for ( itMDT =
m_d->mdtchambervolinfo.begin(); itMDT!=itMDTE; ++itMDT )
137 itMDT->second.trd->unref();
145 double vx = v.x(), vy = v.y(), vz = v.z();
150 m(0,0)*vx + m(0,1)*vy + m(0,2)*vz,
151 m(1,0)*vx + m(1,1)*vy + m(1,2)*vz,
152 m(2,0)*vx + m(2,1)*vy + m(2,2)*vz);
177 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || n[1]==
'E';
179 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || (n[1]==
'E'&&n[2]==
'E');
187 theclass->messageDebug(
"Warning: Can't init since muon geometry information is not present." );
199 if (!sgaccess->
retrieve( theExpt,
"ATLAS" )) {
200 theclass->message(
"MuonChamberProjectionHelper Error: Can't retrieve"
201 " the ATLAS GeoModelExperiment from detector store.");
208 GeoVolumeCursor av(world);
209 const GeoLogVol * logvol(0);
210 const GeoShape * shape(0);
211 while (!av.atEnd()) {
213 if (av.getName()!=
"Muon") {
218 GeoVolumeCursor av2(av.getVolume());
219 while (!av2.atEnd()) {
221 logvol = av2.getVolume()->getLogVol();
223 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null logvol");
227 shape = logvol->getShape();
229 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null shape");
236 if ( trd->getZHalfLength()>0.0
237 && trd->getXHalfLength1() > 0.0
238 && trd->getXHalfLength2() > 0.0
239 && trd->getYHalfLength1() > 0.0
240 && trd->getYHalfLength2() > 0.0 ) {
245 theclass->message(
"MuonChamberProjectionHelper Error: Chamber trd has non-positive shape parameters!");
248 theclass->message(
"MuonChamberProjectionHelper Error: Chamber shape is not a GeoTrd, and is not a boolean with a Trd somewhere");
257 theclass->message(
"MuonChamberProjectionHelper Error: Found no MDT chambers");
270 return m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo,
true );
276 double& distanceToFirstEndPlane,
double& distanceToSecondEndPlane,
277 const double& radius )
280 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
283 const GeoTrd * trd = itChamberInfo->second.trd;
284 double y1(trd->getYHalfLength1()), y2(trd->getYHalfLength2()),
z(trd->getZHalfLength());
295 distanceToFirstEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p1,n1);
296 if (distanceToFirstEndPlane < 0.0 )
299 distanceToSecondEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p2,n2);
300 if (distanceToSecondEndPlane < 0.0 )
304 double r(fabs(radius));
306 double costheta1 = unitdir.dot(n1.unit());
307 double costheta2 = unitdir.dot(n2.unit());
309 distanceToFirstEndPlane +=
r*sqrt(fabs((1-costheta1*costheta1)/costheta1));
310 distanceToSecondEndPlane +=
r*sqrt(fabs((1-costheta2*costheta2)/costheta2));
320 double denominator(planeNormal.dot(lineDirection)*lineDirection.mag());
321 if (denominator==0.0) {
322 theclass->message(
"MuonChamberProjectionHelper Error: pointToPlaneDistAlongLine is undefined!");
325 double numerator(planeNormal.x() * (planePoint.x() - point.x())
326 + planeNormal.y() * (planePoint.y() - point.y())
327 + planeNormal.z() * (planePoint.z() - point.z()));
328 return fabs(numerator/denominator);
347 theclass->message(
"MuonChamberProjectionHelper Error: Can't find MDT chamber among the "
360 const GeoTrd * trd = itChamberInfo->second.trd;
361 trdX = trd->getXHalfLength1();
362 trdZ = trd->getZHalfLength();
363 if ( trdX != trd->getXHalfLength2() ) {
364 theclass->message(
"MuonChamberProjectionHelper Warning: x1!=x2 in GeoTrd shape. Clippings etc. will be to a too large surface.");
365 if ( trdX < trd->getXHalfLength2() )
366 trdX = trd->getXHalfLength2();
376 bool& outsidechamber )
379 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
383 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
386 itChamberInfo->second.ensureInitGlobalToLocal();
387 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
388 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
394 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
399 m_d->projectXZPointToTrdAlongYAxis( ax, az,itChamberInfo->second.trd, firstEndWall_pointA, secondEndWall_pointA );
400 m_d->projectXZPointToTrdAlongYAxis( bx, bz,itChamberInfo->second.trd, firstEndWall_pointB, secondEndWall_pointB );
407 Amg::transform(firstEndWall_pointA, itChamberInfo->second.localToGlobal);
408 Amg::transform(secondEndWall_pointA, itChamberInfo->second.localToGlobal);
409 Amg::transform(firstEndWall_pointB, itChamberInfo->second.localToGlobal);
410 Amg::transform(secondEndWall_pointB, itChamberInfo->second.localToGlobal);
412 outsidechamber =
false;
420 const double epsilon(0.1);
421 const double trdY1(trd->getYHalfLength1()), trdY2(trd->getYHalfLength2());
422 const double y( trdY1 + 0.5*(1.0+
z/trd->getZHalfLength())*(trdY2-trdY1) );
429 const double& x0,
const double& z0,
430 double& x1,
double& z1 )
440 z1 += (-trdX-x1)*(z1-z0)/(x1-x0);
450 z1 += (trdX-x1)*(z1-z0)/(x1-x0);
460 x1 += (-trdZ-z1)*(x1-x0)/(z1-z0);
470 x1 += (trdZ-z1)*(x1-x0)/(z1-z0);
483 const double & extradist )
486 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
490 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
495 if (trdX<=0.0||trdZ<=0.0)
499 itChamberInfo->second.ensureInitGlobalToLocal();
500 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
501 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
504 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
508 double ay(
A.y()), by(B.y());
516 outsidechamber =
false;
523 double& x0,
double& y0,
double& x1,
double& y1 )
525 if ( fabs(x0)<=rectX && fabs(y0)<=rectY ) {
526 if ( fabs(x1)>rectX || fabs(y1)>rectY ) {
529 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (1)");
532 if ( fabs(x1)<=rectX && fabs(y1)<=rectY ) {
535 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (2)");
547 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (3)");
GeoPhysVol * getPhysVol()
Destructor.
void ensureInitGlobalToLocal()
MDTChamberInfo(const Amg::Transform3D &l2g, const GeoTrd *t)
Amg::Transform3D localToGlobal
std::unique_ptr< Amg::Transform3D > globalToLocal
std::map< GeoPVConstLink, MDTChamberInfo > mdtchambervolinfo
Imp(MuonChamberProjectionHelper *tc, StoreGateSvc *ds)
std::map< GeoPVConstLink, MDTChamberInfo >::iterator ChamberInfoMapItr
const GeoTrd * findTRDInShape(const GeoShape *shape)
std::map< GeoPVConstLink, MDTChamberInfo >::iterator itLastMDTChamberLookedUp
void getMDTChamberXAndZ(ChamberInfoMapItr &itChamberInfo, double &trdX, double &trdZ)
bool clip2DLineSegmentToRectangle(const double &rectX, const double &rectY, double &x0, double &y0, double &x1, double &y1)
double pointToPlaneDistAlongLine(const Amg::Vector3D &point, const Amg::Vector3D &lineDirection, const Amg::Vector3D &planePoint, const Amg::Vector3D &planeNormal)
void projectXZPointToTrdAlongYAxis(const double &x, const double &z, const GeoTrd *trd, Amg::Vector3D &firstEndWall_point, Amg::Vector3D &secondEndWall_point)
bool nameIsMDTChamber(const std::string &n)
bool getMDTChamberVolInfo(const GeoPVConstLink &mdtChamber, ChamberInfoMapItr &itChamberInfo, bool silent=false)
MuonChamberProjectionHelper * theclass
StoreGateSvc * detectorStore
static bool constrainPointToRectangleAlongLine(const double &trdX, const double &trdZ, const double &x0, const double &z0, double &x1, double &z1)
bool isKnownMDTChamber(const GeoPVConstLink &mdtChamber)
bool projectAndConstrainLineSegmentToMDTChamberEndWalls(const GeoPVConstLink &mdtChamber, const Amg::Vector3D &pointA, const Amg::Vector3D &pointB, Amg::Vector3D &firstEndWall_pointA, Amg::Vector3D &firstEndWall_pointB, Amg::Vector3D &secondEndWall_pointA, Amg::Vector3D &secondEndWall_pointB, bool &outsidechamber)
MuonChamberProjectionHelper(StoreGateSvc *detectorStore)
~MuonChamberProjectionHelper()
bool getDistancesToMDTChamberWallsAlongLine(const GeoPVConstLink &mdtChamber, const Amg::Vector3D &point, const Amg::Vector3D &lineDirection, double &distanceToFirstEndPlane, double &distanceToSecondEndPlane, const double &radius=0.0)
static Amg::Vector3D & applyTransformToVector(const Amg::Transform3D &m, Amg::Vector3D &v)
bool clipLineSegmentToMDTChamber(const GeoPVConstLink &mdtChamber, Amg::Vector3D &pointA, Amg::Vector3D &pointB, bool &outsidechamber, const double &extradist=0.0)
The Athena Transient Store API.
VP1HelperClassBase(IVP1System *sys=0, QString helpername="")
void message(const QString &) const
static bool hasMuonGeometry()
bool retrieve(const T *&, const QString &key) const
void setVector3DCartesian(Amg::Vector3D &v1, double x1, double y1, double z1)
Sets components in cartesian coordinate system.
Eigen::Affine3d Transform3D
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Eigen::Matrix< double, 3, 1 > Vector3D
hold the test vectors and ease the comparison