FairRoot/PandaRoot
Public Member Functions | Private Member Functions | Private Attributes | List of all members
PndLmdGeometryFactory Class Reference

#include <PndLmdGeometryFactory.h>

Public Member Functions

 PndLmdGeometryFactory (const boost::property_tree::ptree &geometry_property_tree_)
 
virtual ~PndLmdGeometryFactory ()
 
void init (FairGeoLoader *geoLoad)
 
TGeoVolumeAssembly * generateLmdGeometry () const
 

Private Member Functions

void retrieveMaterial (FairGeoLoader *geoLoad)
 
TGeoVolume * generateLmdBox () const
 
TGeoVolume * generateBeamPipe () const
 
TGeoVolume * generateDetectorHalf (bool is_bottom_half) const
 
TGeoVolume * generateDetectorHalfPlane (bool is_bottom_half) const
 
TGeoVolume * generateAluminumCoolingStructure () const
 
TGeoVolume * generatePCB () const
 
TGeoVolume * generatePCBMountScrew () const
 
TGeoVolume * generatePCBCopperPlug () const
 
TGeoVolume * generatePCBBacksideElectronics () const
 
TGeoVolume * generateSensorModule () const
 
TGeoVolume * generateCVDCoolingDisc () const
 
TGeoVolume * generateSensor () const
 
TGeoVolume * generateBoxVacuum (const TGeoVolume *lmd_vol) const
 
void recursiveNodeSubtraction (std::stringstream &ss, TGeoNode *node) const
 
void makeNodesAlignable () const
 
void makeNodesAlignable (TGeoNode *node, unsigned int current_navigation_path_index) const
 

Private Attributes

boost::property_tree::ptree geometry_property_tree
 
std::vector< StringBoolPairnavigation_paths
 
TGeoManager * gGeoMan
 

Detailed Description

Definition at line 23 of file PndLmdGeometryFactory.h.

Constructor & Destructor Documentation

PndLmdGeometryFactory::PndLmdGeometryFactory ( const boost::property_tree::ptree &  geometry_property_tree_)

Definition at line 31 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and navigation_paths.

31  :
32  geometry_property_tree(geometry_property_tree_), gGeoMan(
33  (TGeoManager*) gROOT->FindObject("FAIRGeom")) {
34  auto pt_general = geometry_property_tree.get_child("general");
35  for (ptree::value_type& nav_path : pt_general.get_child("navigation_paths")) {
36  navigation_paths.push_back(
37  std::make_pair(nav_path.second.get<std::string>("name"),
38  nav_path.second.get<bool>("is_alignable")));
39  }
40 }
std::vector< StringBoolPair > navigation_paths
boost::property_tree::ptree geometry_property_tree
PndLmdGeometryFactory::~PndLmdGeometryFactory ( )
virtual

Definition at line 42 of file PndLmdGeometryFactory.cxx.

42  {
43 }

Member Function Documentation

TGeoVolume * PndLmdGeometryFactory::generateAluminumCoolingStructure ( ) const
private

Definition at line 470 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and gGeoMan.

Referenced by generateDetectorHalfPlane().

470  {
471  auto pt_cool_support = geometry_property_tree.get_child("cooling_support");
472 
473  double outer_radius(pt_cool_support.get<double>("outer_radius"));
474  double inner_radius(pt_cool_support.get<double>("inner_radius"));
475 
476  // NOTE: DO NOT use tgeotubeseg because of "bug" with root in combination with
477  // fairroot
478  //(only fixed in root 6.10 or higher but not verified)
479 
480  // construct first a tube segment
481  new TGeoTube("cool_support_tube", inner_radius, outer_radius,
482  pt_cool_support.get<double>("thickness") / 2.0);
483 
484  // cut off lower half and bit more to adapt to clash planes
485  double clash_plane_thickness(
486  geometry_property_tree.get<double>("vacuum_box.horizontal_detector_half_clash_plates.thickness"));
487 
488  // +0.1 are added to make the cutting volume slightly bigger
489  // to avoid having tiny edge left overs due to floating point
490  new TGeoBBox("cool_support_tube_cutoff", outer_radius + 0.1,
491  outer_radius / 2.0 + clash_plane_thickness / 2.0 + 0.1,
492  pt_cool_support.get<double>("thickness") + 0.1);
493 
494  TGeoTranslation* trans_tube_cut = new TGeoTranslation("trans_tube_cut", 0.0,
495  -outer_radius / 2.0 - 0.1 + 0.0001, 0.);
496  // 0.0001 make 1mu space between clash plane and alu support to avoid overlap
497  trans_tube_cut->RegisterYourself();
498 
499  // construct the support from basic shape and it's cut outs
500  TGeoCompositeShape* cool_support = new TGeoCompositeShape("cool_support",
501  "cool_support_tube-cool_support_tube_cutoff:trans_tube_cut");
502 
503  TGeoVolume* aluminum_support_volume = new TGeoVolume("vol_cool_support", cool_support,
504  gGeoMan->GetMedium("Aluminum"));
505  aluminum_support_volume->SetLineColor(kGray);
506  return aluminum_support_volume;
507 }
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateBeamPipe ( ) const
private

Definition at line 217 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, gGeoMan, and Pi.

Referenced by generateLmdGeometry().

