DD to DD4hep Migration

In order to migrate a sub-detector geometry description from DD to DD4hep the following steps should be followed:

  • Geometry configuration migration
  • DD Algorithm migration
  • XML files migration

When this is done, you are ready to start a sub-detector geometry builder migration and a sub-detector sensitive volume assignment migration.

Geometry Configuration Example

DD scenario is defined in a python configuration fragment and all XML files listed as follows:

geomXMLFiles = cms.vstring('Geometry/CMSCommonData/data/normal/cmsextent.xml', 

Similar DD4hep scenario is defined in an XML file. Here is a scenario section from MagneticField/GeomBuilder/data/cms-mf-geometry_160812.xml:

 <Include ref='Geometry/CMSCommonData/data/normal/cmsextent.xml'/>
 <Include ref='Geometry/CMSCommonData/data/cms.xml'/>
 <Include ref='DetectorDescription/DDCMS/data/cmsMagneticField.xml'/>
 <Include ref='MagneticField/GeomBuilder/data/MagneticFieldVolumes_160812_1.xml'/>
 <Include ref='Geometry/CMSCommonData/data/materials.xml'/>

DD Algorithm Example

A DD algorithm is a plugin written in C++ to be invoked by an XML parser to place volumes. Here is an example of a linear positioning algorithm: DDLinear

0054 void
0055 DDLinear::initialize( const DDNumericArguments & nArgs,
0056               const DDVectorArguments & vArgs,
0057               const DDMapArguments & ,
0058               const DDStringArguments & sArgs,
0059               const DDStringVectorArguments &  )
0060 {
0061   m_n           = int(nArgs["N"]);
0062   m_startCopyNo = int(nArgs["StartCopyNo"]);
0063   m_incrCopyNo  = int(nArgs["IncrCopyNo"]);
0064   m_theta       = nArgs["Theta"];
0065   m_phi     = nArgs["Phi"];
0066   m_delta       = nArgs["Delta"];
0067   m_base        = vArgs["Base"];

and a corresponding DD4hep algorithm: DDLinear

0013 static long algorithm( Detector& /* description */,
0014                cms::DDParsingContext& ctxt,
0015                xml_h e,
0016                SensitiveDetector& /* sens */)
0017 {
0018   cms::DDNamespace ns( ctxt, e, true );
0019   DDAlgoArguments  args( ctxt, e );
0021   int            n           = args.value<int>("N");
0022   int            startCopyNo = args.find("StartCopyNo") ? args.value<int>("StartCopyNo") : 1;
0023   int            incrCopyNo  = args.find("IncrCopyNo") ? args.value<int>("IncrCopyNo") : 1;
0024   double         theta       = args.find("Theta") ? args.value<double>("Theta") : 0.;
0025   double         phi         = args.find("Phi") ? args.value<double>("Phi") : 0.;
0026   double         delta       = args.find("Delta") ? args.value<double>("Delta") : 0.;
0027   vector<double> base        = args.value<vector<double> >("Base");
0028   Volume         mother      = ns.volume(args.parentName());
0029   Volume         child       = ns.volume(args.value<string>("ChildName"));
0030   int            copy        = startCopyNo;

How to Access Detector Description

cmsRun configuration should include a DDDetectorESProducer:

process.DDDetectorESProducer = cms.ESSource("DDDetectorESProducer",
                                            confGeomXMLFiles = cms.FileInPath('DetectorDescription/DDCMS/data/cms-2015-muon-geometry.xml'),
                                            appendToDataLabel = cms.string('CMS')

In an analyzer or ES producer it can be accessed as follows:

#include "Geometry/Records/interface/GeometryFileRcd.h"
#include "DetectorDescription/DDCMS/interface/DDDetector.h"
ESTransientHandle<DDDetector> det;
iEventSetup.get<GeometryFileRcd>().get(m_tag.module(), det);

Here is an example https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/plugins/test/DDTestDumpGeometry.cc and its python configuration https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/test/python/testMuonGeometry.py

How to Access Vector Parameters

#include "Geometry/Records/interface/DDVectorRegistryRcd.h"
#include "DetectorDescription/DDCMS/interface/DDVectorRegistry.h"
ESTransientHandle<DDVectorRegistry> registry;
iEventSetup.get<DDVectorRegistryRcd>().get(m_tag.module(), registry);

Here is an example: https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/plugins/test/DDTestVectors.cc and its python configuration: https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/test/python/testDDVectors.py

How to Access All SpecPars

#include "Geometry/Records/interface/DDSpecParRegistryRcd.h"
#include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h"
ESTransientHandle<DDSpecParRegistry> registry;
iEventSetup.get<DDSpecParRegistryRcd>().get(m_tag.module(), registry);

Here is an example [https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/plugins/test/DDTestSpecPars.cc][https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/plugins/test/DDTestSpecPars.cc]] and its configuration https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/test/python/testDDSpecPars.py

How to Filter SpecPars

Assume one needs to access only specific attributes in SpecPars where m_attribute and m_value are defined in the configuration file:

process.test = cms.EDAnalyzer("DDTestSpecParsFilter",
                              DDDetector = cms.ESInputTag('MUON'),
                              attribute = cms.untracked.string('MuStructure'),
                              value = cms.untracked.string('MuonBarrelDT')

Here is how to get them from DDSpecParRegistry:

DDSpecParRefs myReg;
registry->filter(myReg, m_attribute, m_value);

Here is a complete example https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/plugins/test/DDTestSpecParsFilter.cc and its configuration https://cmssdt.cern.ch/lxr/source/DetectorDescription/DDCMS/test/python/testDDSpecParsFilter.py

How to Navigate FilteredView using SpecPars

  • firstChild - navigates to a child which name is defined with // prefix in SpecPar, regex selection is applied - relatively fast, it will continue until all nodes are visited
  • next(int) - native ROOT TGeoIterator - never re-visit the same node, no selection - fast
    • 0 - "first daughter next" behaviour
    • 1 - iteration at the same level only
  • nextSibling, sibling, checkChild - (same as next(1)) regex selection applied, extra functions (collecting copy offsets, etc.)
  • parent, up, down - supplement the above and allow to switch between a one level to a depth navigation

Geometry Builder Migration

To migrate an XXX sub-detector geometry builder, please, create a dd4hep sub-directory under plugins directory and place all related classes(*) there:


In plugins/BuildFile.xml, please, add a rule to build a separate plugin:

<library name="DD4hep_XXXGeometryPlugins" file="dd4hep/*.cc">
   <use name="DetectorDescription/DDCMS"/>
   <use name="Geometry/XXXGeometry"/>
   <use name="dd4hep"/>
   <lib name="Geom"/>
   <flags EDM_PLUGIN="1"/>

(*) all classes which are accessing DDCompactView.

Geometry Builder Validation

Validation of the migrated code should be added as a unit test. The DT Geometry Builder provides a good example. Geometry/​DTGeometryBuilder/​test/runTest.sh is the unit test, and it calls Geometry/​DTGeometryBuilder/​test/​python/validateDTGeometry_cfg.py and Geometry/​DTGeometryBuilder/​plugins/DTGeometryValidate.cc to perform the validation.

DT Geometry Builder


See a complete example

DD4hep Documentation

About DD4hep

DD4hep Manual

DD4hep Reference Guide

Names and Namespaces


Solid Shapes

cms::DDNamespace ns(ctxt,e,true);
ns.addSolid(name, Box(1,1,1));


Rotations and Translations



Includes migration example for DDRotation, DDSplit, DDName, DDCompactView
Migrated to




There are test configurations in DetectorDescription/DDCMS/test/python/ directory which can be run as follows:

cmsRun DetectorDescription/DDCMS/test/python/testDDAngularAlgorithm.py 

Most of the tests produce a geometry root file which can be viewed as follows:

cmsShow -c $CMSSW_RELEASE_BASE/src/Fireworks/Core/macros/simGeo.fwc --tgeo-name=TestAngular --sim-geom-file cmsDD4HepGeom.root
Note: a default configuration background is black.

TestAngular is a name of a TGeoManager in the file. This name is defined in the configuration file:

process.testDump = cms.EDAnalyzer("DDTestDumpFile",
                                  DDDetector = cms.ESInputTag('TestAngular')


On lxplus:
cmsRun $CMSSW_BASE/src/Fireworks/Geometry/python/dumpSimGeometry_cfg.py tag=2017

wget http://cern.ch/cmsshow/cmsShow-10.0.linux.tar.gz 
tar xzf  cmsShow-10.0.linux.tar.gz 
cd  cmsShow-10.0
scp xxx@lxplus.cern.ch:~/CMSSW_10_1_5/src/Fireworks/Geometry/python/cmsSimGeom-2017.root
ln cms/fwlite/CMSSW_10_0_0_FWLITE/src/Fireworks/Core/macros/simGeo.fwc .
./cmsShow -c simGeo.fwc --sim-geom-file "cmsSimGeom-2017.root"

Documents, Discussions and Presentations


-- IannaOsborne - 2018-07-09

Edit | Attach | Watch | Print version | History: r11 < r10 < r9 < r8 < r7 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r11 - 2020-09-15 - IannaOsborne
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    CMSPublic All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback