File indexing completed on 2025-01-18 09:15:25
0001 #include <cstdlib>
0002 #include <iostream>
0003 #include <fmt/format.h>
0004
0005 #include "g4dRIChOptics.hh"
0006 #include "surfaceEnums.h"
0007
0008 #include <TCanvas.h>
0009 #include <TGraphErrors.h>
0010 #include <TAxis.h>
0011 #include <TFile.h>
0012
0013
0014
0015 const int aerOptModel = 3;
0016 const double filter_thr = 300*nm;
0017 const bool vsWavelength = true;
0018 const std::string xmlOutput = "out/optical_materials_drich.xml";
0019 const TString root_file_name = "out/optical_materials_drich.root";
0020
0021
0022
0023 std::FILE *xmlFile;
0024
0025
0026
0027 class UnitDef {
0028 public:
0029 UnitDef(double divisor_, std::string name_) : divisor(divisor_), name(name_), xml(""), title("") {
0030 if(name!="") {
0031 xml = "*" + name;
0032 title = " [" + name + "]";
0033 }
0034 }
0035 double divisor;
0036 std::string name, xml, title;
0037 };
0038
0039
0040
0041
0042 template<class MAT> class MaterialTable {
0043 public:
0044 MAT *mpt;
0045 std::string name;
0046 MaterialTable(MAT *mpt_, std::string name_) : mpt(mpt_), name(name_) {
0047 if(name=="C2F6" or name=="C4F10") PreferredUnits = &PreferredUnits2;
0048 else PreferredUnits = &PreferredUnits1;
0049 }
0050 ~MaterialTable() { if(mpt!=nullptr) delete mpt; };
0051
0052
0053 void PrintXML(bool isSurface=false, G4String detectorName="DRICH") {
0054 fmt::print(xmlFile,"\n<!-- {:_^60} -->\n\n",name);
0055
0056 auto PrintRow = [] (int indentation, UnitDef units) {
0057 return [indentation,&units] (G4double energy, G4double value) {
0058 fmt::print(xmlFile,"{:{}}{:<#.6g}{} {:>#.7g}{}\n",
0059 "", indentation,
0060 energy/eV, "*eV",
0061 value/units.divisor, units.xml
0062 );
0063 };
0064 };
0065 if(isSurface) {
0066 auto surf = mpt->getSurface();
0067 fmt::print(xmlFile,"{:4}<opticalsurface name=\"{}_{}\" model=\"{}\" finish=\"{}\" type=\"{}\">\n",
0068 "",
0069 mpt->getLogicalVName(),
0070 detectorName,
0071 surfaceEnum::GetModel(surf),
0072 surfaceEnum::GetFinish(surf),
0073 surfaceEnum::GetType(surf)
0074 );
0075 for(const auto& propName : mpt->getMaterialPropertyNames()) {
0076 fmt::print(xmlFile,"{:6}<property name=\"{}\" coldim=\"2\" values=\"\n", "", propName);
0077 mpt->loopMaterialPropertyTable(propName,PrintRow(8,PreferredUnits->at(propName)));
0078 fmt::print(xmlFile,"{:8}\"/>\n","");
0079 }
0080 fmt::print(xmlFile,"{:4}</opticalsurface>\n","");
0081 } else {
0082 for(const auto& propName : mpt->getMaterialPropertyNames()) {
0083 fmt::print(xmlFile,"{:4}<matrix name=\"{}__{}_{}\" coldim=\"2\" values=\"\n",
0084 "",
0085 propName,
0086 mpt->getMaterialName(),
0087 detectorName
0088 );
0089 mpt->loopMaterialPropertyTable(propName,PrintRow(6,PreferredUnits->at(propName)));
0090 fmt::print(xmlFile,"{:6}\"/>\n","");
0091 }
0092 }
0093 }
0094
0095
0096 void DrawPlots() {
0097 TString canvName("materialProperties_"+name);
0098 TString pngName("out/"+canvName+".png");
0099 int ncols = 2;
0100 int nrows = 1+(mpt->getMaterialPropertyTableSize()-1)/ncols;
0101 if(nrows==1) ncols=mpt->getMaterialPropertyTableSize();
0102 auto canv = new TCanvas(canvName,canvName,ncols*800,nrows*600);
0103 canv->Divide(ncols,nrows);
0104 int pad=0;
0105 for(const auto& propName : mpt->getMaterialPropertyNames()) {
0106 fmt::print("Plotting property {}\n", propName);
0107 auto units = PreferredUnits->at(propName);
0108 canv->cd(++pad);
0109 canv->GetPad(pad)->SetGrid(1,1);
0110 canv->GetPad(pad)->SetLeftMargin(0.2);
0111 canv->GetPad(pad)->SetRightMargin(0.15);
0112 auto graph = new TGraphErrors();
0113 graph->SetName(TString("graph_"+name+"_"+propName));
0114 std::string xTitle = vsWavelength ? "wavelength [nm]" : "energy [eV]";
0115 graph->SetTitle(TString(name+" "+propName+units.title+";"+xTitle));
0116 auto makeGraph = [&graph,&units] (G4double energy, G4double value) {
0117 auto xval = vsWavelength ? g4dRIChOptics::e2wl(energy)/nm : energy/eV;
0118 graph->AddPoint(xval, value / units.divisor);
0119 };
0120 mpt->loopMaterialPropertyTable(propName,makeGraph, vsWavelength);
0121 graph->SetMarkerStyle(kFullCircle);
0122 graph->SetMarkerColor(kAzure);
0123 graph->GetXaxis()->SetLabelSize(0.05);
0124 graph->GetYaxis()->SetLabelSize(0.05);
0125 graph->GetXaxis()->SetTitleOffset(1.3);
0126 graph->Draw("AP");
0127 graph->Write();
0128 }
0129 canv->SaveAs(pngName);
0130 }
0131
0132
0133 const std::map<G4String,UnitDef> *PreferredUnits;
0134 const std::map<G4String,UnitDef> PreferredUnits1 = {
0135 { "RINDEX", UnitDef( 1., "" )},
0136 { "GROUPVEL", UnitDef( mm/ns, "mm/ns" )},
0137 { "RAYLEIGH", UnitDef( mm, "mm" )},
0138 { "ABSLENGTH", UnitDef( mm, "mm" )},
0139 { "REFLECTIVITY", UnitDef( 1., "" )},
0140 { "REALRINDEX", UnitDef( 1., "" )},
0141 { "IMAGINARYRINDEX", UnitDef( 1., "" )},
0142 { "EFFICIENCY", UnitDef( 1., "" )}
0143 };
0144 const std::map<G4String,UnitDef> PreferredUnits2 = {
0145 { "RINDEX", UnitDef( 1., "" )},
0146 { "GROUPVEL", UnitDef( mm/ns, "mm/ns" )},
0147 { "RAYLEIGH", UnitDef( m, "m" )},
0148 { "ABSLENGTH", UnitDef( m, "m" )},
0149 { "REFLECTIVITY", UnitDef( 1., "" )},
0150 { "REALRINDEX", UnitDef( 1., "" )},
0151 { "IMAGINARYRINDEX", UnitDef( 1., "" )},
0152 { "EFFICIENCY", UnitDef( 1., "" )}
0153 };
0154
0155 };
0156
0157
0158
0159 int main(int argc, char** argv) {
0160
0161
0162 xmlFile = std::fopen(xmlOutput.c_str(),"w");
0163 auto root_file = new TFile(root_file_name,"RECREATE");
0164
0165
0166 fmt::print("[+] read model text file\n");
0167 G4tgbVolumeMgr *volmgr = G4tgbVolumeMgr::GetInstance();
0168 auto model_file = G4String("text/drich-materials.txt");
0169 volmgr->AddTextFile(model_file);
0170 fmt::print("[+] construct detector from text file\n");
0171 G4VPhysicalVolume *vesselPhysVol = volmgr->ReadAndConstructDetector();
0172 fmt::print("[+] done construction\n");
0173
0174
0175
0176
0177 MaterialTable Aerogel(new g4dRIChAerogel("Aerogel"),"Aerogel");
0178 Aerogel.mpt->setOpticalParams(aerOptModel);
0179 Aerogel.PrintXML();
0180 Aerogel.DrawPlots();
0181
0182
0183 MaterialTable Acrylic(new g4dRIChFilter("Acrylic"),"Acrylic");
0184 Acrylic.mpt->setOpticalParams(filter_thr);
0185 Acrylic.PrintXML();
0186 Acrylic.DrawPlots();
0187
0188
0189
0190 MaterialTable C2F6(new g4dRIChGas("C2F6"),"C2F6");
0191 C2F6.mpt->setOpticalParams();
0192 C2F6.PrintXML();
0193 C2F6.DrawPlots();
0194
0195 MaterialTable C4F10(new g4dRIChGas("C4F10"),"C4F10");
0196 C4F10.mpt->setOpticalParams();
0197 C4F10.PrintXML(false,"PFRICH");
0198 C4F10.DrawPlots();
0199
0200
0201 MaterialTable MirrorSurface(new g4dRIChMirror("MirrorSurface"),"MirrorSurface");
0202 MirrorSurface.mpt->setOpticalParams("ciDRICH");
0203 MirrorSurface.PrintXML(true);
0204 MirrorSurface.DrawPlots();
0205
0206
0207 MaterialTable SensorSurface(new g4dRIChPhotosensor("SensorSurface"),"SensorSurface");
0208 SensorSurface.mpt->setOpticalParams("ciDRICH");
0209 SensorSurface.PrintXML(true);
0210 SensorSurface.DrawPlots();
0211
0212
0213 std::fclose(xmlFile);
0214 root_file->Close();
0215 fmt::print("\nwrote XML nodes to {}\n\n",xmlOutput);
0216
0217 }