217  {
218  TGeoVolumeAssembly* lmd_beam_pipe = new TGeoVolumeAssembly("lmd_beam_pipe");
219 
220  auto pt_vac_box = geometry_property_tree.get_child("vacuum_box");
221  auto pt_beam_pipe = geometry_property_tree.get_child("beam_pipe");
222 
223  double box_dim_z = pt_vac_box.get<double>("dimension_z");
224 
225  // upstream pipe part - outside of lmd
226  auto pt_ent_pipe = pt_beam_pipe.get_child("entrance_pipe");
227  double entrance_inner_radius(pt_ent_pipe.get<double>("inner_radius"));
228  TGeoTube* pipe_upstream = new TGeoTube("pipe_upstream", entrance_inner_radius,
229  entrance_inner_radius + pt_ent_pipe.get<double>("thickness"),
230  pt_ent_pipe.get<double>("length") / 2.0);
231  TGeoTranslation* comb_trans_pipe_upstream = new TGeoTranslation("comb_trans_pipe_upstream", 0., 0.,
232  -box_dim_z / 2.0 - pt_ent_pipe.get<double>("length") / 2.0);
233  TGeoVolume* lmd_vol_pipe_up = new TGeoVolume("lmd_vol_pipe_up", pipe_upstream,
234  gGeoMan->GetMedium("steel"));
235  lmd_vol_pipe_up->SetLineColor(11);
236  lmd_beam_pipe->AddNode(lmd_vol_pipe_up, 0, comb_trans_pipe_upstream);
237 
238  // clamp for transition cone steel and aluminum part
239  auto pt_cone_clamp = pt_beam_pipe.get_child("cone_clamp_ring");
240  double cone_clamp_outer_radius = pt_cone_clamp.get<double>("outer_radius");
241  double steel_part_thickness = pt_cone_clamp.get<double>("steel_part_thickness");
242  double alu_part_thickness = pt_cone_clamp.get<double>("aluminum_part_thickness");
243  double cone_angle = pt_beam_pipe.get_child("transition_cone").get<double>("angle_in_degrees")
244  * TMath::Pi() / 180;
245 
246  TGeoPcon* steel_cone_clamp = new TGeoPcon(0., 360., 4);
247  steel_cone_clamp->DefineSection(0, 0.0, entrance_inner_radius, cone_clamp_outer_radius);
248  steel_cone_clamp->DefineSection(1, steel_part_thickness, entrance_inner_radius,
249  cone_clamp_outer_radius);
250  steel_cone_clamp->DefineSection(2, steel_part_thickness, entrance_inner_radius,
251  entrance_inner_radius + alu_part_thickness * std::tan(cone_angle));
252  steel_cone_clamp->DefineSection(3, steel_part_thickness + alu_part_thickness, entrance_inner_radius,
253  entrance_inner_radius);
254 
255  TGeoVolume* steel_cone_clamp_vol = new TGeoVolume("steel_cone_clamp_vol", steel_cone_clamp,
256  gGeoMan->GetMedium("steel"));
257  steel_cone_clamp_vol->SetLineColor(11);
258  double cone_clamp_start_pos_z = -box_dim_z / 2.0 + pt_vac_box.get<double>("wall_thickness");
259  TGeoTranslation* lmd_trans_lmd_cone_clamp = new TGeoTranslation("lmd_trans_lmd_cone_clamp", 0., 0.,
260  cone_clamp_start_pos_z);
261  lmd_trans_lmd_cone_clamp->RegisterYourself();
262  lmd_beam_pipe->AddNode(steel_cone_clamp_vol, 0, lmd_trans_lmd_cone_clamp);
263 
264  TGeoPcon* alu_cone_clamp = new TGeoPcon(0., 360., 2);
265  alu_cone_clamp->DefineSection(0, steel_part_thickness,
266  entrance_inner_radius + alu_part_thickness * std::tan(cone_angle), cone_clamp_outer_radius);
267  alu_cone_clamp->DefineSection(1, steel_part_thickness + alu_part_thickness, entrance_inner_radius,
268  cone_clamp_outer_radius);
269 
270  TGeoVolume* alu_cone_clamp_vol = new TGeoVolume("alu_cone_clamp_vol", alu_cone_clamp,
271  gGeoMan->GetMedium("Aluminum"));
272  alu_cone_clamp_vol->SetLineColor(kGray);
273  lmd_beam_pipe->AddNode(alu_cone_clamp_vol, 0, lmd_trans_lmd_cone_clamp);
274 
275  // transition cone
276  auto pt_cone = pt_beam_pipe.get_child("transition_cone");
277  double alu_cone_thickness(pt_cone.get<double>("aluminum_thickness"));
278  double polyamide_cone_thickness(pt_cone.get<double>("polyamide_thickness"));
279  auto pt_inner_pipe = pt_beam_pipe.get_child("inner_pipe");
280  double inner_beampipe_outer_radius(pt_inner_pipe.get<double>("outer_radius"));
281  double inner_beampipe_thickness(pt_inner_pipe.get<double>("thickness"));
282  double inner_beampipe_inner_radius(inner_beampipe_outer_radius - inner_beampipe_thickness);
283  double cone_length = (entrance_inner_radius - inner_beampipe_inner_radius) / std::tan(cone_angle);
284 
285  TGeoCone* lmd_al_cone = new TGeoCone("lmd_al_cone", cone_length / 2.0, entrance_inner_radius,
286  entrance_inner_radius + alu_cone_thickness, inner_beampipe_inner_radius,
287  inner_beampipe_inner_radius + alu_cone_thickness);
288  TGeoVolume* vol_al_cone = new TGeoVolume("al_cone", lmd_al_cone, gGeoMan->GetMedium("Aluminum"));
289  vol_al_cone->SetLineColor(kGray); // 39);
290  TGeoTranslation* lmd_trans_cone = new TGeoTranslation("lmd_trans_cone", 0., 0.,
291  cone_clamp_start_pos_z + steel_part_thickness + alu_part_thickness + cone_length / 2.0);
292  lmd_trans_cone->RegisterYourself();
293  lmd_beam_pipe->AddNode(vol_al_cone, 0, lmd_trans_cone);
294 
295  TGeoCone* lmd_capton_cone = new TGeoCone("lmd_capton_cone", cone_length / 2.0,
296  entrance_inner_radius + alu_cone_thickness,
297  entrance_inner_radius + alu_cone_thickness + polyamide_cone_thickness,
298  inner_beampipe_inner_radius + alu_cone_thickness,
299  inner_beampipe_inner_radius + alu_cone_thickness + polyamide_cone_thickness);
300  TGeoVolume* vol_capton_cone = new TGeoVolume("capton_cone", lmd_capton_cone,
301  gGeoMan->GetMedium("kapton"));
302  vol_capton_cone->SetLineColor(kRed); // 39);
303  lmd_beam_pipe->AddNode(vol_capton_cone, 0, lmd_trans_cone);
304 
305  // inner beam pipe part
306  double inner_beampipe_length(pt_inner_pipe.get<double>("length"));
307  double inner_beampipe_cone_foil_attach_segement_length(
308  pt_inner_pipe.get<double>("length_cone_foil_attach_segment"));
309  double outer_radius_cone_foil_glue_segment(
310  inner_beampipe_outer_radius
311  + std::tan(cone_angle) * inner_beampipe_cone_foil_attach_segement_length);
312 
313  TGeoPcon* lmd_inner_pipe = new TGeoPcon(0.0, 360.0, 3);
314  lmd_inner_pipe->DefineSection(0, 0.0, outer_radius_cone_foil_glue_segment - inner_beampipe_thickness,
315  outer_radius_cone_foil_glue_segment);
316  lmd_inner_pipe->DefineSection(1, inner_beampipe_cone_foil_attach_segement_length,
317  inner_beampipe_inner_radius, inner_beampipe_outer_radius);
318  lmd_inner_pipe->DefineSection(2,
319  inner_beampipe_cone_foil_attach_segement_length + inner_beampipe_length,
320  inner_beampipe_inner_radius, inner_beampipe_outer_radius);
321 
322  TGeoVolume* vol_inner_pipe = new TGeoVolume("vol_inner_pipe", lmd_inner_pipe,
323  gGeoMan->GetMedium("steel"));
324  vol_inner_pipe->SetLineColor(11); // 39);
325  double inner_pipe_start_position_z(
326  cone_clamp_start_pos_z + steel_part_thickness + alu_part_thickness + cone_length
327  - inner_beampipe_cone_foil_attach_segement_length);
328  TGeoTranslation* lmd_trans_inner_pipe = new TGeoTranslation("lmd_trans_inner_pipe", 0., 0.,
329  inner_pipe_start_position_z);
330  lmd_trans_inner_pipe->RegisterYourself();
331  lmd_beam_pipe->AddNode(vol_inner_pipe, 0, lmd_trans_inner_pipe);
332 
333  // bellow
334  auto pt_exit_pipe = pt_beam_pipe.get_child("exit_pipe");
335  double inner_exit_radius = pt_exit_pipe.get<double>("inner_radius");
336 
337  auto pt_bellow = pt_beam_pipe.get_child("bellow");
338  double flange_to_inner_pipe_outer_radius(
339  inner_beampipe_inner_radius
340  + pt_bellow.get<double>("flange_to_inner_beampipe.outer_radius_increase"));
341  TGeoPcon* beampipe_bellow = new TGeoPcon(0., 360., 6);
342  double tempzpos(
343  inner_pipe_start_position_z + inner_beampipe_cone_foil_attach_segement_length
344  + inner_beampipe_length);
345  beampipe_bellow->DefineSection(0, tempzpos, inner_beampipe_inner_radius,
346  flange_to_inner_pipe_outer_radius);
347  tempzpos += pt_bellow.get<double>("flange_to_inner_beampipe.thickness");
348  beampipe_bellow->DefineSection(1, tempzpos, inner_beampipe_inner_radius,
349  flange_to_inner_pipe_outer_radius);
350  tempzpos += pt_bellow.get<double>("flange_to_inner_beampipe.outer_radius_increase")
351  / std::tan(pt_bellow.get<double>("inner_angle_in_degrees") / 180 * TMath::Pi());
352  beampipe_bellow->DefineSection(2, tempzpos, inner_exit_radius,
353  inner_exit_radius + pt_bellow.get<double>("thickness"));
354  tempzpos += (box_dim_z / 2.0 - pt_vac_box.get<double>("wall_thickness") - tempzpos
355  - pt_bellow.get<double>("flange_to_box.thickness"));
356  beampipe_bellow->DefineSection(3, tempzpos, inner_exit_radius,
357  inner_exit_radius + pt_bellow.get<double>("thickness"));
358  beampipe_bellow->DefineSection(4, tempzpos, inner_exit_radius,
359  inner_exit_radius + pt_bellow.get<double>("thickness")
360  + pt_bellow.get<double>("flange_to_box.outer_radius_increase"));
361  tempzpos += pt_bellow.get<double>("flange_to_box.thickness");
362  beampipe_bellow->DefineSection(5, tempzpos, inner_exit_radius,
363  inner_exit_radius + pt_bellow.get<double>("thickness")
364  + pt_bellow.get<double>("flange_to_box.outer_radius_increase"));
365 
366  TGeoVolume* vol_beampipe_bellow = new TGeoVolume("vol_beampipe_bellow", beampipe_bellow,
367  gGeoMan->GetMedium("steel"));
368  vol_beampipe_bellow->SetLineColor(11); // 39);
369  lmd_beam_pipe->AddNode(vol_beampipe_bellow, 0);
370 
371  // downstream pipe part - outside of lmd
372  double outer_exit_radius = inner_exit_radius + pt_exit_pipe.get<double>("thickness");
373  double tube_length = pt_exit_pipe.get<double>("length");
374  double flange_outer_radius = pt_exit_pipe.get<double>("flange_outer_radius");
375  double flange_thickness = pt_exit_pipe.get<double>("flange_thickness");
376 
377  TGeoPcon* shape_pipe_box_do = new TGeoPcon(0., 360., 4);
378  shape_pipe_box_do->DefineSection(0, box_dim_z / 2.0, inner_exit_radius, outer_exit_radius);
379  shape_pipe_box_do->DefineSection(1, box_dim_z / 2.0 + tube_length - flange_thickness,
380  inner_exit_radius, outer_exit_radius);
381  shape_pipe_box_do->DefineSection(2, box_dim_z / 2.0 + tube_length - flange_thickness,
382  inner_exit_radius, flange_outer_radius);
383  shape_pipe_box_do->DefineSection(3, box_dim_z / 2.0 + tube_length, inner_exit_radius,
384  flange_outer_radius);
385 
386  TGeoVolume* vlum_pipe_box_do = new TGeoVolume("vlum_pipe_box_do", shape_pipe_box_do,
387  gGeoMan->GetMedium("steel"));
388  vlum_pipe_box_do->SetLineColor(11); // 39);
389  lmd_beam_pipe->AddNode(vlum_pipe_box_do, 0);
390 
391  return lmd_beam_pipe;
392 }
Double_t Pi
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateBoxVacuum ( const TGeoVolume *  lmd_vol) const
private

