void Installer<UserData>::install(DetElement component, PlacedVolume pv)   {
  Volume comp_vol = pv.volume();
  if ( comp_vol.isSensitive() )  {  
    Volume mod_vol = parentVolume(component);
    DD4hep::Geometry::PolyhedraRegular comp_shape(comp_vol.solid()), mod_shape(mod_vol.solid());

    if ( !comp_shape.isValid() || !mod_shape.isValid() )   {
      invalidInstaller("Components and/or modules are not Trapezoid -- invalid shapes");
    }
    else if ( !handleUsingCache(component,comp_vol) )  {
      DetElement par = component.parent();
      const TGeoHMatrix& m = par.worldTransformation();
      double dz = m.GetTranslation()[2];
      const double* trans = placementTranslation(component);
      double half_mod_thickness  = (mod_shape->GetZ(1)-mod_shape->GetZ(0))/2.0;
      double half_comp_thickness = (comp_shape->GetZ(1)-comp_shape->GetZ(0))/2.0;
      double si_position         = trans[2]+half_mod_thickness;
      double outer_thickness = half_mod_thickness - si_position;
      double inner_thickness = half_mod_thickness + si_position;
      Vector3D u(1.,0.,0.), v(0.,1.,0.), n(0.,0.,1.), o(100.,100.,0.);
      std::cout << " Module:    " << mod_shape.toString() << std::endl;
      std::cout << " Component: " << comp_shape.toString() << std::endl;
      std::cout << "dz:" << dz << " Si-pos:" << si_position 
                << " Mod-thickness:" << half_mod_thickness 
                << " Comp-thickness:" << half_comp_thickness 
                << std::endl;
      VolPlane surf(comp_vol,Type(Type::Sensitive,Type::Measurement1D),
                    inner_thickness, outer_thickness, u, v, n, o);
      addSurface(component,surf);
    }
  }
}
static void placeStaves(DetElement&   parent,
			DetElement&   stave,
			double        rmin, 
			int           numsides, 
			double        total_thickness, 
			Volume        envelopeVolume, 
			double        innerAngle, 
			Volume        sectVolume)
{
  double innerRotation    = innerAngle;
  double offsetRotation   = -innerRotation / 2;
  double sectCenterRadius = rmin + total_thickness / 2;
  double rotX =  M_PI / 2;
  double rotY = -offsetRotation;
  double posX = -sectCenterRadius  * std::sin(rotY);
  double posY =  sectCenterRadius  * std::cos(rotY);

  for (int module = 1; module <= numsides; ++module)  {
    DetElement det  = module>1 ? stave.clone(_toString(module,"stave%d")) : stave;
    PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Transform3D(RotationZYX(0,rotY,rotX),
									Translation3D(-posX,-posY,0)));
    // Not a valid volID: pv.addPhysVolID("stave", 0);
    pv.addPhysVolID("module",module);
    det.setPlacement(pv);
    parent.add(det);
    rotY -=  innerRotation;
    posX  = -sectCenterRadius * std::sin(rotY);
    posY  =  sectCenterRadius * std::cos(rotY);
  }
}
Exemple #3
0
/// Compute the survey to-world transformation from the detector element placement with respect to the survey constants
void DD4hep::Alignments::AlignmentTools::computeSurvey(Alignment alignment)
{
    Alignment::Object* a = alignment.ptr();
    DetElement parent = a->detector.parent();
    MaskManipulator mask(a->flag);

    if ( parent.isValid() )  {
        DetectorTools::PlacementPath path;
        DetectorTools::placementPath(parent, a->detector, path);

        // TODO: need to take survey corrections into account!

        for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i)  {
            const PlacedVolume& p = path[i];
            a->detectorTrafo.MultiplyLeft(p->GetMatrix());
        }
        a->worldTrafo = parent.survey()->worldTrafo;
        a->worldTrafo.MultiplyLeft(&a->detectorTrafo);
        a->trToWorld  = Geometry::_transform(&a->worldTrafo);
        a->placement = a->detector.placement();
    }
    mask.set(AlignmentData::SURVEY);
    //mask.clear(AlignmentData::INVALID|AlignmentData::DIRTY);
    //mask.set(AlignmentData::VALID|AlignmentData::IDEAL);
}
Exemple #4
0
/// Find a detector element by it's system ID
DetElement LCDDHelper::detectorByID(int id)  const    {
  const LCDD::HandleMap& dets = ptr()->detectors();
  for(LCDD::HandleMap::const_iterator i=dets.begin(); i!=dets.end(); ++i)   {
    DetElement de = (*i).second;
    if ( de.id() == id ) return de;
  }
  return DetElement(0);
}
Exemple #5
0
/*
 * Returns the closest detector element in the hierarchy for a given global position
 */
