示例#1
0
/** Basic entry point to print out detector type map
 *
 *  @author  M.Frank
 *  @version 1.0
 *  @date    01/04/2014
 */
static long detectortype_cache(LCDD& lcdd, int , char** ) {
  vector<string> v = lcdd.detectorTypes();
  printout(INFO,"DetectorTypes","Detector type dump:  %ld types:",long(v.size()));
  for(vector<string>::const_iterator i=v.begin(); i!=v.end(); ++i)   {
    const vector<DetElement>& vv=lcdd.detectors(*i);
    printout(INFO,"DetectorTypes","\t --> %ld %s detectors:",long(vv.size()),(*i).c_str());
    for(vector<DetElement>::const_iterator j=vv.begin(); j!=vv.end(); ++j)
      printout(INFO,"DetectorTypes","\t\t %-16s --> %s  [%s]",(*i).c_str(),(*j).name(),(*j).type().c_str());
  }
  return 1;
}
示例#2
0
static long exec_SimpleGDMLWriter(LCDD& lcdd, int argc, char** argv) {
  if ( argc > 1 )   {
    string output = argv[1];
    ofstream out(output.c_str()+1,ios_base::out);
    SimpleGDMLWriter dmp(out);
    dmp.create(lcdd.world());
  }
  else   {
    SimpleGDMLWriter dmp(cout);
    dmp.create(lcdd.world());
  }
  return 1;
}
示例#3
0
static long load_compact(LCDD& lcdd, int argc, char** argv) {
  if ( argc > 0 )   {
    LCDDBuildType type = BUILD_DEFAULT;
    string input = argv[0];
    if ( argc > 1 )  {
      type = build_type(argv[1]);
      printout(INFO,"CompactLoader","+++ Processing compact file: %s with flag %s",
               input.c_str(), argv[1]);
      lcdd.fromCompact(input,type);
      return 1;
    }
    printout(INFO,"CompactLoader","+++ Processing compact file: %s",input.c_str());
    lcdd.fromCompact(input);
    return 1;
  }
  return 0;
}
static Ref_t create_detector(LCDD& lcdd, xml_h e, Ref_t)    {
  xml_det_t  x_det = e;
  string     name  = x_det.nameStr();
  DetElement sdet (name,x_det.id());
  Material   mat  (lcdd.material(x_det.materialStr()));

  // multiplication factor for ellipse major radius
  double c0 = 3.5;
  double rmin = 0.0, rmax = 0.0, z = 0.0;

  for(xml_coll_t c(x_det,_U(zplane)); c; ++c)  {
    xml_comp_t dim(c);
    rmin = dim.rmin();
    rmax = dim.rmax();
    z    = dim.z();
  }
 
  double ra    = rmax * c0;      // elipse long radius
  double rb    = rmax;           // elipse short radius
  double thick = rmax - rmin;    // pipe wall thickness
 
  EllipticalTube bpElTubeOut(ra+thick, rb+thick, z);
  EllipticalTube bpElTubeInn(ra, rb, z+thick);
  SubtractionSolid bpElTube(bpElTubeOut,bpElTubeInn);

  Tube bpTube1(rb, rb+thick, z+thick, 3*M_PI/2, M_PI/2);
  UnionSolid beamTube1(bpElTube,bpTube1);

  Tube bpTube2(rb+thick, ra+thick, z+thick, 3*M_PI/2, M_PI/2);
  SubtractionSolid beamTube(beamTube1,bpTube2);
  
  Volume     volume(name, beamTube, mat);
  
  double z_offset = x_det.hasAttr(_U(z_offset)) ? x_det.z_offset() : 0.0;

  volume.setVisAttributes(lcdd, x_det.visStr());
  PlacedVolume pv = lcdd.pickMotherVolume(sdet).placeVolume(volume,Position(0,0,z_offset));
  sdet.setPlacement(pv);
  
  if ( x_det.hasAttr(_U(id)) )  {
    int det_id = x_det.id();
    pv.addPhysVolID("system",det_id);
  }
  return sdet;
}
示例#5
0
static long display(LCDD& lcdd, int argc, char** argv) {
  TGeoManager& mgr = lcdd.manager();
  const char* opt = "ogl";
  if (argc > 0) {
    opt = argv[0];
  }
  mgr.SetVisLevel(4);
  mgr.SetVisOption(1);
  TGeoVolume* vol = mgr.GetTopVolume();
  if (vol) {
    vol->Draw(opt);
    return 1;
  }
  return 0;
}
示例#6
0
/** Basic entry point to print out the volume hierarchy
 *
 *  @author  M.Frank
 *  @version 1.0
 *  @date    01/04/2014
 */
static long detelement_cache(LCDD& lcdd, int , char** ) {
  struct Actor {
    static long cache(DetElement de) {
      const DetElement::Children& c = de.children();
      de.worldTransformation();
      de.parentTransformation();
      de.placementPath();
      de.path();
      for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
        cache((*i).second);
      return 1;
    }
  };
  return Actor::cache(lcdd.world());
}
示例#7
0
/** Basic entry point to print out the detector element hierarchy
 *
 *  @author  M.Frank
 *  @version 1.0
 *  @date    01/04/2014
 */