Definition at line 899 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, gGeoMan, i, and recursiveNodeSubtraction().

899  {
900  auto pt_vac_box = geometry_property_tree.get_child("vacuum_box");
901  // general remark: watch out! TGeoShape values are often given has half sizes!
902  double box_dim_x(pt_vac_box.get<double>("dimension_x"));
903  double box_dim_y(pt_vac_box.get<double>("dimension_y"));
904  double box_dim_z(pt_vac_box.get<double>("dimension_z"));
905  double box_thickness(pt_vac_box.get<double>("wall_thickness"));
906 
907  new TGeoBBox("lmd_box_vac", box_dim_x / 2.0 - box_thickness, box_dim_y / 2.0 - box_thickness,
908  box_dim_z / 2.0 - box_thickness);
909 
910  std::stringstream ss;
911  ss << "lmd_box_vac";
912  // recursively loop over all nodes in the assembly and subtract all these
913  // nodes
914  for (int i = 0; i < lmd_vol->GetNdaughters(); ++i) {
915  recursiveNodeSubtraction(ss, lmd_vol->GetNode(i));
916  }
917 
918  TGeoCompositeShape* shape_box_vac = new TGeoCompositeShape("shape_box_vac", ss.str().c_str());
919 
920  std::cout << ss.str() << std::endl;
921  TGeoVolume* lmd_vol_vac = new TGeoVolume("lmd_vol_vac", shape_box_vac, gGeoMan->GetMedium("vacuum7"));
922  lmd_vol_vac->SetLineColor(kCyan);
923  lmd_vol_vac->SetTransparency(50);
924  return lmd_vol_vac;
925 }
void recursiveNodeSubtraction(std::stringstream &ss, TGeoNode *node) const
Int_t i
Definition: run_full.C:25
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateCVDCoolingDisc ( ) const
private

Definition at line 777 of file PndLmdGeometryFactory.cxx.

References cos(), geometry_property_tree, gGeoMan, Pi, and sin().

Referenced by generateSensorModule().

777  {
778  auto pt_cool_support = geometry_property_tree.get_child("cooling_support");
779  double alu_support_inner_radius(pt_cool_support.get<double>("inner_radius"));
780  auto pt_cvd_disc = pt_cool_support.get_child("cvd_disc");
781  unsigned int num_modules_per_half_plane(
782  geometry_property_tree.get<double>("general.modules_per_half_plane"));
783  double gap_between_disc_and_support_structure(0.0);
784 
785  // this code cannot be used at the moment, because of "bug" in root
786  // (version 6.10 or higher should have it fixed, but I could not verify this)
787  // the "bug" is due to fairroot not importing geometries with the tgeomanager,
788  // and the import function performs trigonometric calc (in case of
789  // tgeotubeseg)
790 
791  /*TGeoTubeSeg* cvd_disc = new TGeoTubeSeg("cvd_disc",
792  pt_cvd_disc.get<double>("inner_radius"),
793  alu_support_inner_radius - gap_between_disc_and_support_structure,
794  pt_cvd_disc.get<double>("thickness") / 2.0, 0.0,
795  180.0 / num_modules_per_half_plane);*/
796 
797  new TGeoTube("cvd_disc_tube", pt_cvd_disc.get<double>("inner_radius"),
798  alu_support_inner_radius - gap_between_disc_and_support_structure,
799  pt_cvd_disc.get<double>("thickness") / 2.0);
800 
801  new TGeoBBox("cvd_disc_cut", alu_support_inner_radius + 0.1, alu_support_inner_radius / 2.0 + 0.1,
802  pt_cvd_disc.get<double>("thickness") / 2.0 + 0.1);
803  TGeoTranslation* trans_bottom = new TGeoTranslation("trans_cvd_cut_bottom", 0.0,
804  -(alu_support_inner_radius / 2.0 + 0.1), 0.0);
805  trans_bottom->RegisterYourself();
806 
807  TGeoRotation* rot_cvd_cut_top = new TGeoRotation("rot_cvd_cut_top", 0.0, 0.0,
808  180.0 / num_modules_per_half_plane);
809  TGeoCombiTrans* trans_top = new TGeoCombiTrans("transrot_cvd_cut_top",
810  -std::sin(TMath::Pi() / num_modules_per_half_plane) * (alu_support_inner_radius / 2.0 + 0.1),
811  std::cos(TMath::Pi() / num_modules_per_half_plane) * (alu_support_inner_radius / 2.0 + 0.1), 0.0,
812  rot_cvd_cut_top);
813  trans_top->RegisterYourself();
814 
815  TGeoCompositeShape* cvd_disc = new TGeoCompositeShape("cvd_disc",
816  "cvd_disc_tube-cvd_disc_cut:trans_cvd_cut_bottom-"
817  "cvd_disc_cut:transrot_cvd_cut_top");
818 
819  TGeoVolume* cvd_disc_volume = new TGeoVolume("lmd_vol_cvd_disc", cvd_disc,
820  gGeoMan->GetMedium("HYPdiamond"));
821  cvd_disc_volume->SetLineColor(9);
822  return cvd_disc_volume;
823 }
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
Double_t Pi
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateDetectorHalf ( bool  is_bottom_half) const
private

Definition at line 394 of file PndLmdGeometryFactory.cxx.

References generateDetectorHalfPlane(), geometry_property_tree, i, and navigation_paths.

Referenced by generateLmdGeometry().

394  {
395  std::vector<double> plane_z_positions;
396  auto pt_general = geometry_property_tree.get_child("general");
397  for (ptree::value_type& plane_z : pt_general.get_child("plane_z_positions")) {
398  plane_z_positions.push_back(plane_z.second.get_value<double>());
399  }
400 
401  TGeoVolumeAssembly* lmd_vol_half = new TGeoVolumeAssembly(navigation_paths[1].first.c_str());
402 
403  // create a detector plane volume
404  TGeoVolume* lmd_vol_plane = generateDetectorHalfPlane(is_bottom_half);
405  // now loop over number of planes and make copies of the plane
406  // and align them correctly
407 
408  // determine shift of planes with respect to box center
409  double box_center_position_z(
410  pt_general.get<double>("upstream_beampipe_connection_z_position")
411  + geometry_property_tree.get<double>("vacuum_box.dimension_z") / 2.0
412  + geometry_property_tree.get<double>("beam_pipe.entrance_pipe.length"));
413  double z_shift(
414  geometry_property_tree.get<double>("general.first_plane_position_z") - box_center_position_z);
415  for (unsigned int i = 0; i < plane_z_positions.size(); ++i) {
416  TGeoTranslation* trans_module = new TGeoTranslation(0.0, 0.0, plane_z_positions[i] + z_shift);
417  lmd_vol_half->AddNode(lmd_vol_plane, i, trans_module);
418  }
419  return lmd_vol_half;
420 }
Int_t i
Definition: run_full.C:25
std::vector< StringBoolPair > navigation_paths
boost::property_tree::ptree geometry_property_tree
TGeoVolume * generateDetectorHalfPlane(bool is_bottom_half) const
TGeoVolume * PndLmdGeometryFactory::generateDetectorHalfPlane ( bool  is_bottom_half) const
private

