diff --git a/src/Classic/AbsBeamline/Bend2D.cpp b/src/Classic/AbsBeamline/Bend2D.cpp index 87a0f7e5feda0db756a6df481fe24e0fc231979e..4f64a29f09f2161d0a5d96330fd799dbf6d2223c 100644 --- a/src/Classic/AbsBeamline/Bend2D.cpp +++ b/src/Classic/AbsBeamline/Bend2D.cpp @@ -1680,4 +1680,37 @@ std::array<double,2> Bend2D::getExitFringeFieldLength() const { extFFL[1] = ( exitParameter2_m-exitParameter1_m ); //before edge return extFFL; -} \ No newline at end of file +} + +BoundaryBox Bend2D::getBoundaryBoxInLabCoords() const { + CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m; + CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m; + + double &x = aperture_m.second[0]; + double &y = aperture_m.second[1]; + + std::vector<Vector_t> corners(8); + for (int i = -1; i < 2; i += 2) { + for (int j = -1; j < 2; j += 2) { + unsigned int idx = (i + 1)/2 + (j + 1); + corners[idx] = toBegin.transformFrom(Vector_t(i * x, j * y, 0.0)); + corners[idx + 4] = toEnd.transformFrom(Vector_t(i * x, j * y, 0.0)); + } + } + + BoundingBox bb; + bb.lowerLeftCorner = bb.upperRightCorner = corners[0]; + + for (unsigned int i = 1; i < 8u; ++ i) { + for (unsigned int d; d < 3u; ++ d) { + if (bb.lowerLeftCorner(d) > corners[i](d)) { + bb.lowerLeftCorner(d) = corners[i](d); + } + if (bb.upperLeftCorner(d) < corners[i](d)) { + bb.upperLeftCorner(d) = corners[i](d); + } + } + } + + return bb; +} diff --git a/src/Classic/AbsBeamline/Bend2D.h b/src/Classic/AbsBeamline/Bend2D.h index 2ffdaf73a532b45648de047c025aefef1ac17024..d8b7638c2d20e3aa73560cf2f59e052b020a8623 100644 --- a/src/Classic/AbsBeamline/Bend2D.h +++ b/src/Classic/AbsBeamline/Bend2D.h @@ -129,6 +129,7 @@ public: // Used to create fringe fields in ThickTracker, (before edge[m], after edge[m]) std::array<double,2> getExitFringeFieldLength() const; + BoundaryBox getBoundaryBoxInLabCoords() const override; protected: void setMessageHeader(const std::string & header); double getStartField() const; @@ -375,5 +376,4 @@ Vector_t Bend2D::transformToExitRegion(const Vector_t &R) const { return toExitRegion_m.transformTo(R); } -#endif // CLASSIC_BEND_H - +#endif // CLASSIC_BEND_H \ No newline at end of file diff --git a/src/Classic/AbsBeamline/BendBase.h b/src/Classic/AbsBeamline/BendBase.h index 58da2fbcc89d907b58c2cd308510104db4d9f082..a2bfeb41dc6e3d788d1cabe073dddc1799ed35d9 100644 --- a/src/Classic/AbsBeamline/BendBase.h +++ b/src/Classic/AbsBeamline/BendBase.h @@ -37,7 +37,6 @@ public: void setFieldMapFN(std::string fileName); std::string getFieldMapFN() const; - protected: /// Calculate design radius from design energy and field amplitude double calcDesignRadius(double fieldAmplitude) const; diff --git a/src/Classic/AbsBeamline/ElementBase.cpp b/src/Classic/AbsBeamline/ElementBase.cpp index fe4fde06cbca89180158da48edcb40f116a25ef7..180a10e7e749ceeef419f817be2ce46c65303b1b 100644 --- a/src/Classic/AbsBeamline/ElementBase.cpp +++ b/src/Classic/AbsBeamline/ElementBase.cpp @@ -304,4 +304,64 @@ void ElementBase::setCurrentSCoordinate(double s) { elementEdge_m = actionRange_m.front().first; } } +} + +bool ElementBase::isInsideTransverse(const Vector_t &r) const +{ + double x = aperture_m.second[0]; + double y = aperture_m.second[1]; + double f = 1.0; + if (aperture_m.first == CONIC_RECTANGULAR || + aperture_m.first == CONIC_ELLIPTIC) { + Vector_t rRelativeToBegin = getEdgeToBegin().transformTo(r); + double fractionLength = rRelativeToBegin(2) / getElementLength(); + f = fractionLength * aperture_m.second[2]; + } + + switch(aperture_m.first) { + case RECTANGULAR: + return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]); + case ELLIPTICAL: + return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0); + case CONIC_RECTANGULAR: + return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]); + case CONIC_ELLIPTICAL: + return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0); + default: + return false; + } +} + +BoundaryBox ElementBase::getBoundaryBoxInLabCoords() const { + CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m; + CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m; + + double &x = aperture_m.second[0]; + double &y = aperture_m.second[1]; + double &f = aperture_m.second[2]; + + std::vector<Vector_t> corners(8); + for (int i = -1; i < 2; i += 2) { + for (int j = -1; j < 2; j += 2) { + unsigned int idx = (i + 1)/2 + (j + 1); + corners[idx] = toBegin.transformFrom(Vector_t(i * x, j * y, 0.0)); + corners[idx + 4] = toEnd.transformFrom(Vector_t(i * f * x, j * f * y, 0.0)); + } + } + + BoundingBox bb; + bb.lowerLeftCorner = bb.upperRightCorner = corners[0]; + + for (unsigned int i = 1; i < 8u; ++ i) { + for (unsigned int d; d < 3u; ++ d) { + if (bb.lowerLeftCorner(d) > corners[i](d)) { + bb.lowerLeftCorner(d) = corners[i](d); + } + if (bb.upperLeftCorner(d) < corners[i](d)) { + bb.upperLeftCorner(d) = corners[i](d); + } + } + } + + return bb; } \ No newline at end of file diff --git a/src/Classic/AbsBeamline/ElementBase.h b/src/Classic/AbsBeamline/ElementBase.h index be1623b55e51d6706dbd53958554efa3db1e1679..aaa2fd5a4bcd07f3c33cf7d02c59fffa2f431e46 100644 --- a/src/Classic/AbsBeamline/ElementBase.h +++ b/src/Classic/AbsBeamline/ElementBase.h @@ -359,6 +359,8 @@ public: void setRotationAboutZ(double rotation); double getRotationAboutZ() const; + virtual BoundaryBox getBoundaryBoxInLabCoords() const; + protected: bool isInsideTransverse(const Vector_t &r, double f = 1) const; @@ -531,24 +533,7 @@ inline bool ElementBase::isInside(const Vector_t &r) const { const double length = getElementLength(); - return isInsideTransverse(r, r(2) / length * aperture_m.second[2]) && r(2) >= 0.0 && r(2) < length; -} - -inline -bool ElementBase::isInsideTransverse(const Vector_t &r, double f) const -{ - switch(aperture_m.first) { - case RECTANGULAR: - return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]); - case ELLIPTICAL: - return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0); - case CONIC_RECTANGULAR: - return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]); - case CONIC_ELLIPTICAL: - return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0); - default: - return false; - } + return r(2) >= 0.0 && r(2) < length && isInsideTransverse(r); } inline diff --git a/src/Elements/OpalRBend.cpp b/src/Elements/OpalRBend.cpp index 0f1b9e0be8c28d849f5a493ee21c4a8839024680..af1f3327e64a4f244ac27cb8cded0370bbd57d55 100644 --- a/src/Elements/OpalRBend.cpp +++ b/src/Elements/OpalRBend.cpp @@ -189,7 +189,11 @@ void OpalRBend::update() { if(itsAttr[HAPERT]) { double hapert = Attributes::getReal(itsAttr[HAPERT]); - bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({hapert, hapert, 1.0})); + double gap = Attributes::getReal(itsAttr[GAP]); + bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({hapert, gap, 1.0})); + } else { + double gap = Attributes::getReal(itsAttr[GAP]); + bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({0.5, gap, 1.0}); } if(itsAttr[LENGTH]) @@ -216,4 +220,4 @@ void OpalRBend::update() { // Transmit "unknown" attributes. OpalElement::updateUnknown(bend); -} +} \ No newline at end of file