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"
74 double& x1,
double& z1 );
78 double& x0,
double& y0,
double& x1,
double& y1 );
87 if (shape->typeID()==GeoTrd::getClassTypeID())
88 return static_cast<const GeoTrd*
>(shape);
89 if (shape->typeID() == GeoShapeShift::getClassTypeID() ) {
90 const GeoShapeShift* theShift =
static_cast<const GeoShapeShift*
>(shape);
93 if (shape->typeID() == GeoShapeSubtraction::getClassTypeID() ) {
94 const GeoShapeSubtraction* theSubtraction =
static_cast<const GeoShapeSubtraction*
>(shape);
98 if (shape->typeID() == GeoShapeUnion::getClassTypeID() ) {
99 const GeoShapeUnion* theUnion =
static_cast<const GeoShapeUnion*
>(shape);
103 if (shape->typeID() == GeoShapeIntersection::getClassTypeID() ) {
104 const GeoShapeIntersection* theIntersection =
static_cast<const GeoShapeIntersection*
>(shape);
120 message(
"ERROR: Received NULL detectorstore");
128 message(
"ERROR: Received NULL system pointer (and thus can't get detector store pointer");
129 else if (!
m_d->detectorStore)
130 message(
"ERROR: Could not get detectorStore pointer from system pointer");
137 for ( itMDT =
m_d->mdtchambervolinfo.begin(); itMDT!=itMDTE; ++itMDT )
138 itMDT->second.trd->unref();
146 double vx = v.x(), vy = v.y(), vz = v.z();
151 m(0,0)*vx + m(0,1)*vy + m(0,2)*vz,
152 m(1,0)*vx + m(1,1)*vy + m(1,2)*vz,
153 m(2,0)*vx + m(2,1)*vy + m(2,2)*vz);
178 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || n[1]==
'E';
180 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || (n[1]==
'E'&&n[2]==
'E');
188 theclass->messageDebug(
"Warning: Can't init since muon geometry information is not present." );
200 if (!sgaccess->
retrieve( theExpt,
"ATLAS" )) {
201 theclass->message(
"MuonChamberProjectionHelper Error: Can't retrieve"
202 " the ATLAS GeoModelExperiment from detector store.");
209 GeoVolumeCursor av(world);
210 const GeoLogVol * logvol(0);
211 const GeoShape * shape(0);
212 while (!av.atEnd()) {
214 if (av.getName()!=
"Muon") {
219 GeoVolumeCursor av2(av.getVolume());
220 while (!av2.atEnd()) {
222 logvol = av2.getVolume()->getLogVol();
224 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null logvol");
228 shape = logvol->getShape();
230 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null shape");
237 if ( trd->getZHalfLength()>0.0
238 && trd->getXHalfLength1() > 0.0
239 && trd->getXHalfLength2() > 0.0
240 && trd->getYHalfLength1() > 0.0
241 && trd->getYHalfLength2() > 0.0 ) {
246 theclass->message(
"MuonChamberProjectionHelper Error: Chamber trd has non-positive shape parameters!");
249 theclass->message(
"MuonChamberProjectionHelper Error: Chamber shape is not a GeoTrd, and is not a boolean with a Trd somewhere");
258 theclass->message(
"MuonChamberProjectionHelper Error: Found no MDT chambers");
271 return m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo,
true );
277 double& distanceToFirstEndPlane,
double& distanceToSecondEndPlane,
278 const double& radius )
281 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
284 const GeoTrd * trd = itChamberInfo->second.trd;
285 double y1(trd->getYHalfLength1()), y2(trd->getYHalfLength2()),
z(trd->getZHalfLength());
296 distanceToFirstEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p1,n1);
297 if (distanceToFirstEndPlane < 0.0 )
300 distanceToSecondEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p2,n2);
301 if (distanceToSecondEndPlane < 0.0 )
305 double r(fabs(radius));
307 double costheta1 = unitdir.dot(n1.unit());
308 double costheta2 = unitdir.dot(n2.unit());
310 distanceToFirstEndPlane +=
r*sqrt(fabs((1-costheta1*costheta1)/costheta1));
311 distanceToSecondEndPlane +=
r*sqrt(fabs((1-costheta2*costheta2)/costheta2));
321 double denominator(planeNormal.dot(lineDirection)*lineDirection.mag());
322 if (denominator==0.0) {
323 theclass->message(
"MuonChamberProjectionHelper Error: pointToPlaneDistAlongLine is undefined!");
326 double numerator(planeNormal.x() * (planePoint.x() - point.x())
327 + planeNormal.y() * (planePoint.y() - point.y())
328 + planeNormal.z() * (planePoint.z() - point.z()));
329 return fabs(numerator/denominator);
348 theclass->message(
"MuonChamberProjectionHelper Error: Can't find MDT chamber among the "
361 const GeoTrd * trd = itChamberInfo->second.trd;
362 trdX = trd->getXHalfLength1();
363 trdZ = trd->getZHalfLength();
364 if ( trdX != trd->getXHalfLength2() ) {
365 theclass->message(
"MuonChamberProjectionHelper Warning: x1!=x2 in GeoTrd shape. Clippings etc. will be to a too large surface.");
366 if ( trdX < trd->getXHalfLength2() )
367 trdX = trd->getXHalfLength2();
377 bool& outsidechamber )
380 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
384 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
387 itChamberInfo->second.ensureInitGlobalToLocal();
388 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
389 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
395 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
400 m_d->projectXZPointToTrdAlongYAxis( ax, az,itChamberInfo->second.trd, firstEndWall_pointA, secondEndWall_pointA );
401 m_d->projectXZPointToTrdAlongYAxis( bx, bz,itChamberInfo->second.trd, firstEndWall_pointB, secondEndWall_pointB );
408 Amg::transform(firstEndWall_pointA, itChamberInfo->second.localToGlobal);
409 Amg::transform(secondEndWall_pointA, itChamberInfo->second.localToGlobal);
410 Amg::transform(firstEndWall_pointB, itChamberInfo->second.localToGlobal);
411 Amg::transform(secondEndWall_pointB, itChamberInfo->second.localToGlobal);
413 outsidechamber =
false;
421 const double epsilon(0.1);
422 const double trdY1(trd->getYHalfLength1()), trdY2(trd->getYHalfLength2());
423 const double y( trdY1 + 0.5*(1.0+
z/trd->getZHalfLength())*(trdY2-trdY1) );
430 const double& x0,
const double& z0,
431 double& x1,
double& z1 )
441 z1 += (-trdX-x1)*(z1-z0)/(x1-x0);
451 z1 += (trdX-x1)*(z1-z0)/(x1-x0);
461 x1 += (-trdZ-z1)*(x1-x0)/(z1-z0);
471 x1 += (trdZ-z1)*(x1-x0)/(z1-z0);
484 const double & extradist )
487 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
491 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
496 if (trdX<=0.0||trdZ<=0.0)
500 itChamberInfo->second.ensureInitGlobalToLocal();
501 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
502 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
505 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
509 double ay(
A.y()), by(B.y());
517 outsidechamber =
false;
524 double& x0,
double& y0,
double& x1,
double& y1 )
526 if ( fabs(x0)<=rectX && fabs(y0)<=rectY ) {
527 if ( fabs(x1)>rectX || fabs(y1)>rectY ) {
530 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (1)");
533 if ( fabs(x1)<=rectX && fabs(y1)<=rectY ) {
536 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (2)");
548 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (3)");
GeoPhysVol * getPhysVol()
Destructor.
void ensureInitGlobalToLocal()
MDTChamberInfo(const Amg::Transform3D &l2g, const GeoTrd *t)
Amg::Transform3D * globalToLocal
Amg::Transform3D localToGlobal
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