Definition at line 422 of file PndLmdGeometryFactory.cxx.

References generateAluminumCoolingStructure(), generatePCB(), generateSensorModule(), geometry_property_tree, i, and navigation_paths.

Referenced by generateDetectorHalf().

422  {
423  TGeoVolumeAssembly* lmd_vol_plane = new TGeoVolumeAssembly(navigation_paths[2].first.c_str());
424 
425  TGeoVolume* alu_cooling_half_ring = generateAluminumCoolingStructure();
426  TGeoVolume* pcb_board_half_ring = generatePCB();
427  TGeoRotation* rot_alu_ring = new TGeoRotation();
428  TGeoRotation* rot_back_pcb = new TGeoRotation();
429  rot_back_pcb->RotateY(180.0);
430  if (is_bottom_half) {
431  rot_alu_ring->RotateZ(180.0);
432  rot_back_pcb->RotateZ(180.0);
433  }
434  TGeoCombiTrans* trans_pcb_half_ring = new TGeoCombiTrans("trans_pcb_half_ring", 0.0, 0.0,
435  -geometry_property_tree.get<double>("electronics.distance_between_pcb_and_cooling_support")
436  - 0.5
437  * (geometry_property_tree.get<double>("cooling_support.thickness")
438  + geometry_property_tree.get<double>("electronics.pcb_board.thickness_copper")
439  + geometry_property_tree.get<double>("electronics.pcb_board.thickness_glasfiber")),
440  rot_alu_ring);
441  TGeoCombiTrans* trans_pcb_half_ring_back = new TGeoCombiTrans("trans_pcb_half_ring", 0.0, 0.0,
442  geometry_property_tree.get<double>("electronics.distance_between_pcb_and_cooling_support")
443  + 0.5 * geometry_property_tree.get<double>("cooling_support.thickness"), rot_back_pcb);
444  lmd_vol_plane->AddNode(alu_cooling_half_ring, 0, rot_alu_ring);
445  lmd_vol_plane->AddNode(pcb_board_half_ring, 0, trans_pcb_half_ring);
446  lmd_vol_plane->AddNode(pcb_board_half_ring, 1, trans_pcb_half_ring_back);
447 
448  TGeoVolume* detector_module = generateSensorModule();
449 
450  unsigned int num_modules_per_plane(
451  geometry_property_tree.get<double>("general.modules_per_half_plane"));
452  double relative_module_shift_z(
453  geometry_property_tree.get<double>("general.relative_module_distance_z") / 2.0);
454  unsigned int index_offset(0);
455  if (is_bottom_half) {
456  index_offset += num_modules_per_plane;
457  relative_module_shift_z *= -1; // lower half modules need relative z shift to top half neighbors
458  }
459  for (unsigned int i = 0; i < num_modules_per_plane; ++i) {
460  TGeoRotation* rot_module = new TGeoRotation();
461  rot_module->RotateZ(180.0 / num_modules_per_plane * (i + index_offset));
462  relative_module_shift_z *= -1;
463  TGeoCombiTrans* rottrans_module = new TGeoCombiTrans(0.0, 0.0, relative_module_shift_z, rot_module);
464  lmd_vol_plane->AddNode(detector_module, i, rottrans_module);
465  }
466 
467  return lmd_vol_plane;
468 }
Int_t i
Definition: run_full.C:25
TGeoVolume * generateAluminumCoolingStructure() const
TGeoVolume * generateSensorModule() const
std::vector< StringBoolPair > navigation_paths
boost::property_tree::ptree geometry_property_tree
TGeoVolume * generatePCB() const
TGeoVolume * PndLmdGeometryFactory::generateLmdBox ( ) const
private

Definition at line 139 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and gGeoMan.

Referenced by generateLmdGeometry().

139  {
140  auto pt_general = geometry_property_tree.get_child("general");
141  auto pt_vac_box = geometry_property_tree.get_child("vacuum_box");
142 
143  // general remark: watch out! TGeoShape values are often given has half sizes!
144  double box_dim_x(pt_vac_box.get<double>("dimension_x"));
145  double box_dim_y(pt_vac_box.get<double>("dimension_y"));
146  double box_dim_z(pt_vac_box.get<double>("dimension_z"));
147  double box_thickness(pt_vac_box.get<double>("wall_thickness"));
148 
149  // the lmd box
150  new TGeoBBox("lmd_box_outer", box_dim_x / 2.0, box_dim_y / 2.0, box_dim_z / 2.0);
151  new TGeoBBox("lmd_box_inner", box_dim_x / 2.0 - box_thickness, box_dim_y / 2.0 - box_thickness,
152  box_dim_z / 2.0 - box_thickness);
153 
154  // the two beampipe holes
155  new TGeoTube("box_hole_upstream", 0.0,
156  geometry_property_tree.get_child("beam_pipe.entrance_pipe").get<double>("inner_radius"),
157  box_thickness / 2.0 + 0.1); // 0.1 safety margin
158  // move the cut pipe upstream
159  TGeoTranslation* comb_trans_cut_pipe_upstream = new TGeoTranslation("comb_trans_cut_pipe_upstream", 0.,
160  0., -box_dim_z / 2.0 + box_thickness / 2.0);
161  comb_trans_cut_pipe_upstream->RegisterYourself();
162 
163  new TGeoTube("box_hole_downstream", 0.0,
164  geometry_property_tree.get_child("beam_pipe.exit_pipe").get<double>("inner_radius"),
165  box_thickness / 2.0 + 0.1);
166  // move the cut pipe downstream
167  TGeoTranslation* comb_trans_cut_pipe_downstream = new TGeoTranslation("comb_trans_cut_pipe_downstream",
168  0., 0., +box_dim_z / 2.0 - box_thickness / 2.0);
169  comb_trans_cut_pipe_downstream->RegisterYourself();
170 
171  // the z-plane reinforcement rib
172  double rib_thickness = pt_vac_box.get_child("zplane_reinforcement_rib").get<double>("thickness");
173  new TGeoBBox("lmd_box_rib", box_dim_x / 2.0 - box_thickness, box_dim_y / 2.0 - box_thickness,
174  rib_thickness / 2.);
175  new TGeoTube("rib_hole", 0.0,
176  geometry_property_tree.get_child("beam_pipe.entrance_pipe").get<double>("inner_radius"),
177  rib_thickness / 2.0 + 0.1);
178  // move rib upstream
179  double rib_inner_distance_to_front_plate =
180  pt_vac_box.get_child("zplane_reinforcement_rib").get<double>("inner_distance_to_box_front_plate");
181  TGeoTranslation* comb_trans_rib = new TGeoTranslation("comb_trans_rib", 0., 0.,
182  -box_dim_z / 2.0 + box_thickness + rib_inner_distance_to_front_plate + rib_thickness / 2.0);
183  comb_trans_rib->RegisterYourself();
184 
185  // the horizontal clash plates for the detector halves
186  auto pt_clash_plates = geometry_property_tree.get_child(
187  "vacuum_box.horizontal_detector_half_clash_plates");
188  double clash_plate_dim_x = pt_clash_plates.get<double>("width");
189  double clash_plate_dim_y = pt_clash_plates.get<double>("thickness");
190  double clash_plate_dim_z = box_dim_z - rib_inner_distance_to_front_plate - rib_thickness
191  - box_thickness;
192 
193  double origin_left[3] =
194  { -box_dim_x / 2.0 + clash_plate_dim_x / 2.0 + box_thickness, 0., -box_dim_z / 2.0 + box_thickness
195  + rib_inner_distance_to_front_plate + rib_thickness + clash_plate_dim_z / 2.0 };
196  new TGeoBBox("lmd_box_clash_plate_left", clash_plate_dim_x / 2.0, clash_plate_dim_y / 2.0,
197  clash_plate_dim_z / 2.0, origin_left);
198  double origin_right[3] =
199  { +box_dim_x / 2.0 - clash_plate_dim_x / 2.0 - box_thickness, 0., -box_dim_z / 2.0 + box_thickness
200  + rib_inner_distance_to_front_plate + rib_thickness + clash_plate_dim_z / 2.0 };
201  new TGeoBBox("lmd_box_clash_plate_right", clash_plate_dim_x / 2.0, clash_plate_dim_y / 2.0,
202  clash_plate_dim_z / 2.0, origin_right);
203 
204  // compose all the parts into one luminosity vacuum box
205  TGeoCompositeShape* shape_lmd_box = new TGeoCompositeShape("shape_lmd_box",
206  "(lmd_box_outer-lmd_box_inner + ((lmd_box_rib-rib_hole):comb_trans_rib))"
207  "-box_hole_upstream:comb_trans_cut_pipe_upstream"
208  "-box_hole_downstream:comb_trans_cut_pipe_downstream"
209  "+lmd_box_clash_plate_left+lmd_box_clash_plate_right");
210 
211  TGeoVolume* lmd_vol_box = new TGeoVolume("lmd_vol_box", shape_lmd_box, gGeoMan->GetMedium("steel"));
212  lmd_vol_box->SetLineColor(11);
213 
214  return lmd_vol_box;
215 }
boost::property_tree::ptree geometry_property_tree
TGeoVolumeAssembly * PndLmdGeometryFactory::generateLmdGeometry ( ) const