DetElement IDDecoder::detectorElement(const Position& pos) const {
	DetElement world = Geometry::LCDD::getInstance().world();
	DetElement det = getClosestDaughter(world, pos);
	if (not det.isValid()) {
		throw invalid_position("DD4hep::DDRec::IDDecoder::detectorElement", pos);
	}
	std::cout << det.name() << std::endl;
	return det;
}
Exemple #6
0
 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;
 }
static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)   {
  xml_det_t  x_det     = e;
  xml_dim_t  dim       = x_det.dimensions();
  Material   air       = description.air();
  string     det_name  = x_det.nameStr();
  DetElement sdet       (det_name,x_det.id());
  double     z         = dim.outer_z();
  double     rmin      = dim.inner_r();
  double     r         = rmin;
  int        n         = 0;
  Tube       envelope(rmin,2*rmin,2*z);
  Volume     envelopeVol(det_name+"_envelope",envelope,air);
    
  for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
    xml_comp_t x_layer = c;
    for(int i=0, im=0, repeat=x_layer.repeat(); i<repeat; ++i, im=0)  {
      string layer_name = det_name + _toString(n,"_layer%d");
      double rlayer = r;
      Tube   layer_tub(rmin,rlayer,2*z);
      Volume layer_vol(layer_name,layer_tub,air);
        
      for(xml_coll_t l(x_layer,_U(slice)); l; ++l, ++im)  {
        xml_comp_t x_slice = l;
        double     router = r + x_slice.thickness();
        Material   slice_mat  = description.material(x_slice.materialStr());
        string     slice_name = layer_name + _toString(im,"slice%d");
        Tube       slice_tube(r,router,z*2);
        Volume     slice_vol (slice_name,slice_tube,slice_mat);
          
        if ( x_slice.isSensitive() ) {
          sens.setType("calorimeter");
          slice_vol.setSensitiveDetector(sens);
        }
        r = router;
        slice_vol.setAttributes(description,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
        // Instantiate physical volume
        layer_vol.placeVolume(slice_vol);
      }
      layer_vol.setVisAttributes(description,x_layer.visStr());
      layer_tub.setDimensions(rlayer,r,z*2,0,2*M_PI);
        
      PlacedVolume layer_physvol = envelopeVol.placeVolume(layer_vol);
      layer_physvol.addPhysVolID("layer",n);
      ++n;
    }
  }
  envelope.setDimensions(rmin,r,2*z);
  // Set region of slice
  envelopeVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
    
  PlacedVolume physvol = description.pickMotherVolume(sdet).placeVolume(envelopeVol);
  physvol.addPhysVolID("system",sdet.id()).addPhysVolID(_U(barrel),0);
  sdet.setPlacement(physvol);
  return sdet;
}
Exemple #8
0
/// Access mother volume by detector element
Volume LCDDImp::pickMotherVolume(const DetElement& de) const {
  if ( de.isValid() )   {
    string de_name = de.name();
    HandleMap::const_iterator i = m_motherVolumes.find(de_name);
    if (i == m_motherVolumes.end())   {
      return m_worldVol;
    }
    return (*i).second;
  }
  throw runtime_error("LCDD: Attempt access mother volume of invalid detector [Invalid-handle]");
}
Exemple #9
0
/**
 * Returns the cell ID from the local position in the given volume ID.
 */