template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) {
  struct Actor {
    static long dump(DetElement de,int level, bool sensitive_only) {
      const DetElement::Children& c = de.children();
      if ( !sensitive_only || 0 != de.volumeID() )  {
        PlacedVolume place = de.placement();
        const TGeoNode* node = place.ptr();
        char sens = place.volume().isSensitive() ? 'S' : ' ';
        int value = flag;
        char fmt[128];
        switch(value)  {
        case 0:
          ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s #Dau:%%d VolID:%%08X Place:%%p  %%c",level+1,2*level+1);
          printout(INFO,"DetectorDump",fmt,"",de.path().c_str(),int(c.size()),
                   (unsigned long)de.volumeID(), (void*)node, sens);
          break;
        case 1:
          ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1);
          printout(INFO,"DetectorDump", fmt, "", de.path().c_str(),
                   int(c.size()), (void*)de.volumeID());
          ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Placement: %%s   %%c",level+1,2*level+3);
          printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(), sens);
          break;
        default:
          break;
        }
      }
      for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
        dump((*i).second,level+1,sensitive_only);
      return 1;
    }
  };
  bool sensitive_only = false;
  for(int i=0; i<argc; ++i)  {
    if ( ::strcmp(argv[i],"--sensitive")==0 ) { sensitive_only = true; }
  }
  return Actor::dump(lcdd.world(),0,sensitive_only);
}
示例#8
0
static long exec_GeometryTreeDump(LCDD& lcdd, int, char** ) {
  GeometryTreeDump dmp;
  dmp.create(lcdd.world());
  return 1;
}
示例#9
0
/** Basic entry point to print out the volume hierarchy
 *
 *  @author  M.Frank
 *  @version 1.0
 *  @date    01/04/2014
 */