Definition at line 81 of file PndLmdGeometryFactory.cxx.

References cos(), generateBeamPipe(), generateDetectorHalf(), generateLmdBox(), geometry_property_tree, gGeoMan, makeNodesAlignable(), navigation_paths, sin(), and top.

Referenced by createLmdGeometry().

81  {
82  auto pt_general = geometry_property_tree.get_child("general");
83 
84  double pipe_bend_segment_phi(pt_general.get<double>("pipe_bend_segment_phi"));
85 
86  TGeoRotation* lmd_rot = new TGeoRotation("lmd_rot");
87  lmd_rot->RotateX(0.0);
88  lmd_rot->RotateY(pipe_bend_segment_phi / 3.14 * 180.);
89  lmd_rot->RotateZ(0.0);
90 
91  double box_center_position_z(
92  pt_general.get<double>("upstream_beampipe_connection_z_position")
93  + geometry_property_tree.get<double>("vacuum_box.dimension_z") / 2.0
94  + geometry_property_tree.get<double>("beam_pipe.entrance_pipe.length"));
95 
96  // calculate shift in x from dipole
97  double pipe_bend_start_position_z(pt_general.get<double>("pipe_bend_start_position_z"));
98  double pipe_bend_radius(pt_general.get<double>("pipe_bend_radius"));
99 
100  double dx_from_bending(pipe_bend_radius * (1.0 - std::cos(pipe_bend_segment_phi)));
101  double dx_from_displacement_afterwards(
102  (box_center_position_z - pipe_bend_start_position_z
103  - pipe_bend_radius * std::sin(pipe_bend_segment_phi)) * std::tan(pipe_bend_segment_phi));
104  double shift_x_from_dipole(dx_from_bending + dx_from_displacement_afterwards);
105  TGeoCombiTrans* lmd_frame_transformation = new TGeoCombiTrans("lmd_translation", shift_x_from_dipole,
106  0., box_center_position_z, lmd_rot);
107 
108  // upstream_beampipe_connection_z_position
109 
110  TGeoVolumeAssembly* top = new TGeoVolumeAssembly("lmd_top");
111  gGeoMan->SetTopVolume(top);
112 
113  // create the reference system of the lmd
114  TGeoVolumeAssembly* lmd_vol = new TGeoVolumeAssembly(navigation_paths[0].first.c_str());
115 
116  // generate vacuum box
117  lmd_vol->AddNode(generateLmdBox(), 0);
118  // generate beam pipe segment
119  lmd_vol->AddNode(generateBeamPipe(), 0);
120 
121  // add half detectors
122  lmd_vol->AddNode(generateDetectorHalf(false), 0);
123  lmd_vol->AddNode(generateDetectorHalf(true), 1);
124 
125  // create lmd box vacuum
126  // lmd_vol->AddNode(generateBoxVacuum(lmd_vol), 0);
127 
128  // place correctly in mother volume
129  top->AddNode(lmd_vol, 0, lmd_frame_transformation);
130 
131  gGeoMan->CloseGeometry();
132 
134  std::cout << "Number of alignable volumes: " << gGeoMan->GetNAlignable() << std::endl;
135 
136  return top;
137 }
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
TGeoVolume * generateLmdBox() const
TGeoVolume * generateBeamPipe() const
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
TGeoVolume * top
TGeoVolume * generateDetectorHalf(bool is_bottom_half) const
std::vector< StringBoolPair > navigation_paths
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generatePCB ( ) const
private

Definition at line 509 of file PndLmdGeometryFactory.cxx.

References angle, cos(), generatePCBBacksideElectronics(), generatePCBCopperPlug(), generatePCBMountScrew(), geometry_property_tree, gGeoMan, i, Pi, rot, sin(), and trafo.

Referenced by generateDetectorHalfPlane().

