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 
146 using namespace std;
147 
148 #include "TRestPhysics.h"
149 using namespace REST_Physics;
150 
151 ClassImp(TRestAxionOptics);
152 
157 
172 TRestAxionOptics::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 
251 Int_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 
280 Int_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 
311 Int_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 
324  fExitPosition =
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 
382 Double_t TRestAxionOptics::PropagatePhoton(const TVector3& pos, const TVector3& dir, Double_t energy) {
383  RESTDebug << " --> Entering TRestAxionOptics::PropagatePhoton" << RESTendl;
384 
385  RESTDebug << "Reseting positions" << RESTendl;
386  ResetPositions();
387 
388  fOriginPosition = pos;
389  fEntranceDirection = dir;
390 
392  Int_t entranceRegion = TransportToEntrance(fOriginPosition, fEntranceDirection);
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 
559 TPad* 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 
579 Double_t TRestAxionOptics::GetPhotonReflectivity(Double_t energy) {
580  if (!fMirrorProperties) return 0;
581 
582  Double_t reflectivity = 1.;
583  if (IsFirstMirrorReflection()) {
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  }
590  if (IsSecondMirrorReflection()) {
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 
608 TPad* 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() +
644  fMiddlePosition.Y() * fMiddlePosition.Y());
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 
695 Double_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 
739 Double_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 
769 Double_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 
800 TPad* 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 
919 TPad* 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 ...
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.
virtual std::pair< Double_t, Double_t > GetRadialLimits()=0
It returns the lower/higher radius range where photons are allowed.
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 Int_t FirstMirrorReflection(const TVector3 &pos, const TVector3 &dir)=0
It updates the values fFirstInteractionPosition and fMiddleDirection. Returns 0 if is not in region.
virtual TPad * DrawMirrors()=0
It draws the mirrors using a TGraph. To be implemented at the inherited class.
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:74
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.