13 #include <utl/MathConstants.h>
14 #include <utl/AugerUnits.h>
15 #include <utl/ErrorLogger.h>
16 #include <utl/Photon.h>
17 #include <utl/Point.h>
18 #include <utl/Vector.h>
19 #include <utl/CoordinateSystemPtr.h>
20 #include <utl/RandomEngine.h>
21 #include <utl/TabulatedFunction.h>
23 #include <fdet/Telescope.h>
24 #include <fdet/Mirror.h>
26 #include <CLHEP/Random/Randomize.h>
28 #include <TPolyLine3D.h>
29 #include <TObjArray.h>
33 using namespace TelescopeSimulatorKG2;
37 using CLHEP::RandFlat;
38 using CLHEP::RandGauss;
48 const double mirrorSize,
49 const double mirrorSegmentSigma,
50 const double mirrorRadiusSigma,
51 const double mirrorAbsorptionTop,
52 const double mirrorAbsorptionBot,
56 fMirrorSize(mirrorSize),
57 fMirrorSegmentSigma(mirrorSegmentSigma),
58 fMirrorRadiusSigma(mirrorRadiusSigma),
59 fMirrorAbsorptionTop(mirrorAbsorptionTop),
60 fMirrorAbsorptionBot(mirrorAbsorptionBot),
61 fMirrorDiffusionTop(mirrorDiffusionTop),
62 fMirrorDiffusionBot(mirrorDiffusionBot),
63 fTelCS(tel.GetTelescopeCoordinateSystem()),
64 fOrigin(0,0,0, fTelCS),
65 fReflectivity(tel.GetMirror().GetReflectivity()),
66 fRCurv(tel.GetMirror().GetRadiusOfCurvature()),
67 fSigma(tel.GetMirror().GetSigmaNormal())
77 err <<
"Missed Mirror : nDir>0";
84 if (sphereStatus <= 0) {
87 err <<
"Missed Mirror : " << sphereStatus <<
" !!!";
94 photonOut = intersections.back().first;
95 Vector normal = intersections.back().second;
103 const double horizontalPosOnMirror = asin(posOnSphere.
GetY(
fTelCS) /
fRCurv);
120 const bool HARDDEBUG =
false;
124 const double mirrorGapWidth = 5*
mm;
125 const double angGapWidth = 2 *
fRCurv * asin(0.5*mirrorGapWidth /
fRCurv);
126 const double mirrorSegmentHeight = 650*
mm;
127 const double mirrorSegmentAngWidth = 2 *
fRCurv * asin(0.5*mirrorSegmentHeight /
fRCurv);
140 const double& x = xyz.get<0>();
143 if (
abs(x) > nSeg*mirrorSegmentHeight) {
146 const double& y = xyz.get<1>();
147 const double& z = -xyz.get<2>();
148 const double phi =
fRCurv * atan2(y, z);
150 if (
abs(phi) > nSeg*mirrorSegmentAngWidth) {
153 const double h =
abs(x -
int(x/mirrorSegmentHeight) * mirrorSegmentHeight);
155 if (h < mirrorGapWidth)
158 const double w =
abs(phi -
int(phi/mirrorSegmentAngWidth) * mirrorSegmentAngWidth);
163 const double dh = h - 0.5*mirrorSegmentHeight;
164 const double dw = w - 0.5*mirrorSegmentHeight;
165 const double holeRadius = 10 *
mm;
167 if (dh*dh + dw*dw < holeRadius*holeRadius)
170 const double xe = 0.5 * mirrorSegmentHeight -
abs(dh);
171 const double ye = 0.5 * mirrorSegmentHeight -
abs(dw);
172 const double d = 20 *
mm;
182 const double mirrorGapWidth = 5*
mm;
183 const double angGapWidth = 2 *
fRCurv * asin(0.5*mirrorGapWidth /
fRCurv);
184 const double mirrorSegmentHeight = 624.7*
mm;
185 const double mirrorSegmentHalfWidth = 0.5 * 541*
mm;
186 const double mirrorSegmentAngHalfWidth = 2 *
fRCurv * asin(0.5*mirrorSegmentHalfWidth /
fRCurv);
190 const double& x = xyz.get<0>();
191 const double& y = xyz.get<1>();
192 const double& z = -xyz.get<2>();
193 const double phi =
fRCurv * atan2(y, z);
195 const vector<double> segEle {-3.98*
deg, 11.9316*
deg, -19.9279*
deg, 28.0239*
deg};
196 const vector<double> segSideHight {((488.15 - 155.15) / 2) *
mm, ((467.87 - 143.99) / 2) *
mm,
197 ((466.56 - 151.11) / 2) *
mm, ((472.67 - 133.77) / 2) *
mm};
200 if (!lost &&
abs(x) > 3*mirrorSegmentHeight)
203 if (!lost &&
abs(phi) > 8.3*mirrorSegmentAngHalfWidth)
208 const double w =
abs(phi -
int(phi/mirrorSegmentAngHalfWidth) * mirrorSegmentAngHalfWidth);
209 if (w < angGapWidth) {
210 const bool odd = bool(
int(phi/mirrorSegmentAngHalfWidth)%2);
211 const int s = odd ? 1 : -1;
212 for (
unsigned int i = 0; i < 4; ++i) {
213 const double theta =
fRCurv * (atan2(-x, z) + s * segEle.at(i));
214 if (
abs(theta) < segSideHight.at(i))
222 const bool odd = bool(
int(phi/mirrorSegmentAngHalfWidth)%2);
223 const int s = odd ? 1 : -1;
224 const double holeRadius = 15*
mm;
225 for (
unsigned int i = 0; i < 4; ++i) {
226 const double dPhi_halfSegm = 4.53952*
deg;
227 const double dPhi0 = odd ? dPhi_halfSegm : 0*
deg;
228 for (
unsigned int j = 0; j < 4; ++j) {
229 const double thetaA =
fRCurv * (atan2(-x, z) - s * segEle.at(i));
230 double phiA =
fRCurv * (atan2(y, z) + j * 2 * dPhi_halfSegm + dPhi0);
231 if (thetaA*thetaA + phiA*phiA < holeRadius*holeRadius)
233 phiA =
fRCurv * (atan2(y, z) - j * 2 * dPhi_halfSegm - dPhi0);
234 if (thetaA*thetaA + phiA*phiA < holeRadius*holeRadius)
261 if (sphereStatus2 <= 0) {
262 photonOut = photonIn;
264 err <<
"Missed MirrorSegment : status=" << sphereStatus2 <<
" index=" << ms.
index <<
" !!!";
268 photonOut = intersections.back().first;
269 normal = intersections.back().second;
289 const Vector mirrordiffusion =
310 const int ix = x / segmentWidth - (x < 0 ? 1 : 0);
311 const int iy = y / segmentWidth - (y < 0 ? 1 : 0);
312 const int index = ix * 1000 + iy;
317 const double centerSegmentX = (0.5 + ix) * segmentWidth;
318 const double centerSegmentY = (0.5 + iy) * segmentWidth;
319 const double centerSegmentZ = -
sqrt(
pow(
fRCurv, 2) -
pow(centerSegmentX, 2) -
pow(centerSegmentY, 2));
320 const Point centerSegment(centerSegmentX, centerSegmentY, centerSegmentZ,
fTelCS);
323 const double elevationSegment = atan(centerSegmentX /
fRCurv);
327 CoordinateSystemPtr aux3CS = CoordinateSystem::RotationX((centerSegmentY < 0 ? -1 : 1) * (-dirSegment).GetTheta(aux2CS), aux2CS);
338 const Vector delta(0,0,1, msCS);
339 const Point originPrime(centerSegment + delta * radius);
352 TObjArray*
const objs =
new TObjArray();
359 const int nSubSeg = 3;
361 const double segWidth = width / nSeg;
365 for (
int i = 0; i < nSeg; ++i) {
367 for (
int j = 0; j < nSeg; ++j) {
371 const double x_mir = -
gMirrorWidth / 2 + (0.5 + i) * segWidth;
372 const double y_mir = -
gMirrorWidth / 2 + (0.5 + j) * segWidth;
376 const double r = ms.
radius;
378 const double d = segWidth / nSubSeg;
387 for (
int k = 0; k < nSubSeg; ++k) {
389 for (
int l = 0; l < nSubSeg; ++l) {
391 const double x1 = -segWidth / 2 + k * d;
392 const double y1 = -segWidth / 2 + l * d;
393 const double z1 = r -
sqrt(
pow(r, 2) -
pow(x1, 2) -
pow(y1, 2));
394 const Point p1(x1, y1, z1, ms.
cs);
398 const double x2 = -segWidth / 2 + (k + 1) * d;
399 const double y2 = -segWidth / 2 + l * d;
400 const double z2 = r -
sqrt(
pow(r, 2) -
pow(x2, 2) -
pow(y2, 2));
401 const Point p2(x2, y2, z2, ms.
cs);
403 const double x3 = -segWidth / 2 + k * d;
404 const double y3 = -segWidth / 2 + (l + 1) * d;
405 const double z3 = r -
sqrt(
pow(r, 2) -
pow(x3, 2) -
pow(y3, 2));
406 const Point p3(x3, y3, z3, ms.
cs);
408 const double x4 = -segWidth / 2 + (k + 1) * d;
409 const double y4 = -segWidth / 2 + (l + 1) * d;
410 const double z4 = r -
sqrt(
pow(r, 2) -
pow(x4, 2) -
pow(y4, 2));
411 const Point p4(x4, y4, z4, ms.
cs);
413 TPolyLine3D*
const l1 =
new TPolyLine3D(5);
414 l1->SetLineColor(color);
415 l1->SetLineWidth(size);
std::vector< PhotonNormalPair > IntersectionList
utl::CoordinateSystemPtr cs
const double fMirrorAbsorptionTop
const double fMirrorAbsorptionBot
RandomEngineType & GetEngine()
void Reflection(const utl::Photon &photonIn, const Vector &normal, utl::Photon &photonOut)
Class to hold collection (x,y) points and provide interpolation between them.
utl::CoordinateSystemPtr fTelCS
utl::RandomEngine & fRandom
const double fMirrorSegmentSigma
void Absorption(const utl::Photon &photonIn, const double filterAbsorptionFactor, utl::Photon &photonOut)
double pow(const double x, const unsigned int i)
std::map< int, MirrorSegment > fSegments
RTNext Trace(const utl::Photon &photonIn, utl::Photon &photonOut)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
boost::tuple< double, double, double > Triple
Coordinate triple for easy getting or setting of coordinates.
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Wraps the random number engine used to generate distributions.
double abs(const SVector< n, T > &v)
Vector MirrorDiffusion(utl::RandomEngine &rndm, const Vector &specularDir, const utl::TabulatedFunction *mirrorDiffusionTop, const utl::TabulatedFunction *mirrorDiffusionBot, const double verticalPosOnMirror)
const utl::TabulatedFunction *const fMirrorDiffusionTop
Mirror(utl::RandomEngine &rndm, const fdet::Telescope &tel, const double mirrorSize, const double mirrorSegmentSigma, const double mirrorRadiusSigma, const double mirrorAbsorptionTop, const double mirrorAbsorptionBot, const utl::TabulatedFunction *const mirrorDiffusionTop, const utl::TabulatedFunction *const mirrorDiffusionBot)
const utl::TabulatedFunction *const fMirrorDiffusionBot
const utl::Vector & GetDirection() const
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Detector description interface for Telescope-related data.
bool Sphere(const Point &origin, const double radius, const utl::Photon &photonIn, IntersectionList &intersection)
const utl::TabulatedFunction & fReflectivity
double GetWavelength() const
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
#define ERROR(message)
Macro for logging error messages.
const double fMirrorRadiusSigma
const double gMirrorWidth
void SetDirection(const utl::Vector &v)
MirrorSegment & GetMirrorSegment(const utl::Point &p)
const utl::Point & GetPosition() const