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();
163 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || n[1]==
'E';
165 return n[1]==
'I' || n[1]==
'M' || n[1]==
'O' || (n[1]==
'E'&&n[2]==
'E');
173 theclass->messageDebug(
"Warning: Can't init since muon geometry information is not present." );
185 if (!sgaccess->
retrieve( theExpt,
"ATLAS" )) {
186 theclass->message(
"MuonChamberProjectionHelper Error: Can't retrieve"
187 " the ATLAS GeoModelExperiment from detector store.");
194 GeoVolumeCursor av(world);
195 const GeoLogVol * logvol(0);
196 const GeoShape * shape(0);
197 while (!av.atEnd()) {
199 if (av.getName()!=
"Muon") {
204 GeoVolumeCursor av2(av.getVolume());
205 while (!av2.atEnd()) {
207 logvol = av2.getVolume()->getLogVol();
209 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null logvol");
213 shape = logvol->getShape();
215 theclass->message(
"MuonChamberProjectionHelper Error: Chamber has null shape");
222 if ( trd->getZHalfLength()>0.0
223 && trd->getXHalfLength1() > 0.0
224 && trd->getXHalfLength2() > 0.0
225 && trd->getYHalfLength1() > 0.0
226 && trd->getYHalfLength2() > 0.0 ) {
231 theclass->message(
"MuonChamberProjectionHelper Error: Chamber trd has non-positive shape parameters!");
234 theclass->message(
"MuonChamberProjectionHelper Error: Chamber shape is not a GeoTrd, and is not a boolean with a Trd somewhere");
243 theclass->message(
"MuonChamberProjectionHelper Error: Found no MDT chambers");
256 return m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo,
true );
262 double& distanceToFirstEndPlane,
double& distanceToSecondEndPlane,
263 const double& radius )
266 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
269 const GeoTrd * trd = itChamberInfo->second.trd;
270 double y1(trd->getYHalfLength1()), y2(trd->getYHalfLength2()),
z(trd->getZHalfLength());
276 n1 = itChamberInfo->second.localToGlobal.linear()* n1;
277 n2 = itChamberInfo->second.localToGlobal.linear()* n2;
281 distanceToFirstEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p1,n1);
282 if (distanceToFirstEndPlane < 0.0 )
285 distanceToSecondEndPlane =
m_d->pointToPlaneDistAlongLine(point,lineDirection,p2,n2);
286 if (distanceToSecondEndPlane < 0.0 )
290 double r(fabs(radius));
292 double costheta1 = unitdir.dot(n1.unit());
293 double costheta2 = unitdir.dot(n2.unit());
295 distanceToFirstEndPlane +=
r*sqrt(fabs((1-costheta1*costheta1)/costheta1));
296 distanceToSecondEndPlane +=
r*sqrt(fabs((1-costheta2*costheta2)/costheta2));
306 double denominator(planeNormal.dot(lineDirection)*lineDirection.mag());
307 if (denominator==0.0) {
308 theclass->message(
"MuonChamberProjectionHelper Error: pointToPlaneDistAlongLine is undefined!");
311 double numerator(planeNormal.x() * (planePoint.x() - point.x())
312 + planeNormal.y() * (planePoint.y() - point.y())
313 + planeNormal.z() * (planePoint.z() - point.z()));
314 return fabs(numerator/denominator);
333 theclass->message(
"MuonChamberProjectionHelper Error: Can't find MDT chamber among the "
346 const GeoTrd * trd = itChamberInfo->second.trd;
347 trdX = trd->getXHalfLength1();
348 trdZ = trd->getZHalfLength();
349 if ( trdX != trd->getXHalfLength2() ) {
350 theclass->message(
"MuonChamberProjectionHelper Warning: x1!=x2 in GeoTrd shape. Clippings etc. will be to a too large surface.");
351 if ( trdX < trd->getXHalfLength2() )
352 trdX = trd->getXHalfLength2();
362 bool& outsidechamber )
365 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
369 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
372 itChamberInfo->second.ensureInitGlobalToLocal();
373 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
374 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
380 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
385 m_d->projectXZPointToTrdAlongYAxis( ax, az,itChamberInfo->second.trd, firstEndWall_pointA, secondEndWall_pointA );
386 m_d->projectXZPointToTrdAlongYAxis( bx, bz,itChamberInfo->second.trd, firstEndWall_pointB, secondEndWall_pointB );
389 firstEndWall_pointA = itChamberInfo->second.localToGlobal * firstEndWall_pointA;
390 secondEndWall_pointA = itChamberInfo->second.localToGlobal * secondEndWall_pointA;
391 firstEndWall_pointB = itChamberInfo->second.localToGlobal * firstEndWall_pointB;
392 secondEndWall_pointB = itChamberInfo->second.localToGlobal * secondEndWall_pointB;
394 outsidechamber =
false;
402 const double epsilon(0.1);
403 const double trdY1(trd->getYHalfLength1()), trdY2(trd->getYHalfLength2());
404 const double y( trdY1 + 0.5*(1.0+
z/trd->getZHalfLength())*(trdY2-trdY1) );
411 const double& x0,
const double& z0,
412 double& x1,
double& z1 )
422 z1 += (-trdX-x1)*(z1-z0)/(x1-x0);
432 z1 += (trdX-x1)*(z1-z0)/(x1-x0);
442 x1 += (-trdZ-z1)*(x1-x0)/(z1-z0);
452 x1 += (trdZ-z1)*(x1-x0)/(z1-z0);
465 const double & extradist )
468 if (!
m_d->getMDTChamberVolInfo( mdtChamber, itChamberInfo ))
472 m_d->getMDTChamberXAndZ(itChamberInfo, trdX, trdZ );
477 if (trdX<=0.0||trdZ<=0.0)
481 itChamberInfo->second.ensureInitGlobalToLocal();
482 Amg::Vector3D A((*(itChamberInfo->second.globalToLocal))*pointA), B((*(itChamberInfo->second.globalToLocal))*pointB);
483 double ax(
A.x()), az(
A.z()), bx(B.x()), bz(B.z());
486 outsidechamber = !(
m_d->clip2DLineSegmentToRectangle( trdX, trdZ, ax, az, bx, bz ));
490 double ay(
A.y()), by(B.y());
494 pointA = itChamberInfo->second.localToGlobal *
Amg::Vector3D{ax,ay,az};
495 pointB = itChamberInfo->second.localToGlobal *
Amg::Vector3D{bx,by,bz};
496 outsidechamber =
false;
503 double& x0,
double& y0,
double& x1,
double& y1 )
505 if ( fabs(x0)<=rectX && fabs(y0)<=rectY ) {
506 if ( fabs(x1)>rectX || fabs(y1)>rectY ) {
509 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (1)");
512 if ( fabs(x1)<=rectX && fabs(y1)<=rectY ) {
515 theclass->message(
"MuonChamberProjectionHelper Error: Should never happen (2)");
527 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)
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
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
hold the test vectors and ease the comparison