REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestAxionOptics.cxx
1/******************** REST disclaimer ***********************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
138
139#include "TRestAxionOptics.h"
140
141#include <TAxis.h>
142#include <TGraph.h>
143#include <TH1F.h>
144#include <TH2F.h>
145
146using namespace std;
147
148#include "TRestPhysics.h"
149using namespace REST_Physics;
150
151ClassImp(TRestAxionOptics);
152
157
172TRestAxionOptics::TRestAxionOptics(const char* cfgFileName, string name) : TRestMetadata(cfgFileName) {
173 RESTDebug << "Entering TRestAxionOptics constructor( cfgFileName, name )" << RESTendl;
174 RESTDebug << "File: " << cfgFileName << " Name: " << name << RESTendl;
175}
176
181 if (fEntranceMask) delete fEntranceMask;
182 if (fExitMask) delete fExitMask;
183 if (fMiddleMask) delete fMiddleMask;
184}
185
190 SetLibraryVersion(LIBRARY_VERSION);
191
192 if (fOpticsFile != "") {
193 std::string fullPathFileName = SearchFile(fOpticsFile);
194
195 if (!TRestTools::ReadASCIITable(fullPathFileName, fOpticsData, 3)) {
196 RESTError << "TRestAxionOptics. Error reading optics file : " << fOpticsFile << RESTendl;
197 }
198
199 // std::cout << "Reading table" << std::endl;
200 // TRestTools::PrintTable(fOpticsData, 6, 9);
201 }
202
203 if (fEntranceMask != nullptr) {
204 delete fEntranceMask;
205 fEntranceMask = nullptr;
206 }
208 fEntranceMask->SetName("Entrance");
209 fEntranceMask->SetTitle("Optics entrance mask");
211
212 if (fExitMask != nullptr) {
213 delete fExitMask;
214 fExitMask = nullptr;
215 }
217 fExitMask->SetName("Exit");
218 fExitMask->SetTitle("Optics exit mask");
220
221 if (fMiddleMask != nullptr) {
222 delete fMiddleMask;
223 fMiddleMask = nullptr;
224 }
226 fMiddleMask->SetName("Middle");
227 fMiddleMask->SetTitle("Optics middle mask");
229}
230
236 if (fFirstInteraction && fSecondInteraction) return 2;
237 if (fFirstInteraction) return 1;
238 if (fSecondInteraction) return 1;
239 return 0;
240}
241
251Int_t TRestAxionOptics::TransportToEntrance(const TVector3& pos, const TVector3& dir) {
252 RESTDebug << "TRestAxionOptics::TransportToEntrance" << RESTendl;
253 if (pos.Z() > GetEntrancePositionZ()) {
254 RESTWarning << "TRestAxionOptics::TransportToEntrance" << RESTendl;
255 RESTWarning << "The particle should be placed before the entrance!" << RESTendl;
256 return 0;
257 }
258 if (dir.Z() <= 0) {
259 RESTWarning << "TRestAxionOptics::TransportToEntrance" << RESTendl;
260 RESTWarning << "Photon is not moving on the positive Z-direction!" << RESTendl;
261 return 0;
262 }
264 REST_Physics::MoveToPlane(pos, dir, TVector3(0, 0, 1), TVector3(0, 0, GetEntrancePositionZ()));
265
266 Double_t x = fEntrancePosition.X();
267 Double_t y = fEntrancePosition.Y();
268 return fEntranceMask->GetRegion(x, y);
269}
270
280Int_t TRestAxionOptics::TransportToMiddle(const TVector3& pos, const TVector3& dir) {
281 RESTDebug << "TRestAxionOptics::TransportToMiddle" << RESTendl;
282 if (pos.Z() > 0 || pos.Z() < GetEntrancePositionZ()) {
283 RESTWarning << "TRestAxionOptics::TransportToMiddle" << RESTendl;
284 RESTWarning << "The particle should be placed between entrance and middle!" << RESTendl;
285 return 0;
286 }
287 if (dir.Z() <= 0) {
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;
291 return 0;
292 }
293
294 fMiddlePosition = REST_Physics::MoveToPlane(pos, dir, TVector3(0, 0, 1), TVector3(0, 0, 0));
295 fMiddleDirection = dir;
296
297 Double_t x = fMiddlePosition.X();
298 Double_t y = fMiddlePosition.Y();
299 return fMiddleMask->GetRegion(x, y);
300}
301
311Int_t TRestAxionOptics::TransportToExit(const TVector3& pos, const TVector3& dir) {
312 RESTDebug << "TRestAxionOptics::TransportToExit" << RESTendl;
313 if (pos.Z() < 0 || pos.Z() > GetExitPositionZ()) {
314 RESTWarning << "TRestAxionOptics::TransportToExit" << RESTendl;
315 RESTWarning << "The particle should be placed between middle and exit!" << RESTendl;
316 return 0;
317 }
318 if (dir.Z() <= 0) {
319 RESTWarning << "TRestAxionOptics::TransportToExit" << RESTendl;
320 RESTWarning << "Photon is not moving on the positive Z-direction!" << RESTendl;
321 return 0;
322 }
323
325 REST_Physics::MoveToPlane(pos, dir, TVector3(0, 0, 1), TVector3(0, 0, GetExitPositionZ()));
326 fExitDirection = dir;
327
328 Double_t x = fExitPosition.X();
329 Double_t y = fExitPosition.Y();
330 return fExitMask->GetRegion(x, y);
331}
332
337 fOriginPosition = TVector3(0, 0, 0);
338
339 fEntrancePosition = TVector3(0, 0, 0);
340 fEntranceDirection = TVector3(0, 0, 0);
341
342 fFirstInteractionPosition = TVector3(0, 0, 0);
343
344 fMiddlePosition = TVector3(0, 0, 0);
345 fMiddleDirection = TVector3(0, 0, 0);
346
347 fSecondInteractionPosition = TVector3(0, 0, 0);
348
349 fExitPosition = TVector3(0, 0, 0);
350 fExitDirection = TVector3(0, 0, 0);
351
352 fCurrentMirror = -1;
353}
354
359 if (GetExitDirection().Mag() > 0)
360 return GetExitPosition();
361 else if (GetMiddleDirection().Mag() > 0)
362 return GetMiddlePosition();
363
364 return GetEntrancePosition();
365}
366
371 if (GetExitDirection().Mag() > 0)
372 return GetExitDirection();
373 else if (GetMiddleDirection().Mag() > 0)
374 return GetMiddleDirection();
375
376 return GetEntranceDirection();
377}
378
382Double_t TRestAxionOptics::PropagatePhoton(const TVector3& pos, const TVector3& dir, Double_t energy) {
383 RESTDebug << " --> Entering TRestAxionOptics::PropagatePhoton" << RESTendl;
384
385 RESTDebug << "Reseting positions" << RESTendl;
387
388 fOriginPosition = pos;
389 fEntranceDirection = dir;
390
393 RESTDebug << "Entrance region : " << entranceRegion << RESTendl;
394
395 if (entranceRegion == 0) return 0.0;
396
399 SetMirror();
400
404
407 RESTDebug << "Middle region : " << middleRegion << RESTendl;
408 if (middleRegion != entranceRegion) return 0.0;
409
413
415
417 RESTDebug << "Exit region : " << exitRegion << RESTendl;
418 if (exitRegion != middleRegion) return 0.0;
419
420 return GetPhotonReflectivity(energy);
421}
422
427 if (fMirrorProperties) {
428 delete fMirrorProperties;
429 fMirrorProperties = nullptr;
430 }
431
432 fMirrorProperties = (TRestAxionOpticsMirror*)this->InstantiateChildMetadata("TRestAxionOpticsMirror");
433
435
436 // If we recover the metadata class from a ROOT file we will need to call Initialize ourselves
437 this->Initialize();
438}
439
445
446 RESTMetadata << " - Optics file : " << fOpticsFile << RESTendl;
447 RESTMetadata << "---------" << RESTendl;
448 RESTMetadata << "Entrance position in Z : " << GetEntrancePositionZ() << " mm" << RESTendl;
449 RESTMetadata << "Exit position in Z : " << GetExitPositionZ() << " mm" << RESTendl;
450 RESTMetadata << "Low radial limit : " << GetRadialLimits().first << " mm" << RESTendl;
451 RESTMetadata << "High radial limit : " << GetRadialLimits().second << " mm" << RESTendl;
452 RESTMetadata << "---------" << RESTendl;
453 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;
457}
458
466}
467
473}
474
479 if (fEntranceMask)
481 else
482 RESTWarning << "TRestAxionOptics::PrintEntranceMask. Not available" << RESTendl;
483}
484
489 if (fMiddleMask)
491 else
492 RESTWarning << "TRestAxionOptics::PrintMiddleMask. Not available" << RESTendl;
493}
494
499 if (fExitMask)
501 else
502 RESTWarning << "TRestAxionOptics::PrintExitMask. Not available" << RESTendl;
503}
504
510 std::cout << "Photon tracking summary" << std::endl;
511 std::cout << "-----------------------" << std::endl;
512 std::cout << "Origin : ( " << fOriginPosition.X() << ", " << fOriginPosition.Y() << ", "
513 << fOriginPosition.Z() << ")" << std::endl;
514
515 std::cout << "Entrance Direction : ( " << fEntranceDirection.X() << ", " << fEntranceDirection.Y() << ", "
516 << fEntranceDirection.Z() << ")" << std::endl;
517
518 std::cout << "Entrance : ( " << fEntrancePosition.X() << ", " << fEntrancePosition.Y() << ", "
519 << fEntrancePosition.Z() << ")" << std::endl;
520
521 std::cout << "Entrance radius : "
522 << TMath::Sqrt(fEntrancePosition.X() * fEntrancePosition.X() +
524 << std::endl;
525
526 std::cout << "FirstInteraction : ( " << fFirstInteractionPosition.X() << ", "
527 << fFirstInteractionPosition.Y() << ", " << fFirstInteractionPosition.Z() << ")" << std::endl;
528
529 std::cout << "Middle Direction : ( " << fMiddleDirection.X() << ", " << fMiddleDirection.Y() << ", "
530 << fMiddleDirection.Z() << ")" << std::endl;
531
532 std::cout << "Middle : ( " << fMiddlePosition.X() << ", " << fMiddlePosition.Y() << ", "
533 << fMiddlePosition.Z() << ")" << std::endl;
534
535 std::cout << "Middle radius : "
536 << TMath::Sqrt(fMiddlePosition.X() * fMiddlePosition.X() +
538 << std::endl;
539
540 std::cout << "SecondInteraction : ( " << fSecondInteractionPosition.X() << ", "
541 << fSecondInteractionPosition.Y() << ", " << fSecondInteractionPosition.Z() << ")" << std::endl;
542
543 std::cout << "Exit Direction : ( " << fExitDirection.X() << ", " << fExitDirection.Y() << ", "
544 << fExitDirection.Z() << ")" << std::endl;
545
546 std::cout << "Exit : ( " << fExitPosition.X() << ", " << fExitPosition.Y() << ", " << fExitPosition.Z()
547 << ")" << std::endl;
548
549 std::cout << "Exit radius : "
550 << TMath::Sqrt(fExitPosition.X() * fExitPosition.X() + fExitPosition.Y() * fExitPosition.Y())
551 << std::endl;
552 std::cout << "-----------------------" << std::endl;
553}
554
559TPad* TRestAxionOptics::CreatePad(Int_t nx, Int_t ny) {
560 if (fPad != nullptr) {
561 delete fPad;
562 fPad = nullptr;
563 }
564
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);
567 fPad->Draw();
568 fPad->SetRightMargin(0.09);
569 fPad->SetLeftMargin(0.2);
570 fPad->SetBottomMargin(0.15);
571
572 return fPad;
573}
574
580 if (!fMirrorProperties) return 0;
581
582 Double_t reflectivity = 1.;
585
586 angle = angle * units("deg") / units("rad") / 2.; // Incidence angle in degrees. We divide by 2
587
588 reflectivity *= fMirrorProperties->GetReflectivity(angle, energy);
589 }
592
593 angle = angle * units("deg") / units("rad") / 2.; // Incidence angle in degrees. We divide by 2
594
595 reflectivity *= fMirrorProperties->GetReflectivity(angle, energy);
596 }
597 return reflectivity;
598}
599
608TPad* TRestAxionOptics::DrawParticleTracks(Double_t deviation, Int_t particles) {
609 DrawMirrors();
610
611 for (int n = 0; n < particles; n++) {
612 Double_t r = fRandom->Uniform(GetRadialLimits().first, GetRadialLimits().second);
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),
616 1);
617 direction = direction.Unit();
618
619 Double_t reflectivity = PropagatePhoton(origin, direction, 1);
620
622
623 TGraph* gr = new TGraph();
624
625 Double_t rO = TMath::Sqrt(origin.X() * origin.X() + origin.Y() * origin.Y());
626 gr->SetPoint(gr->GetN(), origin.Z(), rO);
627
629
630 Double_t rEntrance = TMath::Sqrt(fEntrancePosition.X() * fEntrancePosition.X() +
632 if (rEntrance > 0) gr->SetPoint(gr->GetN(), fEntrancePosition.Z(), rEntrance);
633
635
636 Double_t rFirst = TMath::Sqrt(fFirstInteractionPosition.X() * fFirstInteractionPosition.X() +
638
639 if (rFirst > 0) gr->SetPoint(gr->GetN(), fFirstInteractionPosition.Z(), rFirst);
640
642
643 Double_t rMiddle = TMath::Sqrt(fMiddlePosition.X() * fMiddlePosition.X() +
645 if (rMiddle > 0) gr->SetPoint(gr->GetN(), fMiddlePosition.Z(), rMiddle);
646
648
649 Double_t rSecond = TMath::Sqrt(fSecondInteractionPosition.X() * fSecondInteractionPosition.X() +
651
652 if (rSecond > 0) gr->SetPoint(gr->GetN(), fSecondInteractionPosition.Z(), rSecond);
653
655
656 Double_t rExit =
657 TMath::Sqrt(fExitPosition.X() * fExitPosition.X() + fExitPosition.Y() * fExitPosition.Y());
658 if (rExit > 0) gr->SetPoint(gr->GetN(), fExitPosition.Z(), rExit);
659
661
662 if (reflectivity > 0) {
663 TVector3 end = REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1),
664 TVector3(0, 0, 3 * fMirrorLength));
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);
667 }
668
670
671 gr->SetLineWidth(1);
672 if (GetMirror() < 0)
673 gr->SetLineColor(kBlack);
674 else
675 gr->SetLineColor(20 + GetMirror() % 20);
676
677 gr->Draw("L");
678 }
679 return fPad;
680}
681
695Double_t TRestAxionOptics::FindFocal(Double_t from, Double_t to, Double_t energy, Double_t precision,
696 Bool_t recalculate, Int_t particles) {
697 RESTDebug << "Entering TRestAxionOptics::FindFocal" << RESTendl;
698
699 if (fFocal > 0 && recalculate == false) return fFocal;
700
701 Double_t focal = (from + to) / 2.;
702 Double_t spotSize = CalculateSpotSize(energy, focal);
703
704 Double_t step = (to - from) / 10.;
705
706 if (step < 0) {
707 step = from;
708 from = to;
709 to = step;
710 step = (to - from) / 10.;
711 }
712
713 RESTInfo << "Calculating focal : " << focal << RESTendl;
714 for (Double_t f = from; f < to; f += step) {
715 Double_t size = CalculateSpotSize(energy, f);
716 if (size < spotSize) {
717 spotSize = size;
718 focal = f;
719 }
720 }
721
722 if (step > precision) return FindFocal(focal - step, focal + step, energy, precision, recalculate);
723
724 fFocal = focal;
725 return fFocal;
726}
727
739Double_t TRestAxionOptics::CalculateSpotSize(Double_t energy, Double_t z, Int_t particles) {
740 Double_t sum = 0;
741 Int_t nSum = 0;
742 Double_t deviation = 0;
743 for (int n = 0; n < particles; n++) {
744 Double_t reflectivity = PropagateMonteCarloPhoton(energy, deviation);
745
746 if (reflectivity == 0) continue;
747
748 TVector3 posZ =
749 REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1), TVector3(0, 0, z));
750 Double_t x = posZ.X();
751 Double_t y = posZ.Y();
752
753 sum += reflectivity * x * x + y * y;
754 nSum++;
755 }
756
757 if (nSum > 0) sum = TMath::Sqrt(sum / nSum);
758
759 return sum;
760}
761
769Double_t TRestAxionOptics::PropagateMonteCarloPhoton(Double_t energy, Double_t deviation) {
770 Double_t x = fRandom->Uniform(0, 1.5 * GetRadialLimits().second);
771 Double_t y = fRandom->Uniform(0, 1.5 * GetRadialLimits().second);
772 Double_t r2 = x * x + y * y;
773 while (r2 > 1.5 * GetRadialLimits().second || r2 < 0.5 * GetRadialLimits().second) {
774 x = fRandom->Uniform(0, 1.5 * GetRadialLimits().second);
775 y = fRandom->Uniform(0, 1.5 * GetRadialLimits().second);
776 r2 = x * x + y * y;
777 }
778
779 Double_t r = fRandom->Uniform(0.5 * GetRadialLimits().first, 1.5 * GetRadialLimits().second);
780 Double_t angle = fRandom->Uniform(0, 2 * TMath::Pi());
781 TVector3 origin(r * TMath::Cos(angle), r * TMath::Sin(angle), -3 * fMirrorLength);
782
783 Double_t theta = fRandom->Uniform(0, deviation);
784 Double_t phi = fRandom->Uniform(0, 2 * TMath::Pi());
785
786 TVector3 direction(0, 0, 1);
787 direction.SetTheta(theta);
788 direction.SetPhi(phi);
789 direction.SetMag(1.);
790
791 return PropagatePhoton(origin, direction, energy);
792}
793
800TPad* TRestAxionOptics::DrawScatterMaps(Double_t z, Double_t energy, Double_t deviation, Int_t particles,
801 Double_t focalHint) {
803
804 fPad->cd();
805
806 TGraph* grEntrance = new TGraph();
807 TGraph* grExit = new TGraph();
808 TGraph* grZ = new TGraph();
809 TGraph* grFocal = new TGraph();
810
811 Double_t focal = FindFocal(focalHint - 500, focalHint + 500, energy, 1);
812
813 for (int n = 0; n < particles; n++) {
814 Double_t reflectivity = PropagateMonteCarloPhoton(energy, deviation);
815
816 if (fFirstInteractionPosition.Z() == 0) continue; // The photon hits the entrance mask
817 grEntrance->SetPoint(grEntrance->GetN(), fEntrancePosition.X(), fEntrancePosition.Y());
818
819 if (reflectivity == 0) continue; // The photon hits any mask
820 grExit->SetPoint(grExit->GetN(), fExitPosition.X(), fExitPosition.Y());
821
822 TVector3 posZ =
823 REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1), TVector3(0, 0, z));
824 grZ->SetPoint(grZ->GetN(), posZ.X(), posZ.Y());
825
826 TVector3 posFocal = REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1),
827 TVector3(0, 0, focal));
828 grFocal->SetPoint(grFocal->GetN(), posFocal.X(), posFocal.Y());
829 }
830
831 fPad->cd(1);
832
833 grEntrance->GetXaxis()->SetLimits(-GetRadialLimits().second * 1.15, GetRadialLimits().second * 1.15);
834 grEntrance->GetHistogram()->SetMaximum(GetRadialLimits().second * 1.15);
835 grEntrance->GetHistogram()->SetMinimum(-GetRadialLimits().second * 1.15);
836
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);
846
847 grEntrance->SetMarkerStyle(1);
848 grEntrance->Draw("AP");
849
850 fPad->cd(2);
851
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);
861
862 grExit->SetMarkerStyle(1);
863 grExit->Draw("AP");
864
865 fPad->cd(3);
866
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());
871
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);
877
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);
886
887 grZ->SetMarkerStyle(1);
888 grZ->Draw("AP");
889
890 fPad->cd(4);
891
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);
897
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);
906
907 grFocal->SetMarkerStyle(1);
908 grFocal->Draw("AP");
909
910 return fPad;
911}
912
919TPad* TRestAxionOptics::DrawDensityMaps(Double_t z, Double_t energy, Double_t deviation, Int_t particles,
920 Double_t focalHint) {
921 Double_t focal = FindFocal(focalHint - 500, focalHint + 500, energy, 1);
922
924
925 fPad->cd();
926
927 Double_t lowL = -1.15 * GetRadialLimits().second;
928 Double_t highL = 1.15 * GetRadialLimits().second;
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);
931
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);
934
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);
937
938 for (int n = 0; n < particles; n++) {
939 Double_t reflectivity = PropagateMonteCarloPhoton(energy, deviation);
940
941 if (fFirstInteractionPosition.Z() == 0) continue; // The photon hits the entrance mask
942 hEntrance->Fill(fEntrancePosition.X(), fEntrancePosition.Y());
943
944 if (reflectivity == 0) continue; // The photon hits any mask
945 hExit->Fill(fExitPosition.X(), fExitPosition.Y());
946
947 TVector3 posZ =
948 REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1), TVector3(0, 0, z));
949 hZ->Fill(posZ.X(), posZ.Y());
950
951 TVector3 posFocal = REST_Physics::MoveToPlane(fExitPosition, fExitDirection, TVector3(0, 0, 1),
952 TVector3(0, 0, focal));
953 hFocal->Fill(posFocal.X(), posFocal.Y());
954 }
955
956 fPad->cd(1);
957
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);
966
967 hEntrance->Draw("colz");
968
969 fPad->cd(2);
970
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);
979
980 hExit->Draw("colz");
981
982 fPad->cd(3);
983
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);
992
993 hZ->Draw("colz");
994
995 fPad->cd(4);
996
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);
1005
1006 hFocal->Draw("colz");
1007
1008 return fPad;
1009}
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.
A base class for any REST metadata class.
Definition: TRestMetadata.h:70
virtual void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
endl_t RESTendl
Termination flag object for TRestStringOutput.
TRestMetadata * InstantiateChildMetadata(int index, std::string pattern="")
This method will retrieve a new TRestMetadata instance of a child element of the present TRestMetadat...
virtual void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
std::string SearchFile(std::string filename)
Search files in current directory and directories specified in "searchPath" section.
void SetVerboseLevel(TRestStringOutput::REST_Verbose_Level v)
sets the verbose level
static int ReadASCIITable(std::string fName, std::vector< std::vector< Double_t > > &data, Int_t skipLines=0, std::string separator="\t")
Reads an ASCII file containing a table with values.
Definition: TRestTools.cxx:577
This namespace serves to define physics constants and other basic physical operations.
Definition: TRestPhysics.h:34
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.