ARTEMIS-CRIB
 
Loading...
Searching...
No Matches
TUserGeoInitializer.cc
Go to the documentation of this file.
1/**
2 * @file TUserGeoInitializer.cc
3 * @brief
4 * @author Kodai Okawa<okawa@cns.s.u-tokyo.ac.jp>
5 * @date 2024-01-17 21:27:49
6 * @note last modified: 2024-08-23 21:33:03
7 * @details
8 */
9
10#include "TUserGeoInitializer.h"
11
12#include "TDetectorParameter.h"
13#include "TTargetParameter.h"
14#include <TDirectory.h>
15#include <TVector3.h>
16#include <yaml-cpp/yaml.h>
17
19
21
22// definition of constant strings for the key of each node
23namespace {
24const char *kNodeKeyMaterial = "material";
25const char *kNodeKeyConposition = "conposition";
26const char *kNodeKeyVolume = "volume";
27const char *kNodeKeyName = "name";
28const char *kNodeKeyAMass = "atomic_mass";
29const char *kNodeKeyANum = "atomic_num";
30const char *kNodeKeyDensity = "density";
31const char *kNodeKeyThickness = "thickness";
32const char *kNodeKeyCenterRot = "center_rotation";
33const char *kNodeKeyDistance = "distance";
34const char *kNodeKeyAngle = "angle";
35const char *kNodeKeyTop = "top";
36const char *kNodeKeyDetector = "detector";
37const char *kNodeKeyTarget = "target";
38const char *kNodeKeyType = "type";
39const char *kNodeKeySize = "size";
40const char *kNodeKeyOffset = "offset";
41const char *kNodeKeyStrip = "strip";
42const char *kNodeKeyIsGas = "is_gas";
43const char *kNodeKeyZ = "z_position";
44const char *kNodeKeyPedestal = "pedestal";
45} // namespace
46
47////////////////////////////////////////////////////////////////////////////////
48/// In the steering file, we set two parameters,
49///
50/// - "FileName": geometry file, like prm/geo/expname.yaml
51/// - "Visible": make detector geometry figure
52///
53/// in the source code, the geometry parameter objects
54/// can be used by the name of "prm_detector" or "prm_target"
55/// in the constructor of other processor, you can get this
56/// object by
57/// ```
58/// RegisterOptionalInputInfo("DetectorParameter", "name of telescope parameter", fDetectorParameterName,
59/// TString("prm_detectors"), &fDetectorPrm, "TClonesArray", "art::crib::TDetectorParameter");
60/// ```
61
63 RegisterProcessorParameter("DetName", "parameter name of detectors", fDetPrmName, TString("prm_detectors"));
64 RegisterProcessorParameter("TargetName", "parameter name of targets", fTargetPrmName, TString("prm_targets"));
65 RegisterProcessorParameter("FileName", "parameter file of detector geometry", fFileName, TString(""));
66
67 RegisterProcessorParameter("Visible", "add artemis directory or not", fIsVisible, false);
68}
69
71 delete fGeom;
72 delete fDetParameterArray;
74 fGeom = nullptr;
75 fDetParameterArray = nullptr;
76 fTargetParameterArray = nullptr;
77}
78
79void TUserGeoInitializer::Init(TEventCollection *col) {
80 Info("Init", "geometry parameter is loaded from %s", fFileName.Data());
81 if (gGeoManager) {
82 delete gGeoManager;
83 }
84 fGeom = new TGeoManager("geometry", "Detector Geometry");
85
86 Info("Init", "detector parameters are produced to %s", fDetPrmName.Data());
87 fDetParameterArray = new TClonesArray("art::crib::TDetectorParameter");
88
89 Info("Init", "target parameters are produced to %s", fTargetPrmName.Data());
90 fTargetParameterArray = new TClonesArray("art::crib::TTargetParameter");
91
93
94 col->Add("geom", fGeom, fOutputIsTransparent);
95
97 col->AddInfo(fDetPrmName, fDetParameterArray, fOutputIsTransparent);
98
100 col->AddInfo(fTargetPrmName, fTargetParameterArray, fOutputIsTransparent);
101}
102
104
106 FileStat_t info;
107 if (gSystem->GetPathInfo(yamlfile.Data(), info) != 0) {
108 SetStateError(Form("File %s does not exist.", yamlfile.Data()));
109 return;
110 }
111
112 YAML::Node yaml_all = YAML::LoadFile(yamlfile.Data());
113
114#if 0
115 YAML::Emitter emitter;
116 emitter << yaml_all;
117 std::cout << emitter.c_str() << std::endl;
118 std::cout << yaml_all.size() << std::endl;
119#endif
120
121 // TGeo material setting
122 YAML::Node yaml_mat = yaml_all[kNodeKeyMaterial].as<YAML::Node>();
123 std::vector<TGeoMaterial *> mat_vec;
124 std::vector<TGeoMedium *> med_vec;
125 for (decltype(yaml_mat.size()) i = 0; i < yaml_mat.size(); i++) {
126 TString name = yaml_mat[i][kNodeKeyName].as<std::string>();
127 Double_t atm_mass = yaml_mat[i][kNodeKeyAMass].as<double>();
128 Double_t atm_num = yaml_mat[i][kNodeKeyANum].as<double>();
129 Double_t density = yaml_mat[i][kNodeKeyDensity].as<double>();
130 mat_vec.emplace_back(new TGeoMaterial(name.Data(), atm_mass, atm_num, density));
131 med_vec.emplace_back(new TGeoMedium(name.Data(), i + 1, mat_vec[mat_vec.size() - 1]));
132 }
133
134 // TGeo top setting
135 YAML::Node yaml_top = yaml_all[kNodeKeyVolume][kNodeKeyTop].as<YAML::Node>();
136 TString top_name = yaml_top[kNodeKeyName].as<std::string>();
137 Int_t top_mat_id = yaml_top[kNodeKeyMaterial].as<int>();
138 DoubleVec_t top_size = yaml_top[kNodeKeySize].as<std::vector<double>>();
139 if (top_size.size() != 3) {
140 SetStateError("input yaml error");
141 return;
142 }
143
144 TGeoVolume *top =
145 fGeom->MakeBox(top_name.Data(), med_vec[top_mat_id], top_size[0] / 2., top_size[1] / 2., top_size[2] / 2.);
146 fGeom->SetTopVolume(top);
147
148 // TGeo detector setting
149 YAML::Node yaml_prm = yaml_all[kNodeKeyConposition][kNodeKeyDetector].as<YAML::Node>();
150 YAML::Node yaml_det = yaml_all[kNodeKeyVolume][kNodeKeyDetector].as<YAML::Node>();
151 if (yaml_prm.size() != yaml_det.size()) {
152 SetStateError("in yaml, conposition number and detector number is different");
153 return;
154 }
155
156 for (decltype(yaml_det.size()) i = 0; i < yaml_det.size(); i++) {
157 if (yaml_prm[i][kNodeKeyName].as<std::string>() != yaml_det[i][kNodeKeyName].as<std::string>()) {
158 SetStateError("in yaml, set same order for composition and detector");
159 return;
160 }
161 TString det_name = yaml_det[i][kNodeKeyName].as<std::string>();
162 Int_t det_mat_id = yaml_det[i][kNodeKeyMaterial].as<int>();
163 DoubleVec_t det_size = yaml_det[i][kNodeKeySize].as<std::vector<double>>();
164 if (det_size.size() != 3) {
165 SetStateError("input yaml error, detector volume size must be 3D");
166 return;
167 }
168
169 // currently only support box type detector
170 if (yaml_det[i][kNodeKeyType].as<std::string>() != "box") {
171 SetStateError("Currently only support only box type");
172 return;
173 }
174
175 TGeoVolume *det =
176 fGeom->MakeBox(det_name.Data(), med_vec[det_mat_id], det_size[0] / 2., det_size[1] / 2., det_size[2] / 2.);
177 DoubleVec_t rot_point = yaml_prm[i][kNodeKeyCenterRot].as<std::vector<double>>();
178 DoubleVec_t offset = yaml_prm[i][kNodeKeyOffset].as<std::vector<double>>();
179 IntVec_t det_strip = yaml_prm[i][kNodeKeyStrip].as<std::vector<int>>();
180 if (rot_point.size() != 3 || offset.size() != 3 || det_strip.size() != 2) {
181 SetStateError("input yaml error, detector conposition setting is wrong");
182 return;
183 }
184 Double_t distance = yaml_prm[i][kNodeKeyDistance].as<double>();
185 Double_t angle = yaml_prm[i][kNodeKeyAngle].as<double>() * deg2rad;
186
187 TVector3 det_pos(offset[0], offset[1], distance + offset[2]);
188 det_pos.RotateY(angle);
189 TVector3 rot_point_vec(rot_point[0], rot_point[1], rot_point[2]);
190 det_pos += rot_point_vec;
191
192 TGeoCombiTrans *det_trans =
193 new TGeoCombiTrans(det_pos.X(), det_pos.Y(), det_pos.Z(), new TGeoRotation("rot", 90.0, angle / deg2rad, 0.0));
194 top->AddNode(det, i, det_trans);
195
196 // parameter input
197 TDetectorParameter *prm = static_cast<TDetectorParameter *>(fDetParameterArray->ConstructedAt(i));
198 DoubleVec_t thickness = yaml_prm[i][kNodeKeyThickness].as<std::vector<double>>();
199 DoubleVec_t pedestal = yaml_prm[i][kNodeKeyPedestal].as<std::vector<double>>();
200 if (thickness.size() != pedestal.size()) {
201 SetStateError("input yaml error, thickness and pedestal array size are different");
202 return;
203 }
204 std::vector<std::string> material = yaml_prm[i][kNodeKeyMaterial].as<std::vector<std::string>>();
205 StringVec_t material_vec;
206 for (decltype(thickness.size()) j = 0; j < thickness.size(); j++) {
207 if (material.size() == 1) {
208 material_vec.emplace_back(material[0]);
209 } else if (material.size() == thickness.size()) {
210 material_vec.emplace_back(material[j]);
211 } else {
212 SetStateError("input yaml error, composition thickness and material is wrong");
213 return;
214 }
215 }
216
217 if (thickness.size() != material_vec.size()) {
218 SetStateError("something wrong happen...");
219 return;
220 }
221
222 prm->SetDetName(det_name);
223 prm->SetN(thickness.size());
224 prm->SetMaxRadius(top_size[2]);
225 prm->SetMaterial(material_vec);
226 prm->SetThickness(thickness);
227 prm->SetPedestal(pedestal);
228 prm->SetCenterRotPos(rot_point);
229 prm->SetOffset(offset);
230 prm->SetDistance(distance);
231 prm->SetAngle(angle); // radian
232 prm->SetSize(det_size);
233 prm->SetStripNum(det_strip);
234 }
235
236 // targets setting
237 YAML::Node yaml_target = yaml_all[kNodeKeyConposition][kNodeKeyTarget].as<YAML::Node>();
238 for (decltype(yaml_target.size()) i = 0; i < yaml_target.size(); i++) {
239 TTargetParameter *prm = static_cast<TTargetParameter *>(fTargetParameterArray->ConstructedAt(i));
240 TString name = yaml_target[i][kNodeKeyName].as<std::string>();
241 Bool_t is_gas = yaml_target[i][kNodeKeyIsGas].as<bool>();
242 Double_t z = yaml_target[i][kNodeKeyZ].as<double>();
243 Double_t thickness = yaml_target[i][kNodeKeyThickness].as<double>();
244
245 prm->SetTargetName(name);
246 prm->SetIsGasState(is_gas);
247 prm->SetZ(z);
248 prm->SetThickness(thickness);
249 }
250
251 fGeom->CloseGeometry();
252 fGeom->SetTopVisible();
253 top->SetLineColor(kRed);
254
255 if (fIsVisible) {
256 gDirectory->Add(top);
257 }
258}
ClassImp(TUserGeoInitializer)
void SetOffset(DoubleVec_t vec)
void SetCenterRotPos(DoubleVec_t vec)
void SetPedestal(DoubleVec_t vec)
void SetMaterial(StringVec_t vec)
void SetThickness(DoubleVec_t vec)
void SetTargetName(TString val)
void SetThickness(Double_t val)
TString fFileName
Input geometry file name. You can define in steering file.
TString fDetPrmName
It should be "prm_detector".
TGeoManager * fGeom
It is used for TGeoManager process.
~TUserGeoInitializer() override
destructor
TString fTargetPrmName
It should be "prm_target".
TClonesArray * fTargetParameterArray
Target parameter object (art::TTargetParameter array)
Bool_t fIsVisible
Make figure of Detectors of not.
void Init(TEventCollection *col) override
init
TClonesArray * fDetParameterArray
Detector parameter object (art::TDetectorParameter array)
void GeometryFromYaml(TString yamlfile)
Double_t deg2rad
angle converter, degree to radian
return to the guide