139#include "TRestAxionOptics.h"
148#include "TRestPhysics.h"
173 RESTDebug <<
"Entering TRestAxionOptics constructor( cfgFileName, name )" <<
RESTendl;
174 RESTDebug <<
"File: " << cfgFileName <<
" Name: " << name <<
RESTendl;
252 RESTDebug <<
"TRestAxionOptics::TransportToEntrance" <<
RESTendl;
254 RESTWarning <<
"TRestAxionOptics::TransportToEntrance" <<
RESTendl;
255 RESTWarning <<
"The particle should be placed before the entrance!" <<
RESTendl;
259 RESTWarning <<
"TRestAxionOptics::TransportToEntrance" <<
RESTendl;
260 RESTWarning <<
"Photon is not moving on the positive Z-direction!" <<
RESTendl;
281 RESTDebug <<
"TRestAxionOptics::TransportToMiddle" <<
RESTendl;
283 RESTWarning <<
"TRestAxionOptics::TransportToMiddle" <<
RESTendl;
284 RESTWarning <<
"The particle should be placed between entrance and middle!" <<
RESTendl;
288 RESTWarning <<
"TRestAxionOptics::TransportToMiddle" <<
RESTendl;
289 RESTWarning <<
"Photon is not moving on the positive Z-direction!" <<
RESTendl;
290 RESTWarning <<
"Direction : ( " << dir.X() <<
", " << dir.Y() <<
", " << dir.Z() <<
")" <<
RESTendl;
312 RESTDebug <<
"TRestAxionOptics::TransportToExit" <<
RESTendl;
314 RESTWarning <<
"TRestAxionOptics::TransportToExit" <<
RESTendl;
315 RESTWarning <<
"The particle should be placed between middle and exit!" <<
RESTendl;
319 RESTWarning <<
"TRestAxionOptics::TransportToExit" <<
RESTendl;
320 RESTWarning <<
"Photon is not moving on the positive Z-direction!" <<
RESTendl;
383 RESTDebug <<
" --> Entering TRestAxionOptics::PropagatePhoton" <<
RESTendl;
385 RESTDebug <<
"Reseting positions" <<
RESTendl;
393 RESTDebug <<
"Entrance region : " << entranceRegion <<
RESTendl;
395 if (entranceRegion == 0)
return 0.0;
407 RESTDebug <<
"Middle region : " << middleRegion <<
RESTendl;
408 if (middleRegion != entranceRegion)
return 0.0;
417 RESTDebug <<
"Exit region : " << exitRegion <<
RESTendl;
418 if (exitRegion != middleRegion)
return 0.0;
447 RESTMetadata <<
"---------" <<
RESTendl;
452 RESTMetadata <<
"---------" <<
RESTendl;
454 RESTMetadata <<
" Use \"this->PrintMasks()\" to get masks info" <<
RESTendl;
455 RESTMetadata <<
" Use \"this->PrintMirror()\" to get mirror info" <<
RESTendl;
456 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
482 RESTWarning <<
"TRestAxionOptics::PrintEntranceMask. Not available" <<
RESTendl;
492 RESTWarning <<
"TRestAxionOptics::PrintMiddleMask. Not available" <<
RESTendl;
502 RESTWarning <<
"TRestAxionOptics::PrintExitMask. Not available" <<
RESTendl;
510 std::cout <<
"Photon tracking summary" << std::endl;
511 std::cout <<
"-----------------------" << std::endl;
521 std::cout <<
"Entrance radius : "
535 std::cout <<
"Middle radius : "
549 std::cout <<
"Exit radius : "
552 std::cout <<
"-----------------------" << std::endl;
560 if (
fPad !=
nullptr) {
565 fPad =
new TPad(
"optics_pad",
"This is the optics drawing pad", 0.01, 0.02, 0.99, 0.97);
566 if (nx > 1 || ny > 1)
fPad->Divide(nx, ny);
568 fPad->SetRightMargin(0.09);
569 fPad->SetLeftMargin(0.2);
570 fPad->SetBottomMargin(0.15);
582 Double_t reflectivity = 1.;
586 angle = angle *
units(
"deg") /
units(
"rad") / 2.;
593 angle = angle *
units(
"deg") /
units(
"rad") / 2.;
611 for (
int n = 0; n < particles; n++) {
613 Double_t angle =
fRandom->Uniform(0, 2 * TMath::Pi());
614 TVector3 origin(r * TMath::Cos(angle), r * TMath::Sin(angle), -3 *
fMirrorLength);
615 TVector3 direction(
fRandom->Uniform(-deviation, deviation),
fRandom->Uniform(-deviation, deviation),
617 direction = direction.Unit();
623 TGraph* gr =
new TGraph();
625 Double_t rO = TMath::Sqrt(origin.X() * origin.X() + origin.Y() * origin.Y());
626 gr->SetPoint(gr->GetN(), origin.Z(), rO);
645 if (rMiddle > 0) gr->SetPoint(gr->GetN(),
fMiddlePosition.Z(), rMiddle);
658 if (rExit > 0) gr->SetPoint(gr->GetN(),
fExitPosition.Z(), rExit);
662 if (reflectivity > 0) {
665 Double_t rEnd = TMath::Sqrt(end.X() * end.X() + end.Y() * end.Y());
666 if (rEnd > 0) gr->SetPoint(gr->GetN(), end.Z(), rEnd);
673 gr->SetLineColor(kBlack);
696 Bool_t recalculate, Int_t particles) {
697 RESTDebug <<
"Entering TRestAxionOptics::FindFocal" <<
RESTendl;
701 Double_t focal = (from + to) / 2.;
704 Double_t step = (to - from) / 10.;
710 step = (to - from) / 10.;
713 RESTInfo <<
"Calculating focal : " << focal <<
RESTendl;
714 for (Double_t f = from; f < to; f += step) {
716 if (size < spotSize) {
722 if (step > precision)
return FindFocal(focal - step, focal + step, energy, precision, recalculate);
742 Double_t deviation = 0;
743 for (
int n = 0; n < particles; n++) {
746 if (reflectivity == 0)
continue;
750 Double_t x = posZ.X();
751 Double_t y = posZ.Y();
753 sum += reflectivity * x * x + y * y;
757 if (nSum > 0) sum = TMath::Sqrt(sum / nSum);
772 Double_t r2 = x * x + y * y;
780 Double_t angle =
fRandom->Uniform(0, 2 * TMath::Pi());
781 TVector3 origin(r * TMath::Cos(angle), r * TMath::Sin(angle), -3 *
fMirrorLength);
783 Double_t theta =
fRandom->Uniform(0, deviation);
784 Double_t phi =
fRandom->Uniform(0, 2 * TMath::Pi());
786 TVector3 direction(0, 0, 1);
787 direction.SetTheta(theta);
788 direction.SetPhi(phi);
789 direction.SetMag(1.);
801 Double_t focalHint) {
806 TGraph* grEntrance =
new TGraph();
807 TGraph* grExit =
new TGraph();
808 TGraph* grZ =
new TGraph();
809 TGraph* grFocal =
new TGraph();
811 Double_t focal =
FindFocal(focalHint - 500, focalHint + 500, energy, 1);
813 for (
int n = 0; n < particles; n++) {
819 if (reflectivity == 0)
continue;
824 grZ->SetPoint(grZ->GetN(), posZ.X(), posZ.Y());
827 TVector3(0, 0, focal));
828 grFocal->SetPoint(grFocal->GetN(), posFocal.X(), posFocal.Y());
834 grEntrance->GetHistogram()->SetMaximum(
GetRadialLimits().second * 1.15);
835 grEntrance->GetHistogram()->SetMinimum(-
GetRadialLimits().second * 1.15);
837 grEntrance->SetTitle(
"Entrance plane");
838 grEntrance->GetXaxis()->SetTitle(
"X [mm]");
839 grEntrance->GetXaxis()->SetTitleSize(0.04);
840 grEntrance->GetXaxis()->SetLabelSize(0.04);
841 grEntrance->GetXaxis()->SetNdivisions(5);
842 grEntrance->GetYaxis()->SetTitle(
"Y [mm]");
843 grEntrance->GetYaxis()->SetTitleOffset(1.4);
844 grEntrance->GetYaxis()->SetTitleSize(0.04);
845 grEntrance->GetYaxis()->SetLabelSize(0.04);
847 grEntrance->SetMarkerStyle(1);
848 grEntrance->Draw(
"AP");
852 grExit->SetTitle(
"Exit plane");
853 grExit->GetXaxis()->SetTitle(
"X [mm]");
854 grExit->GetXaxis()->SetTitleSize(0.04);
855 grExit->GetXaxis()->SetLabelSize(0.04);
856 grExit->GetXaxis()->SetNdivisions(5);
857 grExit->GetYaxis()->SetTitle(
"Y [mm]");
858 grExit->GetYaxis()->SetTitleOffset(1.4);
859 grExit->GetYaxis()->SetTitleSize(0.04);
860 grExit->GetYaxis()->SetLabelSize(0.04);
862 grExit->SetMarkerStyle(1);
867 Double_t xMin = TMath::MinElement(grZ->GetN(), grZ->GetX());
868 Double_t xMax = TMath::MaxElement(grZ->GetN(), grZ->GetX());
869 Double_t yMin = TMath::MinElement(grZ->GetN(), grZ->GetY());
870 Double_t yMax = TMath::MaxElement(grZ->GetN(), grZ->GetY());
872 std::string zTitle =
"User plane. Z = " +
DoubleToString(z) +
"mm";
873 grZ->SetTitle(zTitle.c_str());
874 grZ->GetXaxis()->SetLimits(1.5 * xMin, 1.5 * xMax);
875 grZ->GetHistogram()->SetMaximum(1.5 * yMax);
876 grZ->GetHistogram()->SetMinimum(1.5 * yMin);
878 grZ->GetXaxis()->SetTitle(
"X [mm]");
879 grZ->GetXaxis()->SetTitleSize(0.04);
880 grZ->GetXaxis()->SetLabelSize(0.04);
881 grZ->GetXaxis()->SetNdivisions(5);
882 grZ->GetYaxis()->SetTitle(
"Y [mm]");
883 grZ->GetYaxis()->SetTitleOffset(1.4);
884 grZ->GetYaxis()->SetTitleSize(0.04);
885 grZ->GetYaxis()->SetLabelSize(0.04);
887 grZ->SetMarkerStyle(1);
892 std::string focalTitle =
"Focal plane. Z = " +
DoubleToString(focal) +
"mm";
893 grFocal->SetTitle(focalTitle.c_str());
894 grFocal->GetXaxis()->SetLimits(-10, 10);
895 grFocal->GetHistogram()->SetMaximum(10);
896 grFocal->GetHistogram()->SetMinimum(-10);
898 grFocal->GetXaxis()->SetTitle(
"X [mm]");
899 grFocal->GetXaxis()->SetTitleSize(0.04);
900 grFocal->GetXaxis()->SetLabelSize(0.04);
901 grFocal->GetXaxis()->SetNdivisions(5);
902 grFocal->GetYaxis()->SetTitle(
"Y [mm]");
903 grFocal->GetYaxis()->SetTitleOffset(1.4);
904 grFocal->GetYaxis()->SetTitleSize(0.04);
905 grFocal->GetYaxis()->SetLabelSize(0.04);
907 grFocal->SetMarkerStyle(1);
920 Double_t focalHint) {
921 Double_t focal =
FindFocal(focalHint - 500, focalHint + 500, energy, 1);
929 TH2F* hEntrance =
new TH2F(
"entranceH",
"Entrance plane", 500, lowL, highL, 500, lowL, highL);
930 TH2F* hExit =
new TH2F(
"exitH",
"Exit plane", 500, lowL, highL, 500, lowL, highL);
932 std::string zTitle =
"User plane. Z = " +
DoubleToString(z) +
"mm";
933 TH2F* hZ =
new TH2F(
"zH", zTitle.c_str(), 500, lowL, highL, 500, lowL, highL);
935 std::string focalTitle =
"Focal plane. Z = " +
DoubleToString(focal) +
"mm";
936 TH2F* hFocal =
new TH2F(
"focalH", focalTitle.c_str(), 500, -10, 10, 500, -10, 10);
938 for (
int n = 0; n < particles; n++) {
944 if (reflectivity == 0)
continue;
949 hZ->Fill(posZ.X(), posZ.Y());
952 TVector3(0, 0, focal));
953 hFocal->Fill(posFocal.X(), posFocal.Y());
958 hEntrance->GetXaxis()->SetTitle(
"X [mm]");
959 hEntrance->GetXaxis()->SetTitleSize(0.04);
960 hEntrance->GetXaxis()->SetLabelSize(0.04);
961 hEntrance->GetXaxis()->SetNdivisions(5);
962 hEntrance->GetYaxis()->SetTitle(
"Y [mm]");
963 hEntrance->GetYaxis()->SetTitleOffset(1.4);
964 hEntrance->GetYaxis()->SetTitleSize(0.04);
965 hEntrance->GetYaxis()->SetLabelSize(0.04);
967 hEntrance->Draw(
"colz");
971 hExit->GetXaxis()->SetTitle(
"X [mm]");
972 hExit->GetXaxis()->SetTitleSize(0.04);
973 hExit->GetXaxis()->SetLabelSize(0.04);
974 hExit->GetXaxis()->SetNdivisions(5);
975 hExit->GetYaxis()->SetTitle(
"Y [mm]");
976 hExit->GetYaxis()->SetTitleOffset(1.4);
977 hExit->GetYaxis()->SetTitleSize(0.04);
978 hExit->GetYaxis()->SetLabelSize(0.04);
984 hZ->GetXaxis()->SetTitle(
"X [mm]");
985 hZ->GetXaxis()->SetTitleSize(0.04);
986 hZ->GetXaxis()->SetLabelSize(0.04);
987 hZ->GetXaxis()->SetNdivisions(5);
988 hZ->GetYaxis()->SetTitle(
"Y [mm]");
989 hZ->GetYaxis()->SetTitleOffset(1.4);
990 hZ->GetYaxis()->SetTitleSize(0.04);
991 hZ->GetYaxis()->SetLabelSize(0.04);
997 hFocal->GetXaxis()->SetTitle(
"X [mm]");
998 hFocal->GetXaxis()->SetTitleSize(0.04);
999 hFocal->GetXaxis()->SetLabelSize(0.04);
1000 hFocal->GetXaxis()->SetNdivisions(5);
1001 hFocal->GetYaxis()->SetTitle(
"Y [mm]");
1002 hFocal->GetYaxis()->SetTitleOffset(1.4);
1003 hFocal->GetYaxis()->SetTitleSize(0.04);
1004 hFocal->GetYaxis()->SetLabelSize(0.04);
1006 hFocal->Draw(
"colz");
A metadata class accessing the Henke database to load reflectivity data.
Double_t GetReflectivity(const Double_t angle, const Double_t energy)
It returns the interpolated reflectivity for a given angle (in degrees) and a given energy (in keV).
void PrintMetadata()
Prints on screen the information about the metadata members of TRestAxionOpticsMirror.
An abstract class to define common optics parameters and methods.
TVector3 GetLastGoodPosition()
It returns the last valid particle position known in the particle tracking.
Bool_t fSecondInteraction
During the photon propagation it tells us if the photon interacted in the second mirror.
void PrintEntranceMask()
Prints on screen the mask used on the entrance optics plane.
virtual Double_t FindFocal(Double_t from, Double_t to, Double_t energy, Double_t precision=1, Bool_t recalculate=false, Int_t particles=5000)
It implements a generic method to identify the optimum focal point. It can be reimplemented at each s...
void PrintPhotonTrackingSummary()
Prints the positions taken by the photon after ray-tracing that should have been updated using the me...
TVector3 fMiddlePosition
The particle position at the optics plane middle.
Int_t fCurrentMirror
During the photon propagation it keeps track of the active mirror shell.
TPad * fPad
A pad pointer to be used by the drawing methods.
TRestCombinedMask * fMiddleMask
The middle optical mask that defines a pattern with regions identified with a number.
Bool_t IsSecondMirrorReflection()
It returns true if the photon got reflected in the second mirror.
std::vector< std::vector< Double_t > > fOpticsData
The optics data table extracted from fOpticsFile.
TVector3 fMiddleDirection
The particle position at the optics plane middle.
Double_t PropagatePhoton(const TVector3 &pos, const TVector3 &dir, Double_t energy)
Propagating photon.
virtual Int_t SecondMirrorReflection(const TVector3 &pos, const TVector3 &dir)=0
It updates the values fSecondInteractionPosition and fExitDirection. Returns 0 if is not in region.
Bool_t fFirstInteraction
During the photon propagation it tells us if the photon interacted in the first mirror.
TVector3 fExitDirection
The particle position at the optics plane exit.
Double_t PropagateMonteCarloPhoton(Double_t energy, Double_t deviation)
It will produce a MonteCarlo photon spatially distributed in XY as defined by the GetRadialLimits met...
TRestCombinedMask * fExitMask
The exit optical mask that defines a pattern with regions identified with a number.
virtual void Initialize()
Initialization of TRestAxionOptics members.
Double_t GetPhotonReflectivity(Double_t energy)
A prototype method to be implemented by specific optics to draw an schematic including the mirrors ge...
TRestAxionOpticsMirror * fMirrorProperties
The mirror properties.
Int_t TransportToEntrance(const TVector3 &pos, const TVector3 &dir)
It moves the incoming particle at the entrance of the optics plane and returns the region number wher...
Int_t TransportToMiddle(const TVector3 &pos, const TVector3 &dir)
It moves the incoming particle to the middle of the optics plane and returns the region number where ...
virtual std::pair< Double_t, Double_t > GetRadialLimits()=0
It returns the lower/higher radius range where photons are allowed.
TRestAxionOptics()
Default constructor.
virtual Double_t GetEntrancePositionZ()=0
It returns the entrance Z-position defined by the optical axis.
Bool_t IsFirstMirrorReflection()
It returns true if the photon got reflected in the first mirror.
TVector3 fExitPosition
The particle position at the optics plane exit.
Double_t fMirrorLength
The mirror length. If all mirrors got the same length. Otherwise will be zero.
TPad * CreatePad(Int_t nx=1, Int_t ny=1)
A prototype method to be implemented by specific optics to draw an schematic including the mirrors ge...
Double_t fFocal
The calculated focal in mm. It is updated by the method TRestAxionOptics::FindFocal.
void PrintMasks()
Prints on screen the 3-optical masks used on the optics planes.
TVector3 fEntrancePosition
The particle position at the optics plane entrance.
TPad * DrawParticleTracks(Double_t deviation=0, Int_t particles=10)
A method to draw an optics schematic including the mirrors geometry, and few photon tracks....
TVector3 GetMiddleDirection()
Returns the middle position from the latest propagated photon.
std::string fOpticsFile
An optics file that contains all the specific optics parameters.
TVector3 GetExitDirection()
Returns the exit position from the latest propagated photon.
void InitFromConfigFile()
Initialization of TRestAxionOptics field members through a RML file.
TPad * DrawDensityMaps(Double_t z, Double_t energy=0, Double_t deviation=0, Int_t particles=1000, Double_t focalHint=7500)
It implements a generic method to identify the optimum focal point. It can be reimplemented at each s...
void PrintMiddleMask()
Prints on screen the mask used on the middle optics plane.
TVector3 GetLastGoodDirection()
It returns the last valid particle direction known in the particle tracking.
TVector3 fSecondInteractionPosition
The particle position at the back mirror interaction point.
TVector3 GetEntranceDirection()
Returns the entrance position from the latest propagated photon.
TRestCombinedMask * fEntranceMask
The entrance optical mask that defines a pattern with regions identified with a number.
virtual void SetMirror()=0
It must be implemented at the inherited optics, making use of fEntrancePosition.
virtual Double_t GetExitPositionZ()=0
It returns the exit Z-position defined by the optical axis.
TVector3 GetMiddlePosition()
Returns the middle position from the latest propagated photon.
void ResetPositions()
It reinitializes particle positions and directions at the different optical regions.
void PrintMirror()
Prints on screen the 3-optical masks used on the optics planes.
TVector3 GetExitPosition()
Returns the exit position from the latest propagated photon.
TRandom3 * fRandom
Random number generator.
void PrintExitMask()
Prints on screen the mask used on the exit optics plane.
Int_t TransportToExit(const TVector3 &pos, const TVector3 &dir)
It moves the incoming particle to the exit of the optics plane and returns the region number where th...
TVector3 GetEntrancePosition()
Returns the entrance position from the latest propagated photon.
virtual TPad * DrawMirrors()=0
It draws the mirrors using a TGraph. To be implemented at the inherited class.
virtual Int_t FirstMirrorReflection(const TVector3 &pos, const TVector3 &dir)=0
It updates the values fFirstInteractionPosition and fMiddleDirection. Returns 0 if is not in region.
TPad * DrawScatterMaps(Double_t z, Double_t energy=0, Double_t deviation=0, Int_t particles=1000, Double_t focalHint=7500)
It implements a generic method to identify the optimum focal point. It can be reimplemented at each s...
Int_t GetMirror()
It returns the mirror index to be used in the photon reflection.
~TRestAxionOptics()
Default destructor.
TVector3 fOriginPosition
The particle position at the origin.
Double_t CalculateSpotSize(Double_t energy, Double_t z, Int_t particles=15000)
It measures the spot size through Monte Carlo at a given plane given by z. If z=0 this method will ch...
Int_t GetNumberOfReflections()
It returns the total number of reflections. Considering maximum 1-reflection per mirror.
TVector3 fFirstInteractionPosition
The particle position at the front mirror interaction point.
void PrintMetadata()
Prints on screen the information about the metadata members of TRestAxionOptics.
TVector3 fEntranceDirection
The particle position at the optics plane entrance.
A class used to define and generate a combined structure mask.
Int_t GetRegion(Double_t &x, Double_t &y) override
It returns a number identifying the region where the particle with coordinates (x,...
void PrintMetadata() override
Prints on screen the complete information about the metadata members from this class.
This namespace serves to define physics constants and other basic physical operations.
TVector3 MoveToPlane(const TVector3 &pos, const TVector3 &dir, const TVector3 &n, const TVector3 &a)
This method will translate the vector with direction dir starting at position pos to the plane define...
Double_t GetVectorsAngle(const TVector3 &v1, const TVector3 &v2)
This method will return the angle in radians between 2 vectors.
std::string DoubleToString(Double_t d, std::string format="%8.6e")
Gets a string from a double.