static long dump_volume_tree(LCDD& lcdd, int argc, char** argv) {
  struct Actor {
    typedef PlacedVolume::VolID  VID;
    typedef PlacedVolume::VolIDs VIDs;
    bool m_printVolIDs;
    bool m_printPositions;
    bool m_printSensitivesOnly;
    Actor(int ac, char** av) 
      : m_printVolIDs(false), m_printPositions(false), m_printSensitivesOnly(false)
    {
      for(int i=0; i<ac; ++i)  {
        char c = ::tolower(av[i][0]);
        if ( c == 'v' ) m_printVolIDs = true;
        else if ( c == 'p' ) m_printPositions = true;
        else if ( c == 's' ) m_printSensitivesOnly = true;
      }
    }

    long dump(TGeoNode* ideal, TGeoNode* aligned,int level, VIDs volids) const {
      char fmt[128];
      string opt_info;
      PlacedVolume pv(ideal);
      bool sensitive = false;
      if ( m_printPositions || m_printVolIDs )  {
        stringstream log;
        if ( m_printPositions )  {
          const double* trans = ideal->GetMatrix()->GetTranslation();
          ::snprintf(fmt, sizeof(fmt), "Pos: (%f,%f,%f) ",trans[0],trans[1],trans[2]);
          log << fmt;
        }
        // Top level volume! have no volume ids
        if ( m_printVolIDs && ideal && ideal->GetMotherVolume() )  {
          VIDs vid = pv.volIDs();
          if ( !vid.empty() )  {
            sensitive = true;
            log << " VolID: ";
            volids.std::vector<VID>::insert(volids.end(),vid.begin(),vid.end());
            for(VIDs::const_iterator i=volids.begin(); i!=volids.end(); ++i)  {
              ::snprintf(fmt, sizeof(fmt), "%s:%2d ",(*i).first.c_str(), (*i).second);
              log << fmt;
            }
          }
        }
        opt_info = log.str();
      }
      TGeoVolume* volume = ideal->GetVolume();
      if ( !m_printSensitivesOnly || (m_printSensitivesOnly && sensitive) )  {
        char sens = pv.volume().isSensitive() ? 'S' : ' ';
        if ( ideal == aligned )  {
          ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s (%%s: %%s) \t[%p] %c %%s",
                     level+1,2*level+1,(void*)ideal, sens);
        }
        else  {
          ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s (%%s: %%s) Ideal:%p Aligned:%p %c %%s",
                     level+1,2*level+1,(void*)ideal,(void*)aligned, sens);
        }
        printout(INFO,"+++",fmt,"",
                 aligned->GetName(),
                 volume->GetTitle(),
                 volume->GetShape()->IsA()->GetName(),
                 opt_info.c_str());
      }
      for (Int_t idau = 0, ndau = aligned->GetNdaughters(); idau < ndau; ++idau)  {
        TGeoNode*   ideal_daughter   = ideal->GetDaughter(idau);
        const char* daughter_name    = ideal_daughter->GetName();
        TGeoNode*   aligned_daughter = volume->GetNode(daughter_name);
        dump(ideal_daughter, aligned_daughter, level+1, volids);
      }
      return 1;
    }
  };
  string place = lcdd.world().placementPath();
  DetectorTools::PlacementPath path;
  DetectorTools::placementPath(lcdd.world(), path);
  PlacedVolume  pv = DetectorTools::findNode(lcdd.world().placement(),place);
  Actor actor(argc,argv);
  return actor.dump(lcdd.world().placement().ptr(),pv.ptr(),0,PlacedVolume::VolIDs());
}
示例#10
0
static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sens)
{

    xml_det_t   x_det = e;
    string det_name = x_det.nameStr();
    Material air = lcdd.air();

    //Detector envelope of SubDetector
    DetElement tracker(det_name, x_det.id());
    //add Extension to Detlement for the RecoGeometry
    Det::DetExtension* ex = new Det::DetExtension();
    tracker.addExtension<Det::IDetExtension> (ex);

    //Create the Volume of the Detector envelope
    DD4hep::XML::Dimension x_det_dim(x_det.dimensions());
    double z = x_det_dim.z();
    Tube tracker_shape(x_det_dim.rmin(),x_det_dim.rmax(),z);
    Volume tracker_vol(x_det.nameStr()+"_envelope",tracker_shape, air);
    //Vizualization
    tracker_vol.setVisAttributes(lcdd.invisible());
    //Set sensitive type tracker
    sens.setType("tracker");

    int layer_num = 0;

    //Go through layers
    for (xml_coll_t j(e,_U(layer)); j; ++j )
    {
        xml_comp_t x_layer = j;
        double rmin     = x_layer.inner_r();
        double rmax     = x_layer.outer_r();
        double radius   = (rmax+rmin)*0.5;
        double layer_z  = x_layer.z();

        //Create Volume and DetElement for Layer
        string layer_name  = det_name + _toString(layer_num,"layer%d");
        Volume layer_vol(layer_name,Tube(rmin,rmax,layer_z), lcdd.material(x_layer.materialStr()));
        DetElement lay_det (tracker,layer_name,layer_num);

        //Visualization
        layer_vol.setVisAttributes(lcdd.invisible());

        //module in phi // later also loop through modules for different modules
        xml_comp_t x_module = x_layer.child(_U(module));
        int repeat = x_module.repeat();
        double deltaphi = 2.*M_PI/repeat;
        //slices in z
        xml_comp_t x_slice = x_layer.child(_U(slice));
        int zrepeat = x_slice.repeat();
        double dz = x_slice.z();

        //add Extension to Detlement for the RecoGeometry
        Det::DetCylinderLayer* detcylinderlayer = new Det::DetCylinderLayer();
        lay_det.addExtension<Det::IDetExtension>(detcylinderlayer);

        int module_num = 0;
        //Place the Modules in z
        for (int k = -zrepeat; k<=zrepeat; k++)
        {
            string zname = _toString(k,"z%d");

            //Place the Modules in phi
            for (int i = 0; i < repeat; ++i)
            {
                //Create Module Volume
                Volume mod_vol("module", Box(x_module.length(), x_module.width(),x_module.thickness()), air);
                //Vizualization
                mod_vol.setVisAttributes(lcdd.invisible());

                double phi = deltaphi/dd4hep::rad * i;
                string module_name = zname + _toString(i,"module%d");

                Position trans(radius * cos(phi),
                               radius * sin(phi),
                               k*dz);

                //Create module Detelement
                DetElement mod_det(lay_det,module_name,module_num);
                //add Extension to Detlement for the RecoGeometry
                Det::DetModule* detmod = new Det::DetModule();
                mod_det.addExtension<Det::IDetExtension> (detmod);

                int comp_num = 0;
                //go through module components
                for (xml_coll_t n(x_module,_U(module_component)); n; ++n) {
                    xml_comp_t x_comp = n;

                    Volume comp_vol("component " + x_comp.materialStr(), Box(x_comp.length(),x_comp.width(), x_comp.thickness()),lcdd.material(x_comp.materialStr()));
                    //                  comp_vol.setVisAttributes(lcdd, x_comp.visStr());
                    //Set Sensitive Volmes sensitive
                    if (x_comp.isSensitive()) {
                        comp_vol.setSensitiveDetector(sens);
                    }
                    //Create DetElement
                    DetElement comp_det(mod_det, "component, " + x_comp.materialStr(),comp_num);
                    //add Extension
                    comp_det.addExtension<Det::IDetExtension> (ex);
                    //place component in Module
                    xml_comp_t x_pos = x_comp.position(false);
                    Position transComp (x_pos.x(),x_pos.y(),x_pos.z());
                    PlacedVolume placedcomp = mod_vol.placeVolume(comp_vol,transComp);
                    //assign the placed Volume to the DetElement
                    comp_det.setPlacement(placedcomp);
                    placedcomp.addPhysVolID("component",comp_num);
                    ++comp_num;
                }

                //Place Box Volumes in layer
                PlacedVolume placedmodule = layer_vol.placeVolume(mod_vol, Transform3D(RotationX(0.5*M_PI)*RotationZ(0.5*M_PI)*RotationX(phi-0.6*M_PI),trans));
                placedmodule.addPhysVolID("module", module_num);
                // assign module DetElement to the placed Module volume
                mod_det.setPlacement(placedmodule);


                ++module_num;
            }
            ++module_num;
        }
        //Place Layervolume

        PlacedVolume placedLayer = tracker_vol.placeVolume(layer_vol);
        placedLayer.addPhysVolID("layer",layer_num);
        placedLayer.addPhysVolID("system",x_det.id());
        //Assign Layer DetElement to LayerVolume
        lay_det.setPlacement(placedLayer);
        ++layer_num;

    }
    Volume mother_vol = lcdd.pickMotherVolume(tracker);
    //Place envelopevolume in mothervolume
    PlacedVolume placed_env = mother_vol.placeVolume(tracker_vol);
    //assign tracker DetElement to tracker volume
    tracker.setPlacement(placed_env); //fuer envelope moeglich


    return tracker;
}
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
  typedef vector<PlacedVolume> Placements;
  xml_det_t   x_det     = e;
  Material    vacuum    = lcdd.vacuum();
  int         det_id    = x_det.id();
  string      det_name  = x_det.nameStr();
  bool        reflect   = x_det.reflect(false);
  DetElement  sdet        (det_name,det_id);
  Assembly    assembly    (det_name);
  //Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
  Volume      motherVol = lcdd.pickMotherVolume(sdet);
  int         m_id=0, c_id=0, n_sensor=0;
  map<string,Volume> modules;
  map<string, Placements>  sensitives;
  PlacedVolume pv;

  assembly.setVisAttributes(lcdd.invisible());
  sens.setType("tracker");

  for(xml_coll_t mi(x_det,_U(module)); mi; ++mi, ++m_id)  {
    xml_comp_t x_mod   = mi;
    string     m_nam   = x_mod.nameStr();
    xml_comp_t trd     = x_mod.trd();
    double     posY;
    double     x1      = trd.x1();
    double     x2      = trd.x2();
    double     z       = trd.z();
    double     y1, y2, total_thickness=0.;
    xml_coll_t ci(x_mod,_U(module_component));
    for(ci.reset(), total_thickness=0.0; ci; ++ci)
      total_thickness += xml_comp_t(ci).thickness();
      
    y1 = y2 = total_thickness / 2;
    Volume  m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
    m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));

    for(ci.reset(), n_sensor=1, c_id=0, posY=-y1; ci; ++ci, ++c_id)  {
      xml_comp_t c       = ci;
      double     c_thick = c.thickness();
      Material   c_mat   = lcdd.material(c.materialStr());
      string     c_name  = _toString(c_id,"component%d");
      Volume     c_vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat);

      c_vol.setVisAttributes(lcdd.visAttributes(c.visStr()));
      pv = m_volume.placeVolume(c_vol,Position(0,posY+c_thick/2,0));
      if ( c.isSensitive() ) {
        sdet.check(n_sensor > 2,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!");
        pv.addPhysVolID("sensor",n_sensor);
        c_vol.setSensitiveDetector(sens);
        sensitives[m_nam].push_back(pv);
        ++n_sensor;
      }
      posY += c_thick;
    }
    modules[m_nam] = m_volume;
  }
  
  for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
    xml_comp_t  x_layer(li);
    int l_id    = x_layer.id();
    int mod_num = 1;

    for(xml_coll_t ri(x_layer,_U(ring)); ri; ++ri)  {
      xml_comp_t x_ring = ri;
      double r        = x_ring.r();
      double phi0     = x_ring.phi0(0);
      double zstart   = x_ring.zstart();
      double dz       = x_ring.dz(0);
      int    nmodules = x_ring.nmodules();
      string m_nam    = x_ring.moduleStr();
      Volume m_vol    = modules[m_nam];
      double iphi     = 2*M_PI/nmodules;
      double phi      = phi0;
      Placements& sensVols = sensitives[m_nam];

      for(int k=0; k<nmodules; ++k) {
        string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d");
        double x = -r*std::cos(phi);
        double y = -r*std::sin(phi);
        DetElement module(sdet,m_base+"_pos",det_id);
        pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2),Position(x,y,zstart+dz)));
        pv.addPhysVolID("side",1).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
        module.setPlacement(pv);
        for(size_t ic=0; ic<sensVols.size(); ++ic)  {
          PlacedVolume sens_pv = sensVols[ic];
          DetElement comp_elt(module,sens_pv.volume().name(),mod_num);
          comp_elt.setPlacement(sens_pv);
        }

        if ( reflect ) {
          pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(M_PI,-M_PI/2-phi,-M_PI/2),Position(x,y,-zstart-dz)));
          pv.addPhysVolID("side",-1).addPhysVolID("layer",l_id).addPhysVolID("module",mod_num);
          DetElement r_module(sdet,m_base+"_neg",det_id);
          r_module.setPlacement(pv);
          for(size_t ic=0; ic<sensVols.size(); ++ic)  {
            PlacedVolume sens_pv = sensVols[ic];
            DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num);
            comp_elt.setPlacement(sens_pv);
          }
        }
        dz   = -dz;
        phi += iphi;
        ++mod_num;
      }
    }
  }
  pv = motherVol.placeVolume(assembly);
  pv.addPhysVolID("system",det_id);
  sdet.setPlacement(pv);
  return sdet;
}
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {

  //XML detector object: DDCore/XML/XMLDetector.h
  DD4hep::XML::DetElement x_det = e;
  
  //Create the DetElement for DD4hep
  DetElement d_det(x_det.nameStr(),x_det.id());
  
  //Pick the mothervolume
  Volume det_vol = lcdd.pickMotherVolume(d_det);

  //XML dimension object: DDCore/XML/XMLDimension.h
  DD4hep::XML::Dimension x_det_dim(x_det.dimensions());
  
  //Tube: DDCore/DD4hep/Shapes.h
  Tube calo_shape(x_det_dim.rmin(),x_det_dim.rmax(),x_det_dim.z());
  
  //Create the detector mother volume
  Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,lcdd.air());

  //Set envelope volume attributes
  calo_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());

  //Place inside the mother volume
  PlacedVolume  calo_plv = det_vol.placeVolume(calo_vol);

  calo_plv.addPhysVolID("system",x_det.id());
  calo_plv.addPhysVolID("barrel",0);
  d_det.setPlacement(calo_plv);

  //Declare this sensitive detector as a calorimeter
  sens.setType("calorimeter");


  int layer_num = 0;  
  float layer_pos_z = 0;
  double tile_phi = 2*M_PI/x_det_dim.phiBins();
  float r = x_det_dim.rmin();
  
  bool debug = false;

  //Repeat layers until we reach the rmax
  while(r<x_det_dim.rmax()){

    //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h
    for(DD4hep::XML::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt){
      
      //Build a layer volume
      DD4hep::XML::Component x_det_layer = layerIt;
      
      float dr = x_det_layer.dr();
      
      string layer_name =  x_det.nameStr()+_toString(layer_num,"_layer%d");
      
      float    x1  = r * tan(tile_phi/2.);
      float    x2  = (r+dr) * tan(tile_phi/2.);
      float    y1  = x_det_dim.z();
      float    y2  = x_det_dim.z();
      float    z   = x_det_layer.dr();
      
      if(debug){
	cout << " r:" << r 
	     << " dr:" << dr 
	     << " x1:" << x1 
	     << " x2:" << x2
	     << " y1:" << y1 
	     << " y2:" << y2 
	     << " z:" << z 
	     << endl;
      }
      
      //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
      Trapezoid layer_shape(x1,x2,y1,y2,z);
      
      //Create a volume with trapezoid shape
      Volume layer_vol(layer_name, layer_shape, lcdd.air());
      layer_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr());
      
      //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id());
      
      //Fill the volume with tiles
      
      
      int tile_number = 0;  
      vector<Volume> tiles;
      
      //Repeat slices until we reach the end of the calorimeter
      for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k)  {
	
	DD4hep::XML::Component tile_xml       = k;
	string                 tile_name      = layer_name + _toString(tile_number,"_slice%d");
	Material               tile_material  = lcdd.material(tile_xml.materialStr());
	float                  tile_thickness = tile_xml.dz();
	float                  tile_y1        = tile_thickness;
	float                  tile_y2        = tile_thickness;
	float                  tile_z         = x_det_layer.dr();
	
	//Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
	Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
	
	//Create a volume with trapezoid shape
	Volume tile_vol(tile_name,tile_shape,tile_material);
	
	if ( tile_xml.isSensitive() ) {
	  tile_vol.setSensitiveDetector(sens);
	}
	
	//Set region, limitset, and visibility settings
	tile_vol.setAttributes(lcdd,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr());
	
	tiles.push_back(tile_vol);
	tile_number++;
      }

      //Place the same volumes inside the envelope
      float tile_pos_z = -x_det_dim.z()/2.;
      int slice_num = 0;
      while(tile_pos_z<x_det_dim.z()/2.){
	tile_number=0;
	for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k)  {
	  
	  DD4hep::XML::Component tile_xml       = k;
	  float                  tile_thickness = tile_xml.dz();
	  
	  //Place the tile inside the layer
	  PlacedVolume tile_plv = layer_vol.placeVolume(tiles.at(tile_number),Position(0,tile_pos_z,0));
	  tile_plv.addPhysVolID("layer",layer_num);
	  tile_plv.addPhysVolID("slice",slice_num);

	  //Increment the z pos of the tile
	  tile_pos_z += tile_thickness;
	  tile_number++;
	  slice_num++;
	}
      }
      
      //Place the same layer around the beam axis phiBins times
      double mod_x_off = r;  
      double mod_y_off = 0;  
      for(int i=0;i<x_det_dim.phiBins();i++){
	if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl;
	double layer_pos_x = mod_x_off * cos(tile_phi*i) - mod_y_off * sin(tile_phi*i);
	double layer_pos_y = mod_x_off * sin(tile_phi*i) + mod_y_off * cos(tile_phi*i);
	Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0)*RotationZYX(0,tile_phi*i,0),
		       Translation3D(layer_pos_x,layer_pos_y,layer_pos_z));
	PlacedVolume pv = calo_vol.placeVolume(layer_vol,tr);
	pv.addPhysVolID("system",x_det.id());
	pv.addPhysVolID("barrel",0);
	pv.addPhysVolID("layer",layer_num);
	pv.addPhysVolID("module",i+1);
	//DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
      }
      
      r += dr;
      layer_num += 1;
    }
  }
  
  //Place the calo inside the world
  
  return d_det;
}
示例#13
0
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
    //XML detector object: DDCore/XML/XMLDetector.h
    xml_dim_t x_det = e;
    //Create the DetElement for DD4hep
    DetElement d_det(x_det.nameStr(),x_det.id());

    //XML dimension object: DDCore/XML/XMLDimension.h
    xml_dim_t x_det_dim(x_det.dimensions());
    //double inner_r = x_det_dim.rmin();
    //double outer_r = x_det_dim.rmax();
    Assembly calo_vol(x_det.nameStr()+"_envelope");
    PlacedVolume pv;

    //Set envelope volume attributes
    calo_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());