509  {
510  TGeoVolumeAssembly* pcb_volume = new TGeoVolumeAssembly("pcb");
511  auto pt_electronics = geometry_property_tree.get_child("electronics");
512 
513  double outer_radius(pt_electronics.get<double>("pcb_board.outer_radius"));
514  double inner_radius(pt_electronics.get<double>("pcb_board.inner_radius"));
515  double pcb_copper_thickness(pt_electronics.get<double>("pcb_board.thickness_copper"));
516  double pcb_glasfiber_thickness(pt_electronics.get<double>("pcb_board.thickness_glasfiber"));
517 
518  // NOTE: DO NOT use tgeotubeseg because of "bug" with root in combination with
519  // fairroot
520  //(only fixed in root 6.10 or higher but not verified)
521 
522  // construct first a tube
523  new TGeoTube("pcb_board_tube", inner_radius, outer_radius, pcb_glasfiber_thickness / 2.0);
524  new TGeoTube("pcb_copper_tube", inner_radius, outer_radius, pcb_copper_thickness / 2.0);
525 
526  // cut off lower half and bit more to adapt to clash planes
527  double clash_plane_thickness(
528  geometry_property_tree.get<double>("vacuum_box.horizontal_detector_half_clash_plates.thickness"));
529  // we cut a little more than for the cooling support
530  double additional_bottom_cutoff(pt_electronics.get<double>("pcb_board.bottom_cutoff"));
531  // +0.1 are added to make the cutting volume slightly bigger
532  // to avoid having tiny edge left overs due to floating point
533  new TGeoBBox("pcb_full_cutoff", outer_radius + 0.1,
534  outer_radius / 2.0 + clash_plane_thickness / 2.0 + additional_bottom_cutoff + 0.1,
535  pcb_glasfiber_thickness + pcb_copper_thickness + 0.1);
536 
537  TGeoTranslation* trans_pcb_tube_cut = new TGeoTranslation("trans_pcb_tube_cut", 0.0,
538  -outer_radius / 2.0 - 0.1 + 0.0001, 0.);
539  // 0.0001 make 1mu space between clash plane and alu support to avoid overlap
540  trans_pcb_tube_cut->RegisterYourself();
541 
542  // volume to cut out the holes for the steel mounting screws
543  //new TGeoTube("pcb_steel_mount_screw_cutout", 0.0,
544  // pt_electronics.get<double>("steel_mount_screws.diameter") / 2.0,
545  // (pcb_glasfiber_thickness + pcb_copper_thickness) / 2.0);
546  TGeoVolume *steel_mount_screw = generatePCBMountScrew();
547 
548  std::stringstream ss;
549  double start_angle(pt_electronics.get<double>("steel_mount_screws.angle_first_screw"));
550  double delta_angle(pt_electronics.get<double>("steel_mount_screws.angle_between_screws"));
551  double hole_position_radius(
552  outer_radius - pt_electronics.get<double>("steel_mount_screws.distance_to_outer_support_edge"));
553  for (unsigned int i = 0; i < pt_electronics.get<double>("steel_mount_screws.number_of_screws"); ++i) {
554  std::string transname("screw_hole_trans_" + i);
555  double angle(start_angle + delta_angle * i);
556  TGeoTranslation* screw_hole_trans = new TGeoTranslation(transname.c_str(),
557  hole_position_radius * std::cos(angle / 180 * TMath::Pi()),
558  hole_position_radius * std::sin(angle / 180 * TMath::Pi()),
559  -0.5
560  * (pt_electronics.get<double>("distance_between_pcb_and_cooling_support")
561  + pt_electronics.get<double>("steel_mount_screws.screw_head_size"))
562  + pt_electronics.get<double>("distance_between_pcb_and_cooling_support"));
563  // subtract the mounting screw from the pcb board
564  screw_hole_trans->RegisterYourself();
565  ss << "-" << steel_mount_screw->GetShape()->GetName() << ":" << transname;
566  // add the mounting screw
567  pcb_volume->AddNode(steel_mount_screw, i, screw_hole_trans);
568  }
569 
570  // construct the support from basic shape and it's cut outs
571  TGeoCompositeShape * pcb_shape = new TGeoCompositeShape("pcb_shape",
572  (std::string("pcb_board_tube-pcb_full_cutoff:trans_pcb_tube_cut") + ss.str()).c_str());
573  // construct the support from basic shape and it's cut outs
574  TGeoCompositeShape* pcb_copper_shape = new TGeoCompositeShape("pcb_copper_shape",
575  (std::string("pcb_copper_tube-pcb_full_cutoff:trans_pcb_tube_cut") + ss.str()).c_str());
576 
577  TGeoTranslation* trans_pcb_copper = new TGeoTranslation("trans_pcb_copper", 0.0, 0.0,
578  -0.5 * (pcb_copper_thickness + pcb_glasfiber_thickness + 0.0001));
579  // make half mu space between to avoid overlap
580  trans_pcb_copper->RegisterYourself();
581 
582  TGeoVolume* pcb_glasfiber_volume = new TGeoVolume("vol_pcb_glassfiber", pcb_shape,
583  gGeoMan->GetMedium("GlassFiber"));
584  pcb_glasfiber_volume->SetLineColor(30);
585  TGeoVolume* pcb_copper_volume = new TGeoVolume("vol_pcb_copper", pcb_copper_shape,
586  gGeoMan->GetMedium("copper"));
587  pcb_copper_volume->SetLineColor(kOrange + 1);
588  pcb_volume->AddNode(pcb_glasfiber_volume, 0);
589  pcb_volume->AddNode(pcb_copper_volume, 0, trans_pcb_copper);
590 
591  // add copper plug on the front side, one for each module
592  unsigned int modules_per_half_plane(
593  geometry_property_tree.get<double>("general.modules_per_half_plane"));
594  TGeoVolume* copper_plug = generatePCBCopperPlug();
595  double middle_radius(0.5 * (inner_radius + outer_radius));
596  double ang_segment_module(180.0 / modules_per_half_plane);
597  for (unsigned int i = 0; i < modules_per_half_plane; ++i) {
598  double angle((0.5 + i) * ang_segment_module);
599  TGeoRotation *rot = new TGeoRotation();
600  rot->RotateZ(angle);
601  TGeoCombiTrans *trafo = new TGeoCombiTrans(middle_radius * std::cos(angle / 180.0 * TMath::Pi()),
602  middle_radius * std::sin(angle / 180.0 * TMath::Pi()),
603  -pcb_copper_thickness
604  - 0.5
605  * (pcb_glasfiber_thickness + pt_electronics.get<double>("copper_plugs.thickness")
606  + 0.0001), rot);
607 
608  pcb_volume->AddNode(copper_plug, i, trafo);
609  }
610 
611  // add electronic chips on back side
612  TGeoVolume* backside_electronic_chip = generatePCBBacksideElectronics();
613  unsigned int segments(pt_electronics.get<double>("backside_electronics.segments"));
614  unsigned int chips_per_segment(pt_electronics.get<double>("backside_electronics.chips_per_segment"));
615  double be_start_angle(pt_electronics.get<double>("backside_electronics.angle_first_segment"));
616  double ang_segment(
617  (pt_electronics.get<double>("backside_electronics.angle_last_segment") - be_start_angle)
618  / (segments-1));
619  for (unsigned int i = 0; i < segments; ++i) {
620  for (unsigned int j = 0; j < chips_per_segment; ++j) {
621  double angle(be_start_angle + i * ang_segment);
622  TGeoRotation *rot = new TGeoRotation();
623  rot->RotateZ(angle);
624  double radius_delta(
625  (-0.5 * (chips_per_segment + 1) + j)
626  * (pt_electronics.get<double>("backside_electronics.dimension_x") + 0.2));
627  TGeoCombiTrans *trafo = new TGeoCombiTrans(
628  (middle_radius + radius_delta) * std::cos(angle / 180.0 * TMath::Pi()),
629  (middle_radius + radius_delta) * std::sin(angle / 180.0 * TMath::Pi()),
630  0.5
631  * (pcb_glasfiber_thickness + pt_electronics.get<double>("backside_electronics.thickness")
632  + 0.0001), rot);
633 
634  pcb_volume->AddNode(backside_electronic_chip, i * chips_per_segment + j, trafo);
635  }
636  }
637 
638  return pcb_volume;
639 }
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
Int_t i
Definition: run_full.C:25
TGeoCombiTrans * trafo
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
TGeoVolume * generatePCBBacksideElectronics() const
TGeoVolume * generatePCBMountScrew() const
TGeoRotation rot
TGeoVolume * generatePCBCopperPlug() const
Double_t angle
Double_t Pi
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generatePCBBacksideElectronics ( ) const
private

Definition at line 667 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and gGeoMan.

Referenced by generatePCB().

667  {
668  auto pt_be = geometry_property_tree.get_child("electronics.backside_electronics");
669 
670  TGeoBBox *pcb_backside_electronic = new TGeoBBox("pcb_backside_electronic",
671  pt_be.get<double>("dimension_x") / 2.0, pt_be.get<double>("dimension_y") / 2.0,
672  pt_be.get<double>("thickness") / 2.0);
673 
674  TGeoVolume* pcb_backside_electronic_volume = new TGeoVolume(
675  pt_be.get<std::string>("volume_name").c_str(), pcb_backside_electronic,
676  gGeoMan->GetMedium("silicon"));
677  pcb_backside_electronic_volume->SetLineColor(kYellow);
678  return pcb_backside_electronic_volume;
679 }
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generatePCBCopperPlug ( ) const
private

Definition at line 654 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and gGeoMan.

Referenced by generatePCB().

654  {
655  auto pt_copperplugs = geometry_property_tree.get_child("electronics.copper_plugs");
656 
657  TGeoBBox *pcb_copper_plug = new TGeoBBox("pcb_copper_plug",
658  pt_copperplugs.get<double>("dimension_x") / 2.0, pt_copperplugs.get<double>("dimension_y") / 2.0,
659  pt_copperplugs.get<double>("thickness") / 2.0);
660 
661  TGeoVolume* pcb_copper_plug_volume = new TGeoVolume("vol_pcb_copper_plug", pcb_copper_plug,
662  gGeoMan->GetMedium("copper"));
663  pcb_copper_plug_volume->SetLineColor(kOrange + 2);
664  return pcb_copper_plug_volume;
665 }
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generatePCBMountScrew ( ) const
private

Definition at line 641 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, and gGeoMan.

Referenced by generatePCB().

641  {
642  auto pt_mountscrews = geometry_property_tree.get_child("electronics.steel_mount_screws");
643  // volume to cut out the holes for the steel mounting screws
644  TGeoTube *steel_mount_screw = new TGeoTube("pcb_steel_mount_screw", 0.0,
645  pt_mountscrews.get<double>("diameter") / 2.0,
646  (geometry_property_tree.get<double>("electronics.distance_between_pcb_and_cooling_support")
647  + pt_mountscrews.get<double>("screw_head_size")) / 2.0);
648  TGeoVolume* steel_mount_screw_volume = new TGeoVolume("vol_steel_mount_screw", steel_mount_screw,
649  gGeoMan->GetMedium("steel"));
650  steel_mount_screw_volume->SetLineColor(11);
651  return steel_mount_screw_volume;
652 }
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateSensor ( ) const
private

