REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestAxionOpticsMirror.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 
109 //
128 
129 #include "TRestAxionOpticsMirror.h"
130 
131 #include <TAxis.h>
132 #include <TGraph.h>
133 #include <TH1F.h>
134 #include <TLatex.h>
135 #include <TLegend.h>
136 
137 using namespace std;
138 
139 ClassImp(TRestAxionOpticsMirror);
140 
145 
160 TRestAxionOpticsMirror::TRestAxionOpticsMirror(const char* cfgFileName, string name)
161  : TRestMetadata(cfgFileName) {
162  RESTDebug << "Entering TRestAxionOpticsMirror constructor( cfgFileName, name )" << RESTendl;
163 
164  Initialize();
165 
167 
169 }
170 
175 
180  SetSectionName(this->ClassName());
181  SetLibraryVersion(LIBRARY_VERSION);
182 
183  fHenkeKeys.clear();
184 
185  if (fMirrorType == "Single") {
186  fHenkeKeys["Ldensity"] = "-1";
187  fHenkeKeys["Layer"] = fLayerTop;
188  fHenkeKeys["Thick"] = fLayerThicknessTop;
189  fHenkeKeys["Sigma1"] = fSigmaTop;
190  fHenkeKeys["Sigma2"] = "0";
191  }
192 
193  if (fMirrorType == "Bilayer") {
194  fHenkeKeys["Tdensity"] = "-1";
195  fHenkeKeys["Tlayer"] = fLayerTop;
196  fHenkeKeys["Thickt"] = fLayerThicknessTop;
197  fHenkeKeys["Sigmat"] = fSigmaTop;
198  fHenkeKeys["Bdensity"] = "-1";
199  fHenkeKeys["Blayer"] = fLayerBottom;
200  fHenkeKeys["Thickb"] = fLayerThicknessBottom;
201  fHenkeKeys["Sigmab"] = fSigmaBottom;
202  fHenkeKeys["Sigmas"] = "0";
203  }
204 
205  fHenkeKeys["Substrate"] = fSubstrate;
206  fHenkeKeys["Sdensity"] = "-1";
207  fHenkeKeys["Pol"] = "0";
208  fHenkeKeys["Scan"] = "Angle";
209  fHenkeKeys["Min"] = "0";
210  fHenkeKeys["Max"] = "4.5";
211  fHenkeKeys["Npts"] = "450";
212  fHenkeKeys["temp"] = "Energy+%28eV%29";
213  fHenkeKeys["Fixed"] = "200";
214  fHenkeKeys["Plot"] = "LinLog";
215  fHenkeKeys["Output"] = "Plot";
216 }
217 
222  Initialize();
223 
224  string mirrorFile = SearchFile(GetReflectivityFilename());
225  string windowFile = SearchFile(GetTransmissionFilename());
226 
227  if (mirrorFile != "" && windowFile != "") {
230  return;
231  }
232 
233  cout << "--------------------------------- INFO ------------------------------" << endl;
234  cout << "The optics material properties were not found in the database" << endl;
235  cout << "Downloading from Henke database. This process will take a long time." << endl;
236  cout << "After producing these files, please, contribute them to the " << endl;
237  cout << "rest-for-physics/axionlib-data inside the optics directory ..." << endl;
238  cout << "---------------------------------- INFO ------------------------------" << endl;
239 
240  fReflectivityTable.clear();
241  fTransmissionTable.clear();
242  map<Int_t, std::vector<Float_t>> reflectivity;
243  map<Int_t, std::vector<Float_t>> transmission;
244  for (double n = 0; n < 9; n = n + 4.5) {
245  fHenkeKeys["Min"] = DoubleToString(n);
246  fHenkeKeys["Max"] = DoubleToString(n + 4.5);
247 
248  cout.flush();
249  vector<Float_t> reflect;
250  vector<Float_t> transm;
251  reflect.clear();
252  transm.clear();
253 
254  cout << "Scanning angles between " << n << " and " << n + 4.5 << ".";
255  for (int e = 30; e <= 15000; e += 30) {
256  fHenkeKeys["Fixed"] = IntegerToString(e);
257  cout << ".";
258  cout.flush();
259  string fname = DownloadHenkeFile();
260 
261  std::vector<std::vector<Double_t>> data;
262  if (!TRestTools::ReadASCIITable(fname, data, 2)) {
263  RESTError << "TRestAxionOpticsMirror. Error reading HenkeFile table" << RESTendl;
264  }
265 
266  // we skip the last point if we are not at the latest angles file
267  Int_t N = data.size() - 1;
268  if (n == 4.5) N = N + 1;
269 
270  for (int m = 0; m < N; m++) reflectivity[e].push_back((Float_t)data[m][1]);
271  for (int m = 0; m < N; m++) transmission[e].push_back((Float_t)data[m][2]);
272  }
273  cout << endl;
274  }
275  cout << "Number of angles stored : " << reflectivity[30].size() << endl;
276 
277  for (const auto& x : reflectivity) {
278  fReflectivityTable.push_back(x.second);
279  }
280  for (const auto& x : transmission) {
281  fTransmissionTable.push_back(x.second);
282  }
283 
284  ExportTables();
285 }
286 
292  string fnameR = "Reflectivity_" + fMirrorType + "_" + fLayerTop + "_" + fLayerThicknessTop + "_" +
293  fSubstrate + "_" + fSigmaTop + ".N901f";
294  if (fMirrorType == "Bilayer")
295  fnameR = "Reflectivity_" + fMirrorType + "_" + fLayerTop + "_" + fLayerThicknessTop + "_" +
296  fSigmaTop + "_" + fLayerBottom + "_" + fLayerThicknessBottom + "_" + fSigmaBottom + "_" +
297  fSubstrate + ".N901f";
298  return fnameR;
299 }
300 
306  string fnameT = "Transmission_" + fMirrorType + "_" + fLayerTop + "_" + fLayerThicknessTop + "_" +
307  fSubstrate + "_" + fSigmaTop + ".N901f";
308  if (fMirrorType == "Bilayer")
309  fnameT = "Transmission_" + fMirrorType + "_" + fLayerTop + "_" + fLayerThicknessTop + "_" +
310  fSigmaTop + "_" + fLayerBottom + "_" + fLayerThicknessBottom + "_" + fSigmaBottom + "_" +
311  fSubstrate + ".N901f";
312  return fnameT;
313 }
314 
320  if (fReflectivityTable.size() == 0) {
321  RESTError << "Nothing to export!" << RESTendl;
322  return 1;
323  }
324 
325  string path = REST_USER_PATH + "/export/";
326 
327  if (!TRestTools::fileExists(path)) {
328  std::cout << "Creating path: " << path << std::endl;
329  int z = system(("mkdir -p " + path).c_str());
330  if (z != 0) RESTError << "Problem creating directory: " << path << RESTendl;
331  }
332 
333  string fnameR = GetReflectivityFilename();
335  RESTInfo << "Reflectivity table generated at: " << path + fnameR << RESTendl;
336 
337  string fnameT = GetTransmissionFilename();
339  RESTInfo << "Transmission table generated at: " << path + fnameT << RESTendl;
340 
341  return 0;
342 }
343 
351  string perlName = "laymir.pl";
352  if (fMirrorType == "Bilayer") perlName = "bimir.pl";
353  string url = "https://henke.lbl.gov/cgi-bin/" + perlName;
354  string result = TRestTools::POSTRequest(url, fHenkeKeys);
355 
356  size_t start = result.find("HREF=\"") + 6;
357  size_t length = result.find(".dat\">") + 4 - start;
358  result = result.substr(start, length);
359 
360  return TRestTools::DownloadRemoteFile("https://henke.lbl.gov/" + result);
361 }
362 
367 Double_t TRestAxionOpticsMirror::GetReflectivity(const Double_t angle, const Double_t energy) {
368  if (fReflectivityTable.size() == 0) LoadTables();
369 
370  Double_t en = energy;
371  if (en < 0.030) {
372  RESTWarning << "Energy is below 30eV! It should be between 30eV and 15keV" << RESTendl;
373  RESTWarning << "Setting energy to 30eV" << RESTendl;
374  en = 0.030;
375  }
376 
377  if (en > 15) {
378  RESTWarning << "Energy is above 15keV! It should be between 30eV and 15keV" << RESTendl;
379  RESTWarning << "Setting energy to 15keV" << RESTendl;
380  en = 15;
381  }
382 
383  Int_t lowEnBin = (Int_t)((en - 0.03) / 0.03);
384  Double_t deltaE = (en - (Double_t)(lowEnBin + 1) * 0.03) / 0.03; // between 0 and 1
385 
386  Double_t ang = angle;
387  if (ang < 0.0) {
388  RESTWarning << "Angle is below 0 degrees! It should be between 0 and 9 degrees" << RESTendl;
389  RESTWarning << "Setting angle to 0 degrees" << RESTendl;
390  ang = 0.0;
391  }
392 
393  if (ang > 9) {
394  RESTWarning << "Angle is above 9 degrees! It should be between 0 and 9 degrees" << RESTendl;
395  RESTWarning << "Setting angle to 9 degrees" << RESTendl;
396  ang = 9;
397  }
398 
399  Int_t lowAngBin = (Int_t)((ang) / 0.01);
400  Double_t deltaAng = (ang - (Double_t)(lowAngBin)*0.01) / 0.01; // between 0 and 1
401 
402  Double_t REnLowAngLow = fReflectivityTable[lowEnBin][lowAngBin];
403  Double_t REnLowAngHi = fReflectivityTable[lowEnBin][lowAngBin + 1];
404  Double_t REnHiAngLow = fReflectivityTable[lowEnBin + 1][lowAngBin];
405  Double_t REnHiAngHi = fReflectivityTable[lowEnBin + 1][lowAngBin + 1];
406 
407  // We have renormalized the grid to unity and now we apply the equation z = f(x,y)
408  // where x is associated with the energy, y is associated with the angle
409  // z = f(x,y) = (1−x)(1−y) * v00+x(1−y) * v10+(1−x)y * v01+xy * v11
410  // So that, for example, when x=1 and v=1 we get v11=REnHiAngHi
411  return (1 - deltaE) * (1 - deltaAng) * REnLowAngLow + deltaE * (1 - deltaAng) * REnHiAngLow +
412  (1 - deltaE) * deltaAng * REnLowAngHi + deltaE * deltaAng * REnHiAngHi;
413 }
414 
419 Double_t TRestAxionOpticsMirror::GetTransmission(const Double_t angle, const Double_t energy) {
420  if (fTransmissionTable.size() == 0) LoadTables();
421 
422  Double_t en = energy;
423  if (en < 0.030) {
424  RESTWarning << "Energy is below 30eV! It should be between 30eV and 15keV" << RESTendl;
425  RESTWarning << "Setting energy to 30eV" << RESTendl;
426  en = 0.030;
427  }
428 
429  if (en > 15) {
430  RESTWarning << "Energy is above 15keV! It should be between 30eV and 15keV" << RESTendl;
431  RESTWarning << "Setting energy to 15keV" << RESTendl;
432  en = 15;
433  }
434 
435  Int_t lowEnBin = (Int_t)((en - 0.03) / 0.03);
436  Double_t deltaE = (en - (Double_t)(lowEnBin + 1) * 0.03) / 0.03; // between 0 and 1
437 
438  Double_t ang = angle;
439  if (ang < 0.0) {
440  RESTWarning << "Angle is below 0 degrees! It should be between 0 and 9 degrees" << RESTendl;
441  RESTWarning << "Setting angle to 0 degrees" << RESTendl;
442  ang = 0.0;
443  }
444 
445  if (ang > 9) {
446  RESTWarning << "Angle is above 9 degrees! It should be between 0 and 9 degrees" << RESTendl;
447  RESTWarning << "Setting angle to 9 degrees" << RESTendl;
448  ang = 9;
449  }
450 
451  Int_t lowAngBin = (Int_t)((ang) / 0.01);
452  Double_t deltaAng = (ang - (Double_t)(lowAngBin)*0.01) / 0.01; // between 0 and 1
453 
454  Double_t REnLowAngLow = fTransmissionTable[lowEnBin][lowAngBin];
455  Double_t REnLowAngHi = fTransmissionTable[lowEnBin][lowAngBin + 1];
456  Double_t REnHiAngLow = fTransmissionTable[lowEnBin + 1][lowAngBin];
457  Double_t REnHiAngHi = fTransmissionTable[lowEnBin + 1][lowAngBin + 1];
458 
459  // We have renormalized the grid to unity and now we apply the equation z = f(x,y)
460  // where x is associated with the energy, y is associated with the angle
461  // z = f(x,y) = (1−x)(1−y) * v00+𝑥(1−y) * v10+(1−𝑥)y * v01+xy * v11
462  // So that, for example, when x=1 and v=1 we get v11=REnHiAngHi
463 
464  return (1 - deltaE) * (1 - deltaAng) * REnLowAngLow + deltaE * (1 - deltaAng) * REnHiAngLow +
465  (1 - deltaE) * deltaAng * REnLowAngHi + deltaE * deltaAng * REnHiAngHi;
466 }
467 
473 
474  RESTMetadata << "Mirror type: " << fMirrorType << RESTendl;
475  if (fMirrorType == "Single") {
476  RESTMetadata << "Layer material: " << fLayerTop << RESTendl;
477  RESTMetadata << "Layer thickness: " << fLayerThicknessTop << " nm" << RESTendl;
478  RESTMetadata << "Layer roughness: " << fSigmaTop << "nm" << RESTendl;
479  }
480 
481  if (fMirrorType == "Bilayer") {
482  RESTMetadata << "Top layer material: " << fLayerTop << RESTendl;
483  RESTMetadata << "Top layer thickness: " << fLayerThicknessTop << " nm" << RESTendl;
484  RESTMetadata << "Top layer roughness: " << fSigmaTop << "nm" << RESTendl;
485  RESTMetadata << "Bottom layer material: " << fLayerBottom << RESTendl;
486  RESTMetadata << "Bottom layer thickness: " << fLayerThicknessBottom << " nm" << RESTendl;
487  RESTMetadata << "Bottom layer roughness: " << fSigmaBottom << "nm" << RESTendl;
488  }
489  RESTMetadata << "Substrate material: " << fSubstrate << RESTendl;
490  RESTMetadata << "+++++++++++++++++++++++++++++++++++++++++++++++++" << RESTendl;
491 }
492 
526 TCanvas* TRestAxionOpticsMirror::DrawOpticsProperties(std::string options, Double_t lowRange,
527  Double_t lowRange2) {
528  if (fReflectivityTable.size() == 0) LoadTables();
529 
530  std::vector<string> optList = TRestTools::GetOptions(options);
531 
532  if (optList.size() == 0)
533  optList = TRestTools::GetOptions(
534  "[1,4,7,10](0,9){0.6,0.68,0.9,0.88}:[0.25,0.5,0.75,1](0,10){0.2,0.2,0.45,0.45}");
535 
536  if (optList.size() != 2) {
537  RESTError << "TRestAxionOpticsMirror::DrawOpticsProperties. Wrong arguments!" << RESTendl;
538  return fCanvas;
539  }
540 
541  std::vector<double> energies = StringToElements(optList[0], "[", ",", "]");
542  std::vector<double> aRange = StringToElements(optList[0], "(", ",", ")");
543  std::vector<double> eLegendCoords = StringToElements(optList[0], "{", ",", "}");
544 
545  std::vector<double> angles = StringToElements(optList[1], "[", ",", "]");
546  std::vector<double> eRange = StringToElements(optList[1], "(", ",", ")");
547  std::vector<double> aLegendCoords = StringToElements(optList[1], "{", ",", "}");
548 
549  if (eRange[0] < 0.03) eRange[0] = 0.03;
550  if (eRange[1] > 15) eRange[1] = 15;
551  if (aRange[0] < 0.0) aRange[0] = 0.0;
552  if (aRange[1] > 9) aRange[1] = 9;
553 
554  // Double_t lowReflec = TRestTools::GetMinValueFromTable(fReflectivityTable);
555  // Double_t highReflec = TRestTools::GetMaxValueFromTable(fReflectivityTable);
556 
557  if (fCanvas != NULL) {
558  delete fCanvas;
559  fCanvas = NULL;
560  }
561  fCanvas = new TCanvas("canv", "This is the canvas title", 1400, 1200);
562  fCanvas->Draw();
563 
564  TPad* pad1 = new TPad("pad1", "This is pad1", 0.01, 0.02, 0.99, 0.97);
565  pad1->Divide(2, 2);
566  pad1->Draw();
567 
569  pad1->cd(1);
570  pad1->cd(1)->SetLogy();
571  pad1->cd(1)->SetRightMargin(0.09);
572  pad1->cd(1)->SetLeftMargin(0.15);
573  pad1->cd(1)->SetBottomMargin(0.15);
574 
575  std::vector<TGraph*> ref_vs_ang_graph;
576 
577  for (unsigned int n = 0; n < energies.size(); n++) {
578  string grname = "gr" + IntegerToString(n);
579  TGraph* gr = new TGraph();
580  gr->SetName(grname.c_str());
581  for (double a = aRange[0]; a <= aRange[1]; a += (aRange[1] - aRange[0]) / 10000.) {
582  gr->SetPoint(gr->GetN(), a, GetReflectivity(a, energies[n]));
583  }
584  gr->SetLineColor(49 - n * 3);
585  gr->SetLineWidth(2);
586  ref_vs_ang_graph.push_back(gr);
587  }
588 
589  ref_vs_ang_graph[0]->GetXaxis()->SetLimits(aRange[0], aRange[1]);
590  ref_vs_ang_graph[0]->GetHistogram()->SetMaximum(1);
591  ref_vs_ang_graph[0]->GetHistogram()->SetMinimum(lowRange);
592 
593  ref_vs_ang_graph[0]->GetXaxis()->SetTitle("Angle [degrees]");
594  ref_vs_ang_graph[0]->GetXaxis()->SetTitleSize(0.05);
595  ref_vs_ang_graph[0]->GetXaxis()->SetLabelSize(0.05);
596  ref_vs_ang_graph[0]->GetYaxis()->SetTitle("Reflectivity");
597  ref_vs_ang_graph[0]->GetYaxis()->SetTitleOffset(1.5);
598  ref_vs_ang_graph[0]->GetYaxis()->SetTitleSize(0.05);
599  ref_vs_ang_graph[0]->GetYaxis()->SetLabelSize(0.05);
600  pad1->cd(1)->SetLogy();
601  ref_vs_ang_graph[0]->Draw("AL");
602  for (unsigned int n = 1; n < energies.size(); n++) ref_vs_ang_graph[n]->Draw("L");
603 
604  Double_t lx1 = 0.6, ly1 = 0.75, lx2 = 0.9, ly2 = 0.95;
605  if (eLegendCoords.size() > 0) {
606  lx1 = eLegendCoords[0];
607  ly1 = eLegendCoords[1];
608  lx2 = eLegendCoords[2];
609  ly2 = eLegendCoords[3];
610  }
611  TLegend* legend = new TLegend(lx1, ly1, lx2, ly2);
612 
613  legend->SetTextSize(0.03);
614  legend->SetHeader("Energies", "C"); // option "C" allows to center the header
615  for (unsigned int n = 0; n < energies.size(); n++) {
616  std::string lname = "gr" + IntegerToString(n);
617  std::string ltitle = DoubleToString(energies[n]) + " keV";
618 
619  legend->AddEntry(lname.c_str(), ltitle.c_str(), "l");
620  }
621  legend->Draw();
622 
624  pad1->cd(2);
625  pad1->cd(2)->SetLogy();
626  pad1->cd(2)->SetRightMargin(0.09);
627  pad1->cd(2)->SetLeftMargin(0.15);
628  pad1->cd(2)->SetBottomMargin(0.15);
629 
630  std::vector<TGraph*> ref_vs_en_graph;
631 
632  for (unsigned int n = 0; n < angles.size(); n++) {
633  string grname = "agr" + IntegerToString(n);
634  TGraph* gr = new TGraph();
635  gr->SetName(grname.c_str());
636  for (double e = eRange[0]; e <= eRange[1]; e += (eRange[1] - eRange[0]) / 10000.) {
637  gr->SetPoint(gr->GetN(), e, GetReflectivity(angles[n], e));
638  }
639  gr->SetLineColor(49 - n * 3);
640  gr->SetLineWidth(2);
641  ref_vs_en_graph.push_back(gr);
642  }
643 
644  ref_vs_en_graph[0]->GetXaxis()->SetLimits(eRange[0], eRange[1]);
645  ref_vs_en_graph[0]->GetHistogram()->SetMaximum(1);
646  ref_vs_en_graph[0]->GetHistogram()->SetMinimum(lowRange2);
647 
648  ref_vs_en_graph[0]->GetXaxis()->SetTitle("Energy [keV]");
649  ref_vs_en_graph[0]->GetXaxis()->SetTitleSize(0.05);
650  ref_vs_en_graph[0]->GetXaxis()->SetLabelSize(0.05);
651  ref_vs_en_graph[0]->GetYaxis()->SetTitle("Reflectivity");
652  ref_vs_en_graph[0]->GetYaxis()->SetTitleOffset(1.5);
653  ref_vs_en_graph[0]->GetYaxis()->SetTitleSize(0.05);
654  ref_vs_en_graph[0]->GetYaxis()->SetLabelSize(0.05);
655  pad1->cd(2)->SetLogy();
656  ref_vs_en_graph[0]->Draw("AL");
657  for (unsigned int n = 1; n < angles.size(); n++) ref_vs_en_graph[n]->Draw("L");
658 
659  if (aLegendCoords.size() > 0) {
660  lx1 = aLegendCoords[0];
661  ly1 = aLegendCoords[1];
662  lx2 = aLegendCoords[2];
663  ly2 = aLegendCoords[3];
664  }
665  TLegend* legendA = new TLegend(lx1, ly1, lx2, ly2);
666  legendA->SetTextSize(0.03);
667  legendA->SetHeader("Angles", "C"); // option "C" allows to center the header
668  for (unsigned int n = 0; n < angles.size(); n++) {
669  std::string lname = "agr" + IntegerToString(n);
670  std::string ltitle = DoubleToString(angles[n]) + " degrees";
671 
672  legendA->AddEntry(lname.c_str(), ltitle.c_str(), "l");
673  }
674  legendA->Draw();
675 
677 
679  pad1->cd(3);
680  pad1->cd(3)->SetRightMargin(0.09);
681  pad1->cd(3)->SetLeftMargin(0.15);
682  pad1->cd(3)->SetBottomMargin(0.15);
683  // ref_vs_ang_graph[0]->GetHistogram()->SetMinimum(0);
684  ref_vs_ang_graph[0]->Draw("AL");
685  for (unsigned int n = 1; n < energies.size(); n++) ref_vs_ang_graph[n]->Draw("L");
686 
688  pad1->cd(4);
689  pad1->cd(4)->SetRightMargin(0.09);
690  pad1->cd(4)->SetLeftMargin(0.15);
691  pad1->cd(4)->SetBottomMargin(0.15);
692 
693  // ref_vs_en_graph[0]->GetHistogram()->SetMinimum(0);
694  ref_vs_en_graph[0]->Draw("AL");
695  for (unsigned int n = 1; n < angles.size(); n++) ref_vs_en_graph[n]->Draw("L");
696 
698  fCanvas->cd(); // c1 is the TCanvas
699  TPad* pad5 = new TPad("all", "all", 0, 0, 1, 1);
700  pad5->SetFillStyle(4000); // transparent
701  pad5->Draw();
702  pad5->cd();
703  TLatex* lat = new TLatex();
704 
705  std::string title;
706  if (fMirrorType == "Single") {
707  title = "Mirror type:" + fMirrorType + " Substrate: " + fSubstrate + ". Layer: " + fLayerTop +
708  " Thickness: " + fLayerThicknessTop + "nm Roughness: " + fSigmaTop + "nm.";
709  lat->SetTextSize(0.02);
710  }
711  if (fMirrorType == "Bilayer") {
712  title = "Mirror type:" + fMirrorType + " Substrate: " + fSubstrate + ". TOP Layer: " + fLayerTop +
713  " Thickness: " + fLayerThicknessTop + "nm Roughness: " + fSigmaTop +
714  "nm. \nBOTTOM Layer: " + fLayerBottom + " Thickness: " + fLayerThicknessBottom +
715  "nm Roughness: " + fSigmaBottom + " nm.";
716  lat->SetTextSize(0.015);
717  }
718  lat->SetTextAlign(22);
719  lat->DrawLatexNDC(.5, .95, title.c_str());
720  return fCanvas;
721 }
A metadata class accessing the Henke database to load reflectivity data.
std::string fSigmaTop
Layer surface roughness in nm.
std::string fLayerThicknessBottom
The bottom layer thickness in nm. Only used for "Bilayer" mirror type.
std::string fSubstrate
The substrate material.
std::string GetTransmissionFilename()
It returns the corresponding transmission filename for the mirror properties defined in the data memb...
std::string fSigmaBottom
Bottom layer surface roughness in nm. Only used for "Bilayer" mirror type.
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).
TCanvas * DrawOpticsProperties(std::string options="", Double_t lowRange=1.e-9, Double_t lowRange2=1.e-3)
A method that creates a canvas where the mirror optics properties are drawn. It generates two plots,...
std::string fLayerThicknessTop
The layer thickness in nm.
void LoadTables()
Loads the reflectivity table.
void PrintMetadata()
Prints on screen the information about the metadata members of TRestAxionOpticsMirror.
std::vector< std::vector< Float_t > > fReflectivityTable
The reflectivity loaded as a table with angle versus energy.
std::map< std::string, std::string > fHenkeKeys
A set of key-value pairs sent to the Henke website for data request.
Int_t ExportTables()
It is a private method to export the tables to a binary file once the tables have been downloaded fro...
TRestAxionOpticsMirror()
Default constructor.
void Initialize()
Initialization of TRestAxionOpticsMirror members.
std::string fLayerBottom
The mirror bottom layer material (chemical formula). Only used for "Bilayer" mirror type.
TCanvas * fCanvas
A canvas to insert the optic properties drawing.
~TRestAxionOpticsMirror()
Default destructor.
Double_t GetTransmission(const Double_t angle, const Double_t energy)
It returns the interpolated transmission for a given angle (in degrees) and a given energy (in keV).
std::string fLayerTop
The mirror layer material (chemical formula).
std::string GetReflectivityFilename()
It returns the corresponding reflectivity filename for the mirror properties defined in the data memb...
std::string fMirrorType
The mirror type (Thick, Single, Bilayer, Multilayer). Only Single/Bilayer is supported now.
std::string DownloadHenkeFile()
It downloads the reflectivity file for the present mirror properties defined at the metadata members.
std::vector< std::vector< Float_t > > fTransmissionTable
The transmission loaded as a table with angle versus energy.
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.
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.
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 SearchFile(std::string filename)
Search files in current directory and directories specified in "searchPath" section.
std::string fConfigFileName
Full name of the rml file.
@ REST_Info
+show most of the information for each steps
static std::string POSTRequest(const std::string &url, const std::map< std::string, std::string > &keys)
It performs a POST web protocol request using a set of keys and values given by argument,...
static std::vector< std::string > GetOptions(std::string optionsStr)
Returns all the options in an option string.
Definition: TRestTools.cxx:86
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static std::string DownloadRemoteFile(const std::string &remoteFile, bool pidPrefix=false)
download the remote file automatically, returns the downloaded file name.
static int ReadBinaryTable(std::string fName, std::vector< std::vector< T >> &data, Int_t columns=-1)
Reads a binary file containing a fixed-columns table with values.
Definition: TRestTools.cxx:253
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
static int ExportBinaryTable(std::string fname, std::vector< std::vector< T >> &data)
Writes the contents of the vector table given as argument to fname as a binary file....
Definition: TRestTools.cxx:214
std::string IntegerToString(Int_t n, std::string format="%d")
Gets a string from an integer.
std::string DoubleToString(Double_t d, std::string format="%8.6e")
Gets a string from a double.
std::vector< double > StringToElements(std::string in, std::string separator)
Convert the input string into a vector of double elements.