#if 0

    //Declare this sensitive detector as a calorimeter
    Tube tub(inner_r,outer_r,x_det_dim.z()/2.0,0.0,2*M_PI);
    //Volume tub_vol(x_det.nameStr()+"_tube",tub,lcdd.material("PyrexGlass"));
    Volume tub_vol(x_det.nameStr()+"_tube",tub,lcdd.material("Iron"));
    calo_vol.placeVolume(tub_vol);
    sens.setType("calorimeter");
    tub_vol.setSensitiveDetector(sens);
    d_det.setAttributes(lcdd,tub_vol,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
#endif

#if 1

    int layer_num = 0;
    float layer_pos_z = 0;
    double tile_phi = 2*M_PI/x_det_dim.phiBins();
    float r = x_det_dim.rmin();

    bool debug = true;

    Assembly stave_vol(x_det.nameStr()+"_stave_0");


    //Repeat layers until we reach the rmax
    while(r<x_det_dim.rmax()) {

        //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h
        for(DD4hep::XML::Collection_t layerIt(x_det,_U(layer)); layerIt; ++layerIt, ++layer_num)   {

            //Build a layer volume
            xml_comp_t x_det_layer = layerIt;

            float dr = x_det_layer.dr();

            string layer_name =  x_det.nameStr()+_toString(layer_num,"_layer%d");

            float    x1  = r * tan(tile_phi/2.);
            float    x2  = (r+dr) * tan(tile_phi/2.);
            float    y1  = x_det_dim.z();
            float    y2  = x_det_dim.z();
            float    z   = x_det_layer.dr();

            if(debug) {
                cout << " r:" << r
                     << " dr:" << dr
                     << " x1:" << x1
                     << " x2:" << x2
                     << " y1:" << y1
                     << " y2:" << y2
                     << " z:" << z
                     << endl;
            }

            //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
            Trapezoid layer_shape(x1,x2,y1,y2,z);

            //Create a volume with trapezoid shape
            Volume layer_vol(layer_name, layer_shape, lcdd.air());
            layer_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr());

            //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id());

            //Fill the volume with tiles
            vector<Volume> tiles;

            //Assembly tile_seq(layer_name+"_seq");
            Trapezoid tile_seq_shape(x1,x2,x_det_layer.dz(),x_det_layer.dz(),x_det_layer.dr());
            Volume tile_seq(layer_name + "_seq",tile_seq_shape,lcdd.air());
            double total_thickness = 0;
            //Repeat slices until we reach the end of the calorimeter
            int slice_num = 0, tile_number = 0;

            tile_seq.setVisAttributes(lcdd.visAttributes("VisibleGreen"));
            for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k, ++slice_num)  {
                xml_comp_t tile_xml       = k;
                string     tile_name      = layer_name + _toString(tile_number,"_slice%d");
                Material   tile_material  = lcdd.material(tile_xml.materialStr());
                float      tile_thickness = tile_xml.dz();
                float      tile_y1        = tile_thickness;
                float      tile_y2        = tile_thickness;
                float      tile_z         = x_det_layer.dr();

                Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
                Volume tile_vol(tile_name,tile_shape,tile_material);
                pv = tile_seq.placeVolume(tile_vol,Position(0,total_thickness,0));
                pv.addPhysVolID("slice",slice_num);
                total_thickness += tile_thickness;
                if ( tile_xml.isSensitive() ) {
                    cout << "Set volume " << tile_name << " sensitive...." << endl;
                    tile_vol.setSensitiveDetector(sens);
                }

                // Set region, limitset, and visibility settings
                tile_vol.setAttributes(lcdd,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr());
                tiles.push_back(tile_vol);
                tile_number++;
            }

            // Place the same volumes inside the envelope
            float tile_pos_z = -x_det_dim.z()/2.;
            int   tile_num = 0;
            while(tile_pos_z<x_det_dim.z()/2.) {
                pv = layer_vol.placeVolume(tile_seq,Position(0,tile_pos_z,0));
                pv.addPhysVolID("tile",tile_num);
                tile_pos_z += total_thickness;
                tile_num++;
            }

            // Place the same layer around the beam axis phiBins times
            Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0),Translation3D(r,0,layer_pos_z));
            pv = stave_vol.placeVolume(layer_vol,tr);
            pv.addPhysVolID("layer",layer_num);
            r += dr;
            cout << "+++ R=" << r << endl;
        }
    }
    //double mod_x_off = outer_r - (outer_r-inner_r)/2.0;
    //double mod_y_off = 0;
    int nphi_bins = x_det_dim.phiBins();
    for(int i=0; i<nphi_bins; i++) {
        if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl;
        double phi = tile_phi*i;
        //double pos_x = mod_x_off * cos(phi) - mod_y_off * sin(phi);
        //double pos_y = mod_x_off * sin(phi) + mod_y_off * cos(phi);
        Transform3D tr(RotationZYX(phi,0,0),Translation3D(0,0,0));
        pv = calo_vol.placeVolume(stave_vol,tr);
        pv.addPhysVolID("stave",i+1);
    }

    cout << "Number of layers: " << layer_num << endl;