CellID IDDecoder::cellIDFromLocal(const Position& local, const VolumeID volID) const {
	double l[3];
	double g[3];
	local.GetCoordinates(l);
	// FIXME: direct lookup of transformations seems to be broken
	//const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volID);
	DetElement det = this->detectorElement(volID);
	const TGeoMatrix& localToGlobal = det.worldTransformation();
	localToGlobal.LocalToMaster(l, g);
	Position global(g[0], g[1], g[2]);
	return this->findReadout(det).segmentation().cellID(local, global, volID);
}
Exemple #10
0
/**
 * Returns the global position from a given cell ID
 */
Position IDDecoder::position(const CellID& cell) const {
	double l[3];
	double g[3];
	DetElement det = this->detectorElement(cell);
	Position local = this->findReadout(det).segmentation().position(cell);
	local.GetCoordinates(l);
	// FIXME: direct lookup of transformations seems to be broken
	//const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(cell);
	const TGeoMatrix& localToGlobal = det.worldTransformation();
	localToGlobal.LocalToMaster(l, g);
	return Position(g[0], g[1], g[2]);
}
Exemple #11
0
 /// Dump method.
 virtual int operator()(DetElement de,int level)  const  {
   const DetElement::Children& children = de.children();
   PlacedVolume place = de.placement();
   char sens = place.volume().isSensitive() ? 'S' : ' ';
   char fmt[128], tmp[32];
   ::snprintf(tmp,sizeof(tmp),"%03d/",level+1);
   ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s #Dau:%%d VolID:%%08X %%c",level+1,2*level+1);
   printout(INFO,"DetectorDump",fmt,"",de.path().c_str(),int(children.size()),
            (unsigned long)de.volumeID(), sens);
   printer.prefix = string(tmp)+de.name();
   (printer)(de, level);
   return 1;
 }
/// Access optical surface data by its identifier
OpticalSurface OpticalSurfaceManager::opticalSurface(DetElement de, const string& nam)  const   {
  if ( de.isValid() )  {
    Object* o = access();
    string  n = de.path() + '#' + nam;
    TGeoOpticalSurface* surf = o->detector.manager().GetOpticalSurface(n.c_str());
    if ( surf ) return surf;
    auto i = o->opticalSurfaces.find(n);
    if ( i != o->opticalSurfaces.end() ) return (*i).second;
    return 0;
  }
  except("OpticalSurface",
         "++ Cannot access OpticalSurface %s without valid detector element!",nam.c_str());
  return OpticalSurface();
}
Exemple #13
0
 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;
 }
