15 #include <utl/MathConstants.h>
16 #include <utl/AugerUnits.h>
17 #include <utl/ErrorLogger.h>
18 #include <utl/Photon.h>
19 #include <utl/Point.h>
20 #include <utl/Vector.h>
21 #include <utl/CoordinateSystemPtr.h>
22 #include <utl/AugerException.h>
23 #include <utl/RandomEngine.h>
26 #include <CLHEP/Random/Randomize.h>
28 #include <det/Detector.h>
30 #include <fdet/FDetector.h>
32 #include <fdet/Telescope.h>
33 #include <fdet/Camera.h>
34 #include <fdet/Pixel.h>
35 #include <fdet/Channel.h>
36 #include <fdet/Mirror.h>
38 #include <TPolyLine3D.h>
42 #include <TPolyMarker3D.h>
46 #include <TObjArray.h>
55 using namespace TelescopeSimulatorKG2;
58 using CLHEP::RandFlat;
63 const bool plotPhotonTracksAtMercedes,
64 const bool simulateMercedesStars,
65 const bool simulateHaloEffects,
66 const bool simulateGhostEffects,
70 fPlotPhotonTracksAtMercedes(plotPhotonTracksAtMercedes),
71 fSimulateMercedesStars(simulateMercedesStars),
72 fSimulateHaloEffects(simulateHaloEffects),
73 fSimulateGhostEffects(simulateGhostEffects),
75 fTelCS(tel.GetTelescopeCoordinateSystem()),
76 fOrigin(0, 0, 0, fTelCS),
77 fRFocal(tel.GetCamera().GetRadiusFocal()),
78 fMercedesEff(tel.GetCamera().GetMercedesEfficiency()),
79 fSigma(tel.GetCamera().GetSigmaNormal()),
80 fRCurv2(
Sqr(tel.GetMirror().GetRadiusOfCurvature()))
103 const double dTheta = 1.5*
deg;
104 const double dPhi = dTheta * cos(30*
deg);
116 const double theta = 16*
deg;
138 if (!
TraceSurf(photonIn, photonCamera)) {
140 photonOut = photonIn;
148 photonOut = photonCamera;
156 const RTResult mercStatus =
TraceMerc(pxlCS, photonCamera, photonOut, nreflections);
167 if (mercStatus ==
eOK)
176 const Vector normalPMT(0, 0, -1, pxlCS);
181 photonsHittingPhotocathode);
182 const utl::Photon& photonRefracted = photonsHittingPhotocathode[0];
193 const double weight = photonCamera.
GetWeight();
194 if (tmpRandNr > photonRefracted.
GetWeight() / weight) {
196 photonOut = photonsHittingPhotocathode[1];
203 photonOut = photonRefracted;
212 photonOut = photonRefracted;
223 const double fNx0 = 10;
224 const double fNy0 = 35 / 3;
226 const double dPhi = 0.5 *
kSqrt3 * dOmega;
234 const double omegap = asin(y);
235 const double phip = atan2(-x, -z);
242 double nxl = 2 * (omegap / dOmega) + 2 * fNx0;
243 double nyl = fNy0 - phip / dPhi;
245 if (nxl < 0 || nxl > 2 * nCols + 1 ||
246 nyl < 0 || nyl > nRows + 1)
254 const double f1 = 3 * nyl - nxl - 1;
255 const double f2 = 3 * nyl + nxl - 2;
260 f = (row % 2) ? f1 : f2;
264 col = col / 2 + (f > 0 ? 0 : 1);
267 col = col / 2 + (f > 0 ? 1 : 0);
274 return col >= 1 && row >= 1 && col <= nCols && row <= nRows;
281 const bool simulateCameraSupport)
289 const bool debug =
false;
302 bool absorbedByCameraBody =
false;
303 const double rCamIn = 1.641*
m;
306 if (intersections.size() != 2)
309 const bool firstIntersection = intersections.front().first.GetPosition().GetZ(
fTelCS) < 0;
321 Photon p(firstIntersection ? intersections.front().first : intersections.back().first);
322 pp =
p.GetPosition();
325 if (x <= (0.86*
m / 2) && y <= (0.93*
m / 2))
326 absorbedByCameraBody =
true;
344 if (absorbedByCameraBody) {
351 if (simulateCameraSupport) {
354 bool absorbedByCamSupport =
false;
360 const double rPhoton2 = (pPlane -
fOrigin).GetMag2();
366 const double ySupportBegin = 35*
cm;
367 const double ySupportEnd = ySupportBegin + 5*
cm;
368 const double zSupportDepth = 10*
cm;
369 if (y >= ySupportBegin && y <= ySupportEnd)
370 absorbedByCamSupport =
true;
377 Photon dummyPhoton = photonOut;
380 if (!absorbedByCamSupport &&
RTFunctions::Plane(pLongerSideSupport1, nLongerSideSupport, photonIn, dummyPhoton)) {
382 if (z <= 0*cm && z >= -zSupportDepth)
383 absorbedByCamSupport =
true;
387 if (!absorbedByCamSupport &&
RTFunctions::Plane(pLongerSideSupport2, nLongerSideSupport, photonIn, dummyPhoton)) {
389 if (z <= 0*cm && z >= -zSupportDepth)
390 absorbedByCamSupport =
true;
394 if (!absorbedByCamSupport &&
RTFunctions::Plane(pLongerSideSupport3, nLongerSideSupport, photonIn, dummyPhoton)) {
396 if (z <= 0*cm && z >= -zSupportDepth)
397 absorbedByCamSupport =
true;
401 if (!absorbedByCamSupport &&
RTFunctions::Plane(pLongerSideSupport4, nLongerSideSupport, photonIn, dummyPhoton)) {
403 if (z <= 0*cm && z >= -zSupportDepth)
404 absorbedByCamSupport =
true;
406 if (absorbedByCamSupport) {
415 const bool firstIntersection = intersections.front().first.GetPosition().GetZ(
fTelCS) < 0;
416 photonOut = firstIntersection ? intersections.front().first : intersections.back().first;
428 photonOut = intersections.front().first;
449 cout <<
"TraceMerc: photon-in"
450 " x=" << setprecision(3) << setw(6) << photon.
GetPosition().
GetX(pxlCS)
451 <<
" y=" << setprecision(3) << setw(6) << photon.
GetPosition().
GetY(pxlCS)
452 <<
" z=" << setprecision(3) << setw(6) << photon.
GetPosition().
GetZ(pxlCS)
453 <<
" nx=" << setprecision(3) << setw(6) << photon.
GetDirection().
GetX(pxlCS)
454 <<
" ny=" << setprecision(3) << setw(6) << photon.
GetDirection().
GetY(pxlCS)
455 <<
" nz=" << setprecision(3) << setw(6) << photon.
GetDirection().
GetZ(pxlCS)
465 bool firstPlane =
true;
466 double closestDist = 0;
467 int closestPlane = 0;
470 const double eps = 0*
mm;
473 for (
int iPlane = 0; iPlane <= 7; ++iPlane) {
475 if (iPlane == iPlanePrev)
480 #warning cache planes for better performance
494 closestPlane = iPlane;
495 nClosestPlane = nPlane;
496 point_next = testPhoton;
498 }
else if (dist < closestDist) {
501 closestPlane = iPlane;
502 nClosestPlane = nPlane;
503 point_next = testPhoton;
512 cout <<
"TraceMerc: nmerc=" << setw(3) << nreflections
513 <<
" x=" << setprecision(3) << setw(6) << point_next.
GetPosition().
GetX(pxlCS)
514 <<
" y=" << setprecision(3) << setw(6) << point_next.
GetPosition().
GetY(pxlCS)
515 <<
" z=" << setprecision(3) << setw(6) << point_next.
GetPosition().
GetZ(pxlCS)
516 <<
" nx=" << setprecision(3) << setw(6) << point_next.
GetDirection().
GetX(pxlCS)
517 <<
" ny=" << setprecision(3) << setw(6) << point_next.
GetDirection().
GetY(pxlCS)
518 <<
" nz=" << setprecision(3) << setw(6) << point_next.
GetDirection().
GetZ(pxlCS)
519 <<
" " << iPlanePrev <<
" -> " << closestPlane
523 iPlanePrev = closestPlane;
530 err <<
" RT::Camera> NO MERCEDES OR PMT HIT! PHOTON invalid! w=" << photonIn.
GetWeight()
531 <<
" closestDist=" << closestDist/
mm <<
" mm";
533 photonOut = photonIn;
538 if (closestPlane == 0) {
545 const utl::Photon& photonRefracted = photonsHittingPhotocathode[0];
551 photonOut = photonRefracted;
562 const double weight = point_next.
GetWeight();
563 if (tmpRandNr > photonRefracted.
GetWeight() / weight) {
565 photon = photonsHittingPhotocathode[1];
569 double amountOfStrayLight = 0;
570 if (amountOfStrayLight > 0) {
571 const double maxTheta = 25 *
degree;
572 const Vector lambertdiffusion =
578 photonOut = photonRefracted;
585 photonOut = photonRefracted;
589 }
else if (closestPlane == 7) {
593 photonOut = point_next;
596 err <<
"Photon backscattered from focal surface towards aperture! ";
612 double amountOfStrayLight = 0;
613 if (amountOfStrayLight > 0 ) {
614 const double maxTheta = 25*
degree;
615 const Vector lambertdiffusion =
668 const double xl = std::fabs(x);
669 const double yl = std::fabs(y);
674 if (xl <= xm && yl <= r - tmp * xl)
699 if (
id == 0 ||
id == 7) {
701 n =
Vector(0, 0,
id == 0 ? 1 : -1 , pxlCS);
705 if (
id > 0 &&
id < 7) {
706 const double dTheta = 60 *
deg;
707 const double theta = dTheta * id;
708 const double sinTheta = sin(theta);
709 const double cosTheta = cos(theta);
711 p =
Point(0.5 * cosTheta *
fD1, 0.5 * sinTheta * fD1, 0, pxlCS);
716 err <<
"This can never happen! Fix TelescopeSimulator. There is no such plane as defined by id=" << id;
725 TObjArray*
const objs =
new TObjArray();
739 for (
int col = 1; col <= nCols; ++col) {
741 for (
int row = 1; row <= nRows; ++row) {
743 const int pixelId = (col - 1) * nRows + row;
746 const double r_in =
fR1;
747 const double r_out =
fR2;
749 for (
int i = 0; i < 6; ++i) {
751 const double theta1 = 30*
deg + 60*
deg * i;
752 const double theta2 = theta1 + 60*
deg;
754 const double s1 = sin(theta1);
755 const double c1 = cos(theta1);
756 const Point p1_in(c1 * r_in, s1 * r_in, 0, pxlCS);
758 const double s2 = sin(theta2);
759 const double c2 = cos(theta2);
760 const Point p2_in(c2 * r_in, s2 * r_in, 0, pxlCS);
762 const Point p1_out(c1 * r_out, s1 * r_out,
fHMerc, pxlCS);
763 const Point p2_out(c2 * r_out, s2 * r_out,
fHMerc, pxlCS);
766 const Point zeroPx(0,0,0, pxlCS);
806 ostringstream pxl_txt;
808 TLatex*
const p_pos =
new TLatex(pxl_x, pxl_y, pxl_txt.str().c_str());
809 p_pos->SetX(pxl_x - p_pos->GetXsize() / 6.);
810 p_pos->SetY(pxl_y - p_pos->GetYsize() / 6.);
811 p_pos->SetTextColor(1);
812 p_pos->SetTextSize(0.01);
813 p_pos->SetTextAngle(0);
815 objs->AddLast(p_pos);
820 TPolyLine3D*
const l_in =
new TPolyLine3D(1);
821 l_in->SetLineColor(2);
827 TPolyLine3D*
const l_out =
new TPolyLine3D(1);
828 l_out->SetLineColor(1);
829 l_out->SetLineStyle(2);
834 objs->AddLast(l_out);
836 TPolyLine3D*
const l_corner =
new TPolyLine3D(1);
837 l_corner->SetLineColor(1);
838 l_corner->SetLineStyle(2);
843 objs->AddLast(l_corner);
849 l_in->SetLineColor(2);
853 l_out->SetLineColor(1);
854 l_out->SetLineStyle(2);
859 objs->AddLast(l_out);
870 const double dx = 5*
cm;
872 const double length = 2*
m;
874 for (
int i = 0; i < 2; ++i) {
876 const double y1 = 30*
cm;
877 const double y2 = 30*
cm + dx;
878 const double z1 = 0*
cm;
879 const double z2 = 10*
cm;
880 const double x1 = 0*
cm;
881 const double x2 = length;
883 TPolyLine3D*
const up =
new TPolyLine3D(4);
884 TPolyLine3D*
const down =
new TPolyLine3D(4);
887 down->SetLineColor(1);
888 down->SetLineWidth(2);
892 for (
int iy = 0; iy < 2; ++iy) {
902 for (
int iz = 0; iz < (do3D ? 2 : 1); ++iz) {
914 TPolyLine3D*
const l =
new TPolyLine3D(1);
std::vector< PhotonNormalPair > IntersectionList
const double fMercedesEff
bool TraceSurf(const utl::Photon &photonIn, utl::Photon &photonOut)
HexagonDirection Hexagon(const double x, const double y, const double r)
constexpr T Sqr(const T &x)
TObjArray * Draw(const bool do3D=true)
RTNext TraceShadow(const utl::Photon &photonIn, utl::Photon &photonOut, const bool doSupport=true)
Base class for all exceptions used in the auger offline code.
RandomEngineType & GetEngine()
void Reflection(const utl::Photon &photonIn, const Vector &normal, utl::Photon &photonOut)
double GetEta() const
Camera angular pixel spacing.
RTNext Trace(const utl::Photon &photonIn, utl::Photon &photonOut, int &nreflections, int &nbackscattered, int &col, int &row)
const bool fPlotPhotonTracksAtMercedes
#define INFO(message)
Macro for logging informational messages.
double GetWeight() const
weight assigned to the photon
double GetMercedesHeight() const
Height of the Mercedes.
void SetPosition(const utl::Point &p)
int Refraction(const double n12, const utl::Photon &photonIn, const Vector &normal, PhotonList &photonsOut)
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
unsigned int GetFirstColumn() const
RTResult TraceMerc(const utl::CoordinateSystemPtr &pxlCS, const utl::Photon &photonIn, utl::Photon &photonOut, int &nreflections)
const Pixel & GetPixel(const unsigned int pixelId) const
Get Pixel by id, throw utl::NonExistentComponentException if n.a.
utl::CoordinateSystemPtr fCameraSupportCoordinateSystem
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
void AddPoint(const utl::Point &p)
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Wraps the random number engine used to generate distributions.
void ConstructPlane(const int id, utl::Vector &n, utl::Point &p, const utl::CoordinateSystemPtr &pxlCS)
const bool fSimulateMercedesStars
double abs(const SVector< n, T > &v)
const fdet::Telescope & fTel
void SetWeight(const double w)
source of the photons. Should use Eye::LightSource enum types
unsigned int GetLastRow() const
AxialVector Normalized(const AxialVector &v)
const utl::Vector & GetDirection() const
const utl::CoordinateSystemPtr & GetPixelCoordinateSystem() const
double GetMercedesBase() const
Base of the Mercedes.
utl::RandomEngine & fRandom
double GetY(const CoordinateSystemPtr &coordinateSystem) const
double Plane(const utl::Point &point, const utl::Vector &normal, const utl::Photon &photonIn, utl::Photon &photonOut)
Detector description interface for Telescope-related data.
Vector LambertDiffusion(utl::RandomEngine &rndm, const Vector &rayIn, const Vector &normal, const double amountOfStrayLight, const double MaxTheta)
utl::CoordinateSystemPtr fTelCS
bool Sphere(const Point &origin, const double radius, const utl::Photon &photonIn, IntersectionList &intersection)
unsigned int GetLastColumn() const
std::vector< utl::Photon > PhotonList
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
const bool fSimulateHaloEffects
bool FindPixelId(const utl::Vector &incidentDir, int &row, int &col) const
#define ERROR(message)
Macro for logging error messages.
unsigned int GetFirstRow() const
void SetDirection(const utl::Vector &v)
const bool fSimulateGhostEffects
RayTracer::Track * fPhotonTrack
const utl::Point & GetPosition() const