#endif
    //Place the calo inside the world
    PlacedVolume  calo_plv = lcdd.pickMotherVolume(d_det).placeVolume(calo_vol);
    calo_plv.addPhysVolID("system",x_det.id());
    calo_plv.addPhysVolID("barrel",0);
    d_det.setPlacement(calo_plv);

    return d_det;
}
示例#14
0
static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens)
{
  xml_det_t   x_det     = element;
  Layering    layering(x_det.child(_U(layers)));
  std::string det_name    = x_det.nameStr();
  std::string det_type    = x_det.typeStr();
  Material    air         = lcdd.air();
  xml_dim_t   dim         = x_det.dimensions();
  xml_dim_t   x_pos  (x_det.child(_U(position)));
  xml_dim_t   x_rot  (x_det.child(_U(rotation)));

  Translation3D det_pos(x_pos.x(),x_pos.y(),x_pos.z());
  //Rotation is  ROOT::Math::RotationZYX
  //The input is Rotation(z,y,x)
  RotationZYX   det_rot(x_rot.z(),x_rot.y(),x_rot.x());
  
  DetElement   sdet(det_name,x_det.id());
  Volume      motherVol = lcdd.pickMotherVolume(sdet); 


  
  // ========= Create Hcal Modules envelope ============================
  //  They will be the volume for placing the Hcal Layers.
  //  Themselves will be placed into the world volume.
  // ==========================================================================
  
  // Hcal module shape
  double box_half_x  = dim.x()/2.0;
  double box_half_y  = dim.y()/2.0;
  double box_half_z  = dim.z()/2.0;
 
  Box    BoxModule(box_half_x,box_half_y,box_half_z);
  
  // define the name of  Module
  std::string envelopeVol_name   = det_name+_toString("_envelope");
  
  Volume envelopeVol(envelopeVol_name,BoxModule,air);
  
  // Set envelope volume attributes.
  envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
  
  
  // ========= Create Hcal Layers===== ==============================
  // It will be the sub volume for placing the slices.
  // Itself will be placed into the Hcal modules envelope.
  // ================================================================
  
  // create Layer (air) and place the slices into it. 
  // place the Layer into the Hcal Modules envelope.
  
  // Hcal layer start position
  double layer_pos_z     = - box_half_z;                      
  
  // Create Hcal Chamber without radiator
  // Place into the Hcal module envelope 
  int layer_num = 0;
  int module_num = 0;

  for(xml_coll_t c(x_det.child(_U(layers)),_U(layer)); c; ++c)
  {
    xml_comp_t   x_layer = c;

    //Layering    layering(x_layer);
    int          repeat = x_layer.repeat();
    const Layer* lay    = layering.layer(layer_num); // Get the layer from the layering engine.
    
    std::string layer_name      = det_name+ _toString(module_num,"_module%d_layer");
    double layer_thickness = lay->thickness();
    DetElement  layer(layer_name,"layerModule",x_det.id());
    
    // Layer box & volume
    double layer_dim_x = box_half_x;
    double layer_dim_y = box_half_y;
    double layer_dim_z = layer_thickness/2.0;
    
    // Build chamber including air gap
    // The Layer will be filled with slices, 
    Volume layer_vol(layer_name, Box(layer_dim_x,layer_dim_y,layer_dim_z), air);
    
    
    // ========= Create sublayer slices =========================================
    // Create and place the slices into Layer
    // ==========================================================================
    
    // Create the slices (sublayers) within the Hcal Chamber.
    double slice_pos_z = -(layer_thickness / 2.0);
    int slice_number = 0;

    for(xml_coll_t k(x_layer,_U(slice)); k; ++k)
    {
      xml_comp_t x_slice = k;
      std::string   slice_name      = layer_name + _toString(slice_number,"_slice%d");
      double   slice_thickness = x_slice.thickness();
      Material slice_material  = lcdd.material(x_slice.materialStr());

      DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id());
      
      slice_pos_z += slice_thickness / 2.0;
      
      // Slice volume & box
      Volume slice_vol(slice_name,Box(layer_dim_x,layer_dim_y,slice_thickness/2.0),slice_material);
      
      if ( x_slice.isSensitive() )
      {
		sens.setType("calorimeter");
		slice_vol.setSensitiveDetector(sens);
      }

      // Set region, limitset, and vis.
      slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
      // slice PlacedVolume
      PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z));
      slice_phv.addPhysVolID("slice",slice_number);
      
      slice.setPlacement(slice_phv);
      // Increment Z position for next slice.
      slice_pos_z += slice_thickness / 2.0;
      // Increment slice number.
      ++slice_number;             
    }
    // Set region, limitset, and vis.
    layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
    
    
    // ========= Place the Layer (i.e. Chamber) =================================
    // Place the Layer into the Hcal module envelope.
    // with the right position, and registry the ID layer
    // ==========================================================================
    
    for (int j = 0; j < repeat; j++)
    {
      
      // Layer position in z within the Modules.
      layer_pos_z += layer_thickness / 2.0;
      
      PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol,Position(0,0,layer_pos_z));

      // registry the ID of Layer
      layer_phv.addPhysVolID("layer",layer_num);
      layer_phv.addPhysVolID("module",j);

      // then setPlacement for it.
      layer.setPlacement(layer_phv);
      
      // Increment the layer_pos_z
      layer_pos_z += layer_thickness / 2.0;
      ++layer_num;         
    }
    
    module_num++; 
  }
  
  
  // for the alignment in the compact XML file
  Transform3D Tr3D = Transform3D(det_rot,det_pos);
  PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Tr3D);
  
  
  env_phv.addPhysVolID("system",x_det.id());
  sdet.setPlacement(env_phv);
  
  return sdet;
}
示例#15
0
/// Constructor. The detector element is identified by the name
Geant4SensitiveDetector::Geant4SensitiveDetector(const string& nam, LCDD& lcdd)
    : G4VSensitiveDetector(nam), m_lcdd(lcdd), m_detector(), m_sensitive(), m_readout(), m_hce(0) {
    m_sensitive = lcdd.sensitiveDetector(nam);
    m_detector = lcdd.detector(nam);
    m_readout = m_sensitive.readout();
}
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
  xml_det_t   x_det     = e;
  xml_dim_t   dim       = x_det.dimensions();
  int         det_id    = x_det.id();
  bool        reflect   = x_det.reflect(true);
  string      det_name  = x_det.nameStr();
  Material    air       = lcdd.air();
  int         numsides  = dim.numsides();
  double      rmin      = dim.rmin();
  double      rmax      = dim.rmax()*std::cos(M_PI/numsides);
  double      zmin      = dim.zmin();
  Layering    layering(x_det);
  double      totalThickness = layering.totalThickness();
  Volume      endcapVol("endcap",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
  DetElement  endcap("endcap",det_id);

  int l_num = 1;
  int layerType   = 0;
  double layerZ   = -totalThickness/2;

  endcapVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());

  for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
    xml_comp_t       x_layer  = c;
    double           l_thick  = layering.layer(l_num-1)->thickness();
    string           l_name   = _toString(layerType,"layer%d");
    int              l_repeat = x_layer.repeat();
    Volume           l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
    vector<PlacedVolume> sensitives;

    int s_num = 1;
    double sliceZ = -l_thick/2;
    for(xml_coll_t s(x_layer,_U(slice)); s; ++s)  {
      xml_comp_t x_slice = s;
      string     s_name  = _toString(s_num,"slice%d");
      double     s_thick = x_slice.thickness();
      Material   s_mat   = lcdd.material(x_slice.materialStr());
      Volume     s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
        
      s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr()));
      sliceZ += s_thick/2;
      PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ));
      s_phv.addPhysVolID("slice",s_num);
      if ( x_slice.isSensitive() )  {
	sens.setType("calorimeter");
	s_vol.setSensitiveDetector(sens);
	sensitives.push_back(s_phv);
      }
      sliceZ += s_thick/2;
      s_num++;
    }
    l_vol.setVisAttributes(lcdd.visAttributes(x_layer.visStr()));
    if ( l_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
    for(int j=0; j<l_repeat; ++j) {
      string phys_lay = _toString(l_num,"layer%d");
      layerZ += l_thick/2;
      DetElement    layer_elt(endcap, phys_lay, l_num);
      PlacedVolume  pv = endcapVol.placeVolume(l_vol,Position(0,0,layerZ));
      pv.addPhysVolID("layer", l_num);
      layer_elt.setPlacement(pv);
      for(size_t ic=0; ic<sensitives.size(); ++ic)  {
	PlacedVolume sens_pv = sensitives[ic];
	DetElement comp_elt(layer_elt,sens_pv.volume().name(),l_num);
	comp_elt.setPlacement(sens_pv);
      }
      layerZ += l_thick/2;
      ++l_num;
    }
    ++layerType;
  }

  double z_pos = zmin+totalThickness/2;
  PlacedVolume pv;
  // Reflect it.
  if ( reflect )  {
    Assembly    assembly(det_name);
    DetElement  both_endcaps(det_name,det_id);
    Volume      motherVol = lcdd.pickMotherVolume(both_endcaps);
    DetElement  sdetA = endcap;
    Ref_t(sdetA)->SetName((det_name+"_A").c_str());
    DetElement  sdetB = endcap.clone(det_name+"_B",x_det.id());

    pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
						    Position(0,0,z_pos)));
    pv.addPhysVolID("barrel", 1);
    sdetA.setPlacement(pv);

    pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,M_PI,0),
						    Position(0,0,-z_pos)));
    pv.addPhysVolID("barrel", 2);
    sdetB.setPlacement(pv);

    pv = motherVol.placeVolume(assembly);
    pv.addPhysVolID("system", det_id);
    both_endcaps.setPlacement(pv);
    both_endcaps.add(sdetA);
    both_endcaps.add(sdetB);
    return both_endcaps;
  }
  Volume motherVol = lcdd.pickMotherVolume(endcap);
  pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0),
						 Position(0,0,z_pos)));
  pv.addPhysVolID("system", det_id);
  pv.addPhysVolID("barrel", 1);
  endcap.setPlacement(pv);
  Ref_t(endcap)->SetName(det_name.c_str());
  return endcap;
}