/// Register the temporary surface objects with the TGeoManager
void OpticalSurfaceManager::registerSurfaces(DetElement subdetector)    {
  Object* o = access();
  unique_ptr<Object> extension(new Object(o->detector));
  for(auto& s : o->opticalSurfaces)  {
    //string n = s.first.first.path() + '#' + s.first.second;
    //s.second->SetName(n.c_str());
    o->detector.manager().AddOpticalSurface(s.second.ptr());
    extension->opticalSurfaces.insert(s);
  }
  o->opticalSurfaces.clear();
  
  for(auto& s : o->skinSurfaces)  {
    string n = s.first.first.path() + '#' + s.first.second;
    s.second->SetName(n.c_str());
    o->detector.manager().AddSkinSurface(s.second.ptr());
    extension->skinSurfaces.insert(s);
  }
  o->skinSurfaces.clear();
  
  for(auto& s : o->borderSurfaces)  {
    string n = s.first.first.path() + '#' + s.first.second;
    s.second->SetName(n.c_str());
    o->detector.manager().AddBorderSurface(s.second.ptr());
    extension->borderSurfaces.insert(s);
  }
  o->borderSurfaces.clear();
  
  if ( extension->opticalSurfaces.empty() &&
       extension->borderSurfaces.empty()  &&
       extension->skinSurfaces.empty() )   {
    return;
  }
  subdetector.addExtension(new detail::DeleteExtension<Object,Object>(extension.release()));
}
/// Callback to process a single detector element
int ConditionsDependencyCreator::operator()(DetElement de, int)  const  {
  ConditionKey      key(de,"derived_data");
  ConditionKey      target1(de,"derived_data/derived_1");
  ConditionKey      target2(de,"derived_data/derived_2");
  ConditionKey      target3(de,"derived_data/derived_3");
  DependencyBuilder build_1(de, target1.item_key(), call1);
  DependencyBuilder build_2(de, target2.item_key(), call2);
  DependencyBuilder build_3(de, target3.item_key(), call3);
  //DependencyBuilder build_1(de, "derived_data/derived_1", call1);
  //DependencyBuilder build_2(de, "derived_data/derived_2", call2);
  //DependencyBuilder build_3(de, "derived_data/derived_3", call3);

  // Compute the derived stuff
  build_1.add(key);

  build_2.add(key);
  build_2.add(target1);
  
  build_3.add(key);
  build_3.add(target1);
  build_3.add(target2);

  content.addDependency(build_1.release());
  content.addDependency(build_2.release());
  content.addDependency(build_3.release());
  printout(printLevel,"Example","++ Added derived conditions dependencies for %s",de.path().c_str());
  return 1;
}
template<typename T> Condition ConditionsCreator::make_condition(DetElement de, const string& name, T val)  const {
  Condition cond(de.path()+"#"+name, name);
  T& value   = cond.bind<T>();
  value      = val;
  cond->hash = ConditionKey::hashCode(de,name);
  return cond;
}
Exemple #17
0
template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operator()(Nodes::value_type& n) const  {
  Entry& e = *n.second.second;
  bool       check = e.checkOverlap();
  bool       overlap = e.overlapDefined();
  bool       has_matrix  = e.hasMatrix();
  DetElement det = e.detector;
  bool       valid     = det->global_alignment.isValid();
  string     det_placement = det.placementPath();

  if ( !valid && !has_matrix )  {
    cout << "++++ SKIP ALIGNMENT: ++++ " << e.path
         << " DE:" << det_placement
         << " Valid:" << yes_no(valid)
         << " Matrix:" << yes_no(has_matrix) << endl;
    /*    */
    return;
  }

  cout << "++++ " << e.path
       << " DE:" << det_placement
       << " Valid:" << yes_no(valid)
       << " Matrix:" << yes_no(has_matrix)
       << endl;
  /*  */
  // Need to care about optional arguments 'check_overlaps' and 'overlap'
  DetectorAlignment ad(det);
  Alignment alignment;
  bool is_not_volume = e.path == det_placement;
  if ( check && overlap )     {
    alignment = is_not_volume
      ? ad.align(e.transform, e.overlapValue(), e.overlap)
      : ad.align(e.path, e.transform, e.overlapValue(), e.overlap);
  }
  else if ( check )    {
    alignment = is_not_volume
      ? ad.align(e.transform, e.overlapValue())
      : ad.align(e.path, e.transform, e.overlapValue());
  }
  else     {
    alignment = is_not_volume ? ad.align(e.transform) : ad.align(e.path, e.transform);
  }
  if ( alignment.isValid() )  {
    insert(alignment);
    return;
  }
  throw runtime_error("Failed to apply alignment for "+e.path);
}
Exemple #18
0
void local_to_world(const char* com,const DetElement de, const Position& pos,const Position& loc)  {
  Position glob;
  printf("Local to World: Transformation '%s'(%7.3f, %7.3f, %7.3f)->world (Should be: (%7.3f, %7.3f, %7.3f) :\n",
	 com, loc.x(),loc.y(),loc.z(),
	 loc.x()+pos.x(),loc.y()+pos.y(),loc.z()+pos.z() );
  de.localToWorld(loc,glob);
  printCoord(glob,loc);
}
Exemple #19
0
void world_to_local(const char* com,const DetElement de, const Position& pos,const Position& glob)  {
  Position loc;
  printf("World to Local: Transformation '%s'(%7.3f, %7.3f, %7.3f)->world (Should be: (%7.3f, %7.3f, %7.3f) :\n",
	 com, glob.x(),glob.y(),glob.z(),
	 glob.x()-pos.x(),glob.y()-pos.y(),glob.z()-pos.z() );
  de.worldToLocal(glob,loc);
  printCoord(glob,loc);
}
Exemple #20
0
// helper method to get the closest daughter DetElement to the position starting from the given DetElement
DetElement IDDecoder::getClosestDaughter(const DetElement& det, const Position& position) {
	DetElement result;

	// check if we have a shape and see if we are inside
	if (det.volume().isValid() and det.volume().solid().isValid()) {
		double globalPosition[3] = { position.x(), position.y(), position.z() };
		double localPosition[3] = { 0., 0., 0. };
		det.worldTransformation().MasterToLocal(globalPosition, localPosition);
		if (det.volume().solid()->Contains(localPosition)) {
			result = det;
		} else {
			// assuming that any daughter shape would be inside this shape
			return DetElement();
		}
	}

	const DetElement::Children& children = det.children();
	DetElement::Children::const_iterator it = children.begin();
	while (it != children.end()) {
		DetElement daughterDet = getClosestDaughter(it->second, position);
		if (daughterDet.isValid()) {
			result = daughterDet;
			break;
		}
		++it;
	}
	return result;
}
Exemple #21
0
static void* create_printer(Detector& description, int argc,char** argv)  {
  PrintLevel print_level = INFO;
  string prefix = "", name = "";
  int    flags = 0, have_pool = 0, arg_error = false;
  for(int i=0; i<argc && argv[i]; ++i)  {
    if ( 0 == ::strncmp("-prefix",argv[i],4) )
      prefix = argv[++i];
    else if ( 0 == ::strncmp("-name",argv[i],5) )
      name = argv[++i];
    else if ( 0 == ::strncmp("-flags",argv[i],5) )
      flags = ::atol(argv[++i]);
    else if ( 0 == ::strncmp("-pool",argv[i],5) )
      have_pool = 1;
    else if ( 0 == ::strncmp("-print",argv[i],5) )
      print_level = dd4hep::printLevel(argv[++i]);
    else
      arg_error = true;
  }
  if ( arg_error )   {
    /// Help printout describing the basic command line interface
    cout <<
      "Usage: -plugin <name> -arg [-arg]                                             \n"
      "     name:   factory name(s)  DD4hep_ConditionsPrinter,                       \n"
      "                              dd4hep_AlignmentsPrinter                        \n"
      "                              dd4hep_AlignedVolumePrinter                     \n"
      "     -prefix <string>         Printout prefix for user customized output.     \n"
      "     -flags  <number>         Printout processing flags.                      \n"
      "     -pool                    Attach conditions user pool from                \n"
      "                              PluginTester's slice instance attached.       \n\n"
      "     -print <value>           Printout level for the printer object.          \n"
      "\tArguments given: " << arguments(argc,argv) << endl << flush;
    ::exit(EINVAL);
  }
  DetElement world = description.world();
  printout(INFO,"Printer","World=%s [%p]",world.path().c_str(),world.ptr());
  ConditionsSlice* slice = 0;
  if ( have_pool )   {
    PluginTester*    test  = description.extension<PluginTester>();
    slice = test->extension<ConditionsSlice>("ConditionsTestSlice");
  }
  PRINTER* p = (flags) ? new PRINTER(slice, prefix, flags) : new PRINTER(slice, prefix);
  p->printLevel = print_level;
  if ( !name.empty() ) p->name = name;
  return (void*)dynamic_cast<WRAPPER*>(createProcessorWrapper(p));
}
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;
}
Exemple #23
0
/// Compute the ideal/nominal to-world transformation from the detector element placement
void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment)   {
    Alignment::Object* a = alignment.ptr();
    MaskManipulator mask(a->flag);
    DetElement parent = a->detector.parent();
    if ( parent.isValid() )  {
        DetectorTools::PlacementPath path;
        DetectorTools::placementPath(parent, a->detector, path);
        for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i)  {
            const PlacedVolume& p = path[i];
            a->detectorTrafo.MultiplyLeft(p->GetMatrix());
            a->nodes.push_back(p);
        }
        a->worldTrafo = parent.nominal()->worldTrafo;
        a->worldTrafo.MultiplyLeft(&a->detectorTrafo);
        a->trToWorld  = Geometry::_transform(&a->worldTrafo);
        a->placement  = a->detector.placement();
        mask.clear();
        mask.set(AlignmentData::HAVE_PARENT_TRAFO);
        mask.set(AlignmentData::HAVE_WORLD_TRAFO);
        mask.set(AlignmentData::IDEAL);
    }
}
/// Callback to process a single detector element
int ConditionsCreator::operator()(DetElement de, int)  const  {
  Condition temperature = make_condition<double>(de,"temperature",1.222);
  Condition pressure    = make_condition<double>(de,"pressure",888.88);
  Condition derived     = make_condition<int>   (de,"derived_data",100);
  Condition dbl_table   = make_condition<vector<double> >(de,"double_table",{1.,2.,3.,4.,5.,6.,7.,8.,9.});
  Condition int_table   = make_condition<vector<int> >   (de,"int_table",{10,20,30,40,50,60,70,80,90});

  slice.manager.registerUnlocked(pool, temperature);
  slice.manager.registerUnlocked(pool, pressure);
  slice.manager.registerUnlocked(pool, derived);
  slice.manager.registerUnlocked(pool, dbl_table);
  slice.manager.registerUnlocked(pool, int_table);
  printout(printLevel,"Creator","++ Adding manually conditions for %s",de.path().c_str());
  return 5;
}
int DeltaCollector<T>::operator()(DetElement de, int level)  const  {
  if ( de.isValid() )  {
    int count = 0;
    vector<Condition> conditions;
    cond::conditionsCollector(mapping,conditions)(de,level);
    for( auto cond : conditions )   {
      if ( cond->testFlag(Condition::ALIGNMENT_DELTA) )  {
        insert_item(deltas, de, cond.get<Delta>());
        ++count;
      }
    }
    return count;
  }
  except("Alignments","Cannot process alignments of an invalid detector element");
  return 0;  
}
Exemple #26
0
/// Given a detector element, access it's sensitive detector (if the sub-detector is sensitive!)
SensitiveDetector LCDDHelper::sensitiveDetector(DetElement detector) const    {
  for(DetElement par = detector; par.isValid(); par = par.parent())  {
    if ( par.ptr() != ptr()->world().ptr() )  {
      PlacedVolume pv = par.placement();
      if ( pv.isValid() )   {
        const PlacedVolume::VolIDs& ids = pv.volIDs();
        for(PlacedVolume::VolIDs::const_iterator i=ids.begin(); i!=ids.end();++i)  {
          if ( (*i).first == "system" )   {
            return sensitiveDetector(par.name());
          }
        }
      }
    }
  }
  return SensitiveDetector(0);
}
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;
}
Exemple #28
0
/*
 * Returns the volume ID of a given global position
 */
