REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestAxionWolterOptics.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
113
114#include "TRestAxionWolterOptics.h"
115
116using namespace std;
117#include <TAxis.h>
118#include <TGraph.h>
119#include <TH1F.h>
120
121#include <cmath>
122
123#include "TRestPhysics.h"
124using namespace REST_Physics;
125ClassImp(TRestAxionWolterOptics);
126
131
136
151TRestAxionWolterOptics::TRestAxionWolterOptics(const char* cfgFileName, string name)
152 : TRestAxionOptics(cfgFileName) {
153 RESTDebug << "Entering TRestAxionWolterOptics constructor( cfgFileName, name )" << RESTendl;
154
155 Initialize();
156
158
160}
161
167
168 SetSectionName(this->ClassName());
169 SetLibraryVersion(LIBRARY_VERSION);
170
171 fR1 = GetR1();
172 fR2 = GetR2();
173 fR3 = GetR3();
174 fR4 = GetR4();
175 fR5 = GetR5();
176 fAlpha = GetAlpha();
178
179 fXSep.clear();
180 for (unsigned int n = 0; n < fAlpha.size(); n++)
181 if (fR2[n] == fR3[n]) {
182 fXSep.push_back(0);
183 } else {
184 fXSep.push_back(2 * (fR1[n] - fR3[n] - fMirrorLength * TMath::Sin(fAlpha[n])) /
185 TMath::Tan(fAlpha[n]));
186 }
187
188 if (fAlpha.size() == 0) return;
189
190 fCosAlpha.clear();
191 for (const auto& a : fAlpha) fCosAlpha.push_back(TMath::Cos(a));
192
193 fCosAlpha_3.clear();
194 for (const auto& a : fAlpha) fCosAlpha_3.push_back(TMath::Cos(3 * a));
195
196 fFrontVertex.clear();
197 for (unsigned int n = 0; n < fAlpha.size(); n++) fFrontVertex.push_back(fR3[n] / TMath::Tan(fAlpha[n]));
198
199 fBackVertex.clear();
200 for (unsigned int n = 0; n < fAlpha.size(); n++)
201 fBackVertex.push_back(fR3[n] / TMath::Tan(3. * fAlpha[n]));
202
204 if (fEntranceRingsMask) {
205 delete fEntranceRingsMask;
206 fEntranceRingsMask = nullptr;
207 }
209
210 std::vector<Double_t> inner, outer;
211 for (unsigned int n = 0; n < fR1.size() - 1; n++) {
212 inner.push_back(fR1[n] + fThickness[n]);
213 outer.push_back(fR1[n + 1]);
214 }
215 fEntranceRingsMask->SetRadii(inner, outer);
216
217 fEntranceMask->AddMask(fSpiderMask);
219
221 if (fMiddleRingsMask) {
222 delete fMiddleRingsMask;
223 fMiddleRingsMask = nullptr;
224 }
226
227 inner.clear();
228 outer.clear();
229 for (unsigned int n = 0; n < fR3.size() - 1; n++) {
230 inner.push_back(fR3[n] + fThickness[n]);
231 outer.push_back(fR3[n + 1]);
232 }
233 fMiddleRingsMask->SetRadii(inner, outer);
234
235 fMiddleMask->AddMask(fSpiderMask);
237
239 if (fExitRingsMask) {
240 delete fExitRingsMask;
241 fExitRingsMask = nullptr;
242 }
244
245 inner.clear();
246 outer.clear();
247 for (unsigned int n = 0; n < fR5.size() - 1; n++) {
248 inner.push_back(fR5[n] + fThickness[n]);
249 outer.push_back(fR5[n + 1]);
250 }
251 fExitRingsMask->SetRadii(inner, outer);
252
253 fExitMask->AddMask(fSpiderMask);
254 fExitMask->AddMask(fExitRingsMask);
255
256 if (fRandom != nullptr) {
257 delete fRandom;
258 fRandom = nullptr;
259 }
260 fRandom = new TRandom3(0);
261}
262
267Int_t TRestAxionWolterOptics::FirstMirrorReflection(const TVector3& pos, const TVector3& dir) {
268 Int_t mirror = GetMirror();
269 RESTDebug << "--> Entering TRestAxionWolterOptics::FirstMirrorReflection" << RESTendl;
270 RESTDebug << "Mirror: " << mirror << RESTendl;
271 if (mirror < 0) {
272 RESTError << "TRestAxionWolterOptics::FirstMirrorReflection. Mirror index cannot be negative!"
273 << RESTendl;
274 return -1;
275 }
276
277 if (mirror >= 0 && (unsigned int)mirror >= fFrontVertex.size()) {
278 RESTError << "TRestAxionWolterOptics::FirstMirrorReflection. Mirror index above number of mirrors!"
279 << RESTendl;
280 return -1;
281 }
282
283 RESTDebug << "Vertex Z: " << fFrontVertex[mirror] << RESTendl;
284 RESTDebug << "Cos Alpha: " << fCosAlpha[mirror] << RESTendl;
285 TVector3 vertex(0, 0, fFrontVertex[mirror]);
286 Double_t cosA = fCosAlpha[mirror];
287
290 pos + dir * REST_Physics::GetConeVectorIntersection(pos, dir, TVector3(0, 0, -1), vertex, cosA);
291
293 fFirstInteractionPosition.Z() > -(0.5 * fXSep[mirror])) {
294 RESTDebug << "TRestAxionWolterOptics::FirstMirrorReflection. No interaction!" << RESTendl;
297 fFirstInteraction = false;
298 return 0;
299 }
300
301 TVector3 coneNormal = REST_Physics::GetConeNormal(fFirstInteractionPosition, fAlpha[mirror]);
302 RESTDebug << "Cone normal: (" << coneNormal.X() << ", " << coneNormal.Y() << ", " << coneNormal.Z() << ")"
303 << RESTendl;
304
306
307 RESTDebug << "<-- Exiting TRestAxionWolterOptics::FirstMirrorReflection" << RESTendl;
308
309 fFirstInteraction = true;
310 return 1;
311}
312
317Int_t TRestAxionWolterOptics::SecondMirrorReflection(const TVector3& pos, const TVector3& dir) {
318 Int_t mirror = GetMirror();
319 if (mirror < 0) {
320 RESTError << "TRestAxionWolterOptics::FirstMirrorReflection. Mirror index cannot be negative!"
321 << RESTendl;
322 return 0;
323 }
324
325 if (mirror >= 0 && (unsigned int)mirror >= fFrontVertex.size()) {
326 RESTError << "TRestAxionWolterOptics::FirstMirrorReflection. Mirror index above number of mirrors!"
327 << RESTendl;
328 return 0;
329 }
330
331 TVector3 vertex(0, 0, fBackVertex[mirror]);
332 Double_t cosA = fCosAlpha_3[mirror];
333
336 pos + dir * REST_Physics::GetConeVectorIntersection(pos, dir, TVector3(0, 0, -1), vertex, cosA);
337
339 fSecondInteractionPosition.Z() < (0.5 * fXSep[mirror])) {
340 RESTDebug << "TRestAxionWolterOptics::SecondMirrorReflection. No interaction!" << RESTendl;
343 fSecondInteraction = false;
344 return 0;
345 }
346
347 TVector3 coneNormal = REST_Physics::GetConeNormal(fSecondInteractionPosition, 3 * fAlpha[mirror]);
348
350
351 fSecondInteraction = true;
352 return 1;
353}
354
359 if (fSpiderMask) {
360 delete fSpiderMask;
361 fSpiderMask = nullptr;
362 }
363
364 fSpiderMask = (TRestSpiderMask*)this->InstantiateChildMetadata("TRestSpiderMask");
365
366 if (fSpiderMask == nullptr) {
367 RESTWarning << "TRestAxionWolterOptics requires usually a TRestSpiderMask definition" << RESTendl;
368 } else {
369 }
370
372
373 // If we recover the metadata class from ROOT file we will need to call Initialize ourselves
374 this->Initialize();
375}
376
384 if (fR3.size() > 0) {
385 for (unsigned int n = 0; n < fR3.size(); n++) {
386 Double_t dR1 = fR1[n] - fR3[n] - fMirrorLength * TMath::Sin(fAlpha[n]);
387 Double_t dR5 = fR5[n] - fR3[n] + fMirrorLength * TMath::Sin(3 * fAlpha[n]);
388 if (n % 10 == 0)
389 std::cout << "## R1\tdelta R1\tR3\tR5\tdelta R5\talpha\tCosAlpha\tFrontVertex\tBackVertex"
390 << std::endl;
391
392 std::cout << fR1[n] << "\t" << dR1 << "\t" << fR3[n] << "\t" << fR5[n] << "\t" << dR5 << "\t"
393 << fAlpha[n] << "\t" << fCosAlpha[n] << "\t" << fFrontVertex[n] << "\t"
394 << fBackVertex[n] << std::endl;
395 }
396 }
397}
398
404}
405
410
416
417 fPad->cd();
418 std::vector<TGraph*> graphCollection;
419 for (unsigned int mirror = 0; mirror < fR3.size(); mirror++) {
420 TGraph* gr = new TGraph(); //"Mirror" + IntegerToString(mirror + 1));
421
422 Double_t lX = fMirrorLength * fCosAlpha[mirror];
423
424 gr->SetPoint(0, -lX, fR1[mirror]);
425 gr->SetPoint(1, 0, fR3[mirror]);
426 gr->SetPoint(2, lX, fR5[mirror]);
427
428 gr->GetXaxis()->SetLimits(-3.5 * lX, 3.5 * lX);
429 gr->GetHistogram()->SetMaximum(fR1.back() * 1.15);
430 gr->GetHistogram()->SetMinimum(fR1.front() * 0.8);
431
432 gr->GetXaxis()->SetTitle("Z [mm]");
433 gr->GetXaxis()->SetTitleSize(0.04);
434 gr->GetXaxis()->SetLabelSize(0.04);
435 gr->GetXaxis()->SetNdivisions(5);
436 gr->GetYaxis()->SetTitle("R [mm]");
437 gr->GetYaxis()->SetTitleOffset(1.4);
438 gr->GetYaxis()->SetTitleSize(0.04);
439 gr->GetYaxis()->SetLabelSize(0.04);
440 gr->SetLineWidth(6 * fThickness[mirror]);
441 gr->SetLineColor(20 + mirror % 20);
442 if (mirror == 0)
443 gr->Draw("AL");
444 else
445 gr->Draw("L");
446 }
447
448 return fPad;
449}
An abstract class to define common optics parameters and methods.
Bool_t fSecondInteraction
During the photon propagation it tells us if the photon interacted in the second mirror.
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.
TVector3 fMiddleDirection
The particle position at the optics plane middle.
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.
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 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...
void InitFromConfigFile()
Initialization of TRestAxionOptics field members through a RML file.
TVector3 fSecondInteractionPosition
The particle position at the back mirror interaction point.
TRestCombinedMask * fEntranceMask
The entrance optical mask that defines a pattern with regions identified with a number.
TRandom3 * fRandom
Random number generator.
Int_t GetMirror()
It returns the mirror index to be used in the photon reflection.
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 that calculates the reflection path of X-rays through a Wolter 1 telescope.
std::vector< Double_t > fXSep
std::vector< Double_t > fBackVertex
The Z-position of the cone vertex defined by the back mirrors.
TRestRingsMask * fEntranceRingsMask
The rings structure to be used at entrance as an optical opaque mask.
Double_t GetEntrancePositionZ() override
It returns the entrance Z-position defined by the optical axis.
std::vector< Double_t > fR3
Radius R3 in mm. See schematic figure.
std::vector< Double_t > fR4
Radius R4 in mm. See schematic figure.
std::vector< Double_t > fAlpha
Mirror angle (alpha) in radians. See schematic figure.
std::vector< Double_t > GetR4()
It returns a vector with the values of R4.
TRestAxionWolterOptics()
Default constructor.
std::vector< Double_t > GetThickness()
It returns a vector with the values of mirror thickness.
std::vector< Double_t > GetR2()
It returns a vector with the values of R2.
std::vector< Double_t > fThickness
Mirror thickness in mm. See schematic figure.
void PrintSpider()
It prints out the spider mask common to all the optical planes.
void InitFromConfigFile() override
Initialization of TRestAxionWolterOptics field members through a RML file.
TRestRingsMask * fExitRingsMask
The rings structure to be used at entrance as an optical opaque mask.
Int_t SecondMirrorReflection(const TVector3 &pos, const TVector3 &dir) override
Implementation of first mirror interaction. It updates fSecondInteractionPosition and fExitDirection ...
TRestRingsMask * fMiddleRingsMask
The rings structure to be used at entrance as an optical opaque mask.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionWolterOptics.
std::vector< Double_t > fCosAlpha
Mirror pre-calculated cosine angle (alpha). See schematic figure.
std::vector< Double_t > GetR5()
It returns a vector with the values of R5.
void PrintParameters()
It prints out the Wolter (relevant) parameters extracted from the optics data file,...
std::vector< Double_t > GetAlpha()
It returns a vector with the values of alpha.
std::vector< Double_t > fR2
Radius R2 in mm. See schematic figure.
TPad * DrawMirrors() override
A method to to draw an optics schematic including the mirrors geometry.
std::vector< Double_t > fR5
Radius R5 in mm. See schematic figure.
Int_t FirstMirrorReflection(const TVector3 &pos, const TVector3 &dir) override
Implementation of first mirror interaction. It updates fFirstInteractionPosition and fMiddleDirection...
TRestSpiderMask * fSpiderMask
The spider structure to be used as an optical opaque mask (common to all planes)
std::vector< Double_t > GetR3()
It returns a vector with the values of R3.
std::vector< Double_t > fCosAlpha_3
Mirror pre-calculated cosine angle (alpha). See schematic figure.
std::vector< Double_t > fR1
Entrance radius R1 in mm. See schematic figure.
~TRestAxionWolterOptics()
Default destructor.
std::vector< Double_t > GetR1()
It returns a vector with the values of R1.
void Initialize() override
Initialization of TRestAxionWolterOptics members.
std::vector< Double_t > fFrontVertex
The Z-position of the cone vertex defined by the front mirrors.
Double_t GetExitPositionZ() override
It returns the exit Z-position defined by the optical axis.
endl_t RESTendl
Termination flag object for TRestStringOutput.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
TRestMetadata * InstantiateChildMetadata(int index, std::string pattern="")
This method will retrieve a new TRestMetadata instance of a child element of the present TRestMetadat...
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
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string fConfigFileName
Full name of the rml file.
A class used to define a rings mask pattern.
void SetRadii(const std::vector< Double_t > &innerR, const std::vector< Double_t > &outterR)
It allows to redefine the inner and outter rings radii directly.
A class used to define and generate a spider structure mask.
void PrintMetadata() override
Prints on screen the complete information about the metadata members from this class.
@ REST_Info
+show most of the information for each steps
This namespace serves to define physics constants and other basic physical operations.
Definition: TRestPhysics.h:34
TVector3 MoveByDistance(const TVector3 &pos, const TVector3 &dir, Double_t d)
This method transports a position pos by a distance d in the direction defined by dir.
TVector3 GetConeNormal(const TVector3 &pos, const Double_t alpha, const Double_t R=0)
This method will return a vector that is normal to the cone surface. The position pos should be at th...
Double_t GetConeVectorIntersection(const TVector3 &pos, const TVector3 &dir, const TVector3 &d, const TVector3 &v, const Double_t cosTheta)
This method will find the intersection of the trajectory defined by the vector starting at pos and mo...
TVector3 GetVectorReflection(const TVector3 &dir, const TVector3 &n)
This method will return the reflected vector respect to a plane defined by its normal vector n....