Definition at line 825 of file PndLmdGeometryFactory.cxx.

References geometry_property_tree, gGeoMan, navigation_paths, and thickness.

Referenced by generateSensorModule().

825  {
826  TGeoVolumeAssembly* lmd_vol_sensor = new TGeoVolumeAssembly(navigation_paths[4].first.c_str());
827 
828  auto pt_sensors = geometry_property_tree.get_child("sensors");
829  auto pt_active_part = pt_sensors.get_child("active_part");
830 
831  double sensor_dim_x(pt_sensors.get<double>("dimension_x"));
832  double sensor_dim_y(pt_sensors.get<double>("dimension_x"));
833  double thickness(pt_sensors.get<double>("thickness"));
834 
835  double active_part_dim_x(pt_active_part.get<double>("dimension_x"));
836  double active_part_dim_y(pt_active_part.get<double>("dimension_y"));
837  double active_part_offset_x(pt_active_part.get<double>("offset_x"));
838  double active_part_offset_y(pt_active_part.get<double>("offset_y"));
839 
840  new TGeoBBox("sensor_full_centered", sensor_dim_x / 2.0, sensor_dim_y / 2.0, thickness / 2.0);
841 
842  TGeoBBox* sensor_active_centered = new TGeoBBox("sensor_active_centered", active_part_dim_x / 2.0,
843  active_part_dim_y / 2.0, thickness / 2.0);
844  new TGeoBBox("sensor_active_centered_cutout", active_part_dim_x / 2.0, active_part_dim_y / 2.0,
845  thickness / 2.0 + 0.1);
846 
847  TGeoTranslation* trans_sensor_active = new TGeoTranslation("trans_sensor_active",
848  -sensor_dim_x / 2.0 + active_part_dim_x / 2.0 + active_part_offset_x,
849  -sensor_dim_y / 2.0 + active_part_dim_y / 2.0 + active_part_offset_y, 0.);
850  trans_sensor_active->RegisterYourself();
851 
852  TGeoCompositeShape* sensor_passive_centered = new TGeoCompositeShape("sensor_passive_centered",
853  "(sensor_full_centered-sensor_active_centered_"
854  "cutout:trans_sensor_active)");
855 
856  TGeoVolume* passive_sensor_volume = new TGeoVolume("LumPassiveRect", sensor_passive_centered,
857  gGeoMan->GetMedium("silicon"));
858  passive_sensor_volume->SetLineColor(kViolet);
859 
860  TGeoVolume* active_sensor_volume = new TGeoVolume(navigation_paths[5].first.c_str(),
861  sensor_active_centered, gGeoMan->GetMedium("silicon"));
862  active_sensor_volume->SetLineColor(kYellow);
863 
864  // put cable on top of the sensor
865  /*TGeoTubeSeg* shape_kapton_disc = new TGeoTubeSeg("shape_kapton_disc",
866  inner_rad,
867  lmd_cool_sup_inner_rad - gap_between_disc_and_support_structure,
868  kapton_disc_thick_half, -delta_phi / 2. / pi * 180.,
869  +delta_phi / 2. / pi * 180.);
870 
871  TGeoRotation* kapton_rotation = new TGeoRotation("kapton_rotation", 0, 0,
872  0);
873  TGeoTranslation* kapton_translation = new TGeoTranslation(
874  "kapton_translation", -cvd_disc_dist, 0, 0);
875  TGeoCombiTrans* kapton_combtrans = new TGeoCombiTrans(*kapton_translation,
876  *kapton_rotation);
877  kapton_combtrans->SetName("kapton_combtrans");
878  kapton_combtrans->RegisterYourself();
879 
880  //this next line is pretty stupid but it made the work for the better
881  geometry minimal
882  //otherwise I would have to do some deeper digging and reworking...
883  TGeoCompositeShape *shape_kapton_support =
884  new TGeoCompositeShape("shape_kapton_support",
885  "(shape_kapton_disc:kapton_combtrans+shape_kapton_disc:kapton_combtrans)");
886 
887  TGeoVolume* lmd_vol_kapton_disc = new TGeoVolume("lmd_vol_kapton_disc",
888  shape_kapton_support, fgGeoMan->GetMedium("Aluminum")); //kapton")); //
889  changed to equivalent for glue/flex cable etc.
890  lmd_vol_kapton_disc->SetLineColor(kRed);
891  //lmd_vol_kapton_disc->SetTransparency(50);
892  lmd_vol_kapton_disc->SetVisibility(false);*/
893 
894  lmd_vol_sensor->AddNode(passive_sensor_volume, 0);
895  lmd_vol_sensor->AddNode(active_sensor_volume, 0, trans_sensor_active);
896  return lmd_vol_sensor;
897 }
Double_t thickness
std::vector< StringBoolPair > navigation_paths
boost::property_tree::ptree geometry_property_tree
TGeoVolume * PndLmdGeometryFactory::generateSensorModule ( ) const
private

Definition at line 681 of file PndLmdGeometryFactory.cxx.

References generateCVDCoolingDisc(), generateSensor(), geometry_property_tree, i, navigation_paths, rot, sensor, and trans.

Referenced by generateDetectorHalfPlane().

681  {
682  TGeoVolumeAssembly* lmd_vol_module = new TGeoVolumeAssembly(navigation_paths[3].first.c_str());
683 
684  // generate cvd cooling disk
685  TGeoVolume* cvd_disc = generateCVDCoolingDisc();
686  lmd_vol_module->AddNode(cvd_disc, 0);
687 
688  // generate a sensor and replicate it on the module
689  TGeoVolume* sensor = generateSensor();
690 
691  unsigned int num_modules_per_plane(
692  geometry_property_tree.get<double>("general.modules_per_half_plane"));
693  double cvd_disc_inner_radius(
694  geometry_property_tree.get<double>("cooling_support.cvd_disc.inner_radius"));
695  double cvd_disc_outer_radius(geometry_property_tree.get<double>("cooling_support.inner_radius"));
696  double cvd_disc_thickness(geometry_property_tree.get<double>("cooling_support.cvd_disc.thickness"));
697  double sensor_dim_x(geometry_property_tree.get<double>("sensors.dimension_x"));
698  double sensor_dim_y(geometry_property_tree.get<double>("sensors.dimension_y"));
699  double sensor_thickness(geometry_property_tree.get<double>("sensors.thickness"));
700 
701  unsigned int num_sensors_per_module_side(
702  geometry_property_tree.get<unsigned int>("general.sensors_per_module_side"));
703 
704  TGeoRotation* rot_all_sensors_front = new TGeoRotation("rot_all_sensors", 0.0, 0.0, 0.0);
705 
706  unsigned int column_counter(0);
707  double current_row_x_shift(0.0);
708  double current_row_y_shift(0.0);
709  for (unsigned int i = 0; i < num_sensors_per_module_side; ++i) {
710  // check if sensors overlap the cvd disc and if so start a new row
711  if (current_row_x_shift + sensor_dim_x * (column_counter + 1)
712  > cvd_disc_outer_radius - cvd_disc_inner_radius) {
713  current_row_x_shift += geometry_property_tree.get<double>("general.offset_second_row_sensors_x");
714  current_row_y_shift += sensor_dim_y;
715  rot_all_sensors_front->RotateZ(
716  geometry_property_tree.get<double>("general.rotation_second_row_sensors_z"));
717 
718  // reset column counter
719  column_counter = 0;
720  }
721 
722  TGeoCombiTrans* rottrans_side_offset =
723  new TGeoCombiTrans(
724  (current_row_x_shift + 0.5 * sensor_dim_x + cvd_disc_inner_radius
725  + sensor_dim_x * column_counter), 0.5 * sensor_dim_y + current_row_y_shift,
726  -0.5 * sensor_thickness - 0.5 * cvd_disc_thickness, rot_all_sensors_front);
727  lmd_vol_module->AddNode(sensor, i, rottrans_side_offset);
728 
729  ++column_counter;
730  }
731 
732  // now sensors on back (they need a flip rotation)
733  TGeoRotation* rot_all_sensors_back = new TGeoRotation("rot_all_sensors", 0.0, 0.0, 0.0);
734  rot_all_sensors_back->RotateX(180.0);
735  rot_all_sensors_back->RotateZ(180.0 / num_modules_per_plane);
736 
737  column_counter = 0;
738  current_row_x_shift = 0.0;
739  current_row_y_shift = 0.0;
740  for (unsigned int i = 0; i < num_sensors_per_module_side; ++i) {
741  // check if sensors overlap the cvd disc and if so start a new row
742  if (current_row_x_shift + sensor_dim_x * (column_counter + 1)
743  > cvd_disc_outer_radius - cvd_disc_inner_radius) {
744  current_row_x_shift += geometry_property_tree.get<double>("general.offset_second_row_sensors_x");
745  current_row_y_shift -= sensor_dim_y;
746  rot_all_sensors_back->RotateZ(
747  geometry_property_tree.get<double>("general.rotation_second_row_sensors_z"));
748 
749  // reset column counter
750  column_counter = 0;
751  }
752 
753  // corrections from rotation
754  double x_center(
755  current_row_x_shift + cvd_disc_inner_radius + sensor_dim_x * column_counter
756  + 0.5 * sensor_dim_x);
757 
758  // calculate corrections
759  TGeoHMatrix rot;
760  rot.RotateZ(180.0 / num_modules_per_plane);
761  TGeoHMatrix trans;
762  trans.SetDx(x_center);
763  trans.SetDy(-0.5 * sensor_dim_y + current_row_y_shift);
764  rot.Multiply(&trans);
765 
766  TGeoCombiTrans* rottrans_side_offset = new TGeoCombiTrans(rot.GetTranslation()[0],
767  rot.GetTranslation()[1], 0.5 * sensor_thickness + 0.5 * cvd_disc_thickness,
768  rot_all_sensors_back);
769  lmd_vol_module->AddNode(sensor, num_sensors_per_module_side + i, rottrans_side_offset);
770 
771  ++column_counter;
772  }
773 
774  return lmd_vol_module;
775 }
Int_t i
Definition: run_full.C:25
TGeoVolume * sensor
TGeoVolume * generateCVDCoolingDisc() const
TGeoVolume * generateSensor() const
TGeoTranslation * trans
std::vector< StringBoolPair > navigation_paths
TGeoRotation rot
boost::property_tree::ptree geometry_property_tree
void PndLmdGeometryFactory::init ( FairGeoLoader *  geoLoad)