VolumeID IDDecoder::volumeID(const Position& pos) const {
	DetElement det = this->detectorElement(pos);
	return det.volumeID();
}
Exemple #29
0
 /// Dump method.
 virtual int operator()(DetElement de, int)  
 {  return de.hasConditions() ? processor->processElement(de) : 1;    }
static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector sens)  {
    xml_det_t   x_det     = e;
    int         det_id    = x_det.id();
    string      det_name  = x_det.nameStr();
    DetElement    sdet      (det_name,det_id);
    
    // --- create an envelope volume and position it into the world ---------------------
    
    Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  e , sdet ) ;
    dd4hep::xml::setDetectorTypeFlag( e, sdet ) ;
    
    if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
    
    //-----------------------------------------------------------------------------------
    
    xml_dim_t   dim       = x_det.dimensions();
    Material    air       = theDetector.air();
    int         nsides_inner = dim.nsides_inner();
    int         nsides_outer = dim.nsides_outer();
    double      rmin      = dim.rmin();
    double      rmax      = dim.rmax(); /// FIXME: IS THIS RIGHT?
    double      zmin      = dim.zmin();
    
    double       rcutout   = dim.hasAttr(_U(rmin2)) ? dim.rmin2() : 0.;
    double       zcutout   = dim.hasAttr(_U(z2)) ? dim.z2() : 0.;
    
    Layering    layering(x_det);
    double      totalThickness = layering.totalThickness();
    Readout readout = sens.readout();
    Segmentation seg = readout.segmentation();
    
    std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); //Assume uniform cell sizes, provide dummy cellID
    double cell_sizeX      = cellSizeVector[0];
    double cell_sizeY      = cellSizeVector[1];
    
    
    PolyhedraRegular polyVolume(nsides_outer,rmin,rmax,totalThickness);
    Volume      endcapVol("endcap",polyVolume,air);
    
    
    if(zcutout >0. || rcutout > 0.){
        PolyhedraRegular cutoutPolyVolume(nsides_inner,0,rmin+rcutout,zcutout);
        Position cutoutPos(0,0,(zcutout-totalThickness)/2.0);
        std::cout<<"Cutout z width will be  "<<zcutout<<std::endl; 
        endcapVol=Volume("endcap",SubtractionSolid(polyVolume,cutoutPolyVolume,cutoutPos),air);
        
    }
    
    
    DetElement  endcapA(sdet,"endcap",det_id);
    Ref_t(endcapA)->SetName((det_name+"_A").c_str());
    
    int layer_num = 0;
    int layerType   = 0;
    double layerZ   = -totalThickness/2;
    
    //Create caloData object to extend driver with data required for reconstruction
    LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
    caloData->layoutType = LayeredCalorimeterData::EndcapLayout ;
    caloData->inner_symmetry = nsides_inner;
    caloData->outer_symmetry = nsides_outer; 
    
    /** NOTE: phi0=0 means lower face flat parallel to experimental floor
     *  This is achieved by rotating the modules with respect to the envelope
     *  which is assumed to be a Polyhedron and has its axes rotated with respect
     *  to the world by 180/nsides. In any other case (e.g. if you want to have
     *  a tip of the calorimeter touching the ground) this value needs to be computed
     */
    
    caloData->inner_phi0 = 0.; 
    caloData->outer_phi0 = 0.; 
    caloData->gap0 = 0.; //FIXME
    caloData->gap1 = 0.; //FIXME
    caloData->gap2 = 0.; //FIXME  
    
    
    /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
    caloData->extent[0] = rmin ;
    caloData->extent[1] = rmax ; ///FIXME: CHECK WHAT IS NEEDED (EXSCRIBED?)
    caloData->extent[2] = zmin ;
    caloData->extent[3] = zmin + totalThickness;
    
    endcapVol.setAttributes(theDetector,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           layer_thick  = layering.layer(layer_num)->thickness();
        string           layer_type_name   = _toString(layerType,"layerType%d");
        int              layer_repeat = x_layer.repeat();
        double            layer_rcutout = x_layer.hasAttr(_U(gap)) ? x_layer.gap() : 0;
        
        std::cout<<"Number of layers in group "<<layerType<<" : "<<layer_repeat<<std::endl; 
        
        Volume           layer_vol(layer_type_name,PolyhedraRegular(nsides_outer,rmin+layer_rcutout,rmax,layer_thick),air);
        
        int slice_num = 0;
        double sliceZ = -layer_thick/2;
        
        //Create a caloLayer struct for thiss layer type to store copies of in the parent struct
        LayeredCalorimeterData::Layer caloLayer ;
        caloLayer.cellSize0 = cell_sizeX;
        caloLayer.cellSize1 = cell_sizeY; 
        
        double nRadiationLengths=0.;
        double nInteractionLengths=0.;
        double thickness_sum=0;
        
        for(xml_coll_t s(x_layer,_U(slice)); s; ++s)  {
            xml_comp_t x_slice = s;
            string     slice_name  = _toString(slice_num,"slice%d");
            double     slice_thickness = x_slice.thickness();
            Material   slice_material   = theDetector.material(x_slice.materialStr());
            Volume     slice_vol(slice_name,PolyhedraRegular(nsides_outer,rmin+layer_rcutout,rmax,slice_thickness),slice_material);
            
            slice_vol.setVisAttributes(theDetector.visAttributes(x_slice.visStr()));
            sliceZ += slice_thickness/2;
            layer_vol.placeVolume(slice_vol,Position(0,0,sliceZ));
            
            nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
            nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
            thickness_sum += slice_thickness/2;
            
            if ( x_slice.isSensitive() )  {
                sens.setType("calorimeter");
                slice_vol.setSensitiveDetector(sens);
                
#if DD4HEP_VERSION_GE( 0, 15 )
                //Store "inner" quantities
                caloLayer.inner_nRadiationLengths = nRadiationLengths;
                caloLayer.inner_nInteractionLengths = nInteractionLengths;
                caloLayer.inner_thickness = thickness_sum;
                //Store scintillator thickness
                caloLayer.sensitive_thickness = slice_thickness;
#endif
                //Reset counters to measure "outside" quantitites
                nRadiationLengths=0.;
                nInteractionLengths=0.;
                thickness_sum = 0.;
            } 
            
            nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
            nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
            thickness_sum += slice_thickness/2;

            sliceZ += slice_thickness/2;
            slice_num++;
        }
        
#if DD4HEP_VERSION_GE( 0, 15 )
        //Store "outer" quantities
        caloLayer.outer_nRadiationLengths = nRadiationLengths;
        caloLayer.outer_nInteractionLengths = nInteractionLengths;
        caloLayer.outer_thickness = thickness_sum;
#endif        
        layer_vol.setVisAttributes(theDetector.visAttributes(x_layer.visStr()));
        
        
        if ( layer_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
        
        for(int j=0; j<layer_repeat; ++j) {
            string phys_lay = _toString(layer_num,"layer%d");
            
            //The rest of the data is constant; only the distance needs to be updated  
            //Store the position up to the inner face of the layer
            caloLayer.distance = zmin +  totalThickness/2 + layerZ;
            //Push back a copy to the caloData structure
            caloData->layers.push_back( caloLayer );
            
            layerZ += layer_thick/2;
            DetElement    layer_elt(endcapA, phys_lay, layer_num);
            PlacedVolume  pv = endcapVol.placeVolume(layer_vol,Position(0,0,layerZ));
            pv.addPhysVolID("layer", layer_num);
            layer_elt.setPlacement(pv);
            
            layerZ += layer_thick/2;
            ++layer_num;
        }
        ++layerType;
    }
    
    double z_pos = zmin+totalThickness/2;
    PlacedVolume pv;
    // Reflect it.
    
    DetElement  endcapB = endcapA.clone(det_name+"_B",x_det.id());
    
    //Removed rotations to align with envelope
    //NOTE: If the envelope is not a polyhedron (eg. if you use a tube)
    //you may need to rotate so the axes match
    
    pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,0,0),
                                                    Position(0,0,z_pos)));
    pv.addPhysVolID("side", 1);
    endcapA.setPlacement(pv);
    
    //Removed rotations
    pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,M_PI,0),
                                                    Position(0,0,-z_pos)));
    pv.addPhysVolID("side", 2);
    endcapB.setPlacement(pv);
    
    sdet.add(endcapB);
    
    sdet.addExtension< LayeredCalorimeterData >( caloData ) ;
    
    return sdet;
    
}