Definition at line 45 of file PndLmdGeometryFactory.cxx.

References retrieveMaterial().

Referenced by createLmdGeometry().

45  {
47 }
FairGeoLoader * geoLoad
void retrieveMaterial(FairGeoLoader *geoLoad)
void PndLmdGeometryFactory::makeNodesAlignable ( ) const
private

Definition at line 938 of file PndLmdGeometryFactory.cxx.

References gGeoMan, and i.

Referenced by generateLmdGeometry(), and makeNodesAlignable().

938  {
939  TGeoNode* node = gGeoMan->GetTopNode();
940  gGeoMan->CdTop();
941  for (int i = 0; i < node->GetNdaughters(); ++i) {
942  makeNodesAlignable(node->GetDaughter(i), 0);
943  }
944 }
Int_t i
Definition: run_full.C:25
void PndLmdGeometryFactory::makeNodesAlignable ( TGeoNode *  node,
unsigned int  current_navigation_path_index 
) const
private

Definition at line 946 of file PndLmdGeometryFactory.cxx.

References gGeoMan, i, makeNodesAlignable(), and navigation_paths.

947  {
948  // make this volume alignable
949  std::stringstream full_path;
950  full_path << gGeoMan->GetPath() << "/" << node->GetName();
951  gGeoMan->cd(full_path.str().c_str());
952 
953  bool found(false);
954  // first check if this node name is found in any of the navigation paths
955  for (auto const& path_part : navigation_paths) {
956  if (std::string(node->GetName()).find(path_part.first) != std::string::npos) {
957  found = true;
958  break;
959  }
960  }
961 
962  if (found) {
963  if (std::string(node->GetName()).find(navigation_paths[current_navigation_path_index].first)
964  != std::string::npos) {
965  if (navigation_paths[current_navigation_path_index].second) gGeoMan->SetAlignableEntry(
966  full_path.str().c_str(), full_path.str().c_str());
967  }
968  else {
969  std::runtime_error("PndLmdGeometryFactory::makeNodesAlignable(): Volume path structure "
970  "is mismatching!");
971  }
972  }
973 
974  for (int i = 0; i < node->GetNdaughters(); ++i) {
975  makeNodesAlignable(node->GetDaughter(i), current_navigation_path_index + 1);
976  }
977  gGeoMan->CdUp();
978 }
Int_t i
Definition: run_full.C:25
std::vector< StringBoolPair > navigation_paths
void PndLmdGeometryFactory::recursiveNodeSubtraction ( std::stringstream &  ss,
TGeoNode *  node 
) const
private

Definition at line 927 of file PndLmdGeometryFactory.cxx.

References i.

Referenced by generateBoxVacuum().

927  {
928  if (node->GetNdaughters() == 0) {
929  ss << "-" << node->GetVolume()->GetName() << ":" << node->GetMatrix()->GetName();
930  }
931  else {
932  for (int i = 0; i < node->GetNdaughters(); ++i) {
933  recursiveNodeSubtraction(ss, node->GetDaughter(i));
934  }
935  }
936 }
void recursiveNodeSubtraction(std::stringstream &ss, TGeoNode *node) const
Int_t i
Definition: run_full.C:25
void PndLmdGeometryFactory::retrieveMaterial ( FairGeoLoader *  geoLoad)
private

Definition at line 49 of file PndLmdGeometryFactory.cxx.

References FairMediumAir, FairMediumVacuum, geobuild, and Media.

Referenced by init().

49  {
50  FairGeoMedia* Media = geoLoad->getGeoInterface()->getMedia();
51  FairGeoBuilder* geobuild = geoLoad->getGeoBuilder();
52 
53  // retrieve available media
54  FairGeoMedium* FairMediumAir = Media->getMedium("air");
55  FairGeoMedium* FairMediumSteel = Media->getMedium("steel");
56  FairGeoMedium* FairMediumAl = Media->getMedium("Aluminum");
57  FairGeoMedium* FairMediumSilicon = Media->getMedium("silicon");
58  FairGeoMedium* FairMediumDiamond = Media->getMedium("HYPdiamond");
59  FairGeoMedium* FairMediumVacuum = Media->getMedium("vacuum7");
60  FairGeoMedium* FairMediumKapton = Media->getMedium("kapton");
61  FairGeoMedium* FairMediumCopper = Media->getMedium("copper");
62  FairGeoMedium* FairMediumGlassFiber = Media->getMedium("GlassFiber");
63 
64  if (!FairMediumAir || !FairMediumSteel || !FairMediumAl || !FairMediumKapton || !FairMediumSilicon
65  || !FairMediumVacuum || !FairMediumCopper) {
66  LOG(ERROR) << "PndLmdGeometryFactory::retrieveMaterial: not all media found ";
67  return;
68  }
69 
70  geobuild->createMedium(FairMediumAir);
71  geobuild->createMedium(FairMediumSteel);
72  geobuild->createMedium(FairMediumAl);
73  geobuild->createMedium(FairMediumKapton);
74  geobuild->createMedium(FairMediumSilicon);
75  geobuild->createMedium(FairMediumDiamond);
76  geobuild->createMedium(FairMediumVacuum);
77  geobuild->createMedium(FairMediumCopper);
78  geobuild->createMedium(FairMediumGlassFiber);
79 }
FairGeoMedium * FairMediumVacuum
FairGeoLoader * geoLoad
FairGeoMedia * Media
FairGeoMedium * FairMediumAir
FairGeoBuilder * geobuild

Member Data Documentation

boost::property_tree::ptree PndLmdGeometryFactory::geometry_property_tree
private
TGeoManager* PndLmdGeometryFactory::gGeoMan
private
std::vector<StringBoolPair> PndLmdGeometryFactory::navigation_paths
private

The documentation for this class was generated from the following files: