diff --git a/CondCore/GeometryPlugins/plugins/plugin.cc b/CondCore/GeometryPlugins/plugins/plugin.cc
index 7bda52b85d4ab..9f13d8ef8052f 100644
--- a/CondCore/GeometryPlugins/plugins/plugin.cc
+++ b/CondCore/GeometryPlugins/plugins/plugin.cc
@@ -22,6 +22,7 @@
#include "Geometry/Records/interface/CSCRecoGeometryRcd.h"
#include "Geometry/Records/interface/DTRecoGeometryRcd.h"
#include "Geometry/Records/interface/RPCRecoGeometryRcd.h"
+#include "Geometry/Records/interface/GEMRecoGeometryRcd.h"
#include "CondFormats/GeometryObjects/interface/PGeometricDetExtra.h"
#include "Geometry/Records/interface/PGeometricDetExtraRcd.h"
@@ -40,3 +41,4 @@ REGISTER_PLUGIN(CSCRecoDigiParametersRcd,CSCRecoDigiParameters);
REGISTER_PLUGIN(CSCRecoGeometryRcd,RecoIdealGeometry);
REGISTER_PLUGIN(DTRecoGeometryRcd,RecoIdealGeometry);
REGISTER_PLUGIN(RPCRecoGeometryRcd,RecoIdealGeometry);
+REGISTER_PLUGIN(GEMRecoGeometryRcd,RecoIdealGeometry);
diff --git a/CondTools/Geometry/test/geSingleBigFile.xml b/CondTools/Geometry/test/geSingleBigFile.xml
new file mode 100644
index 0000000000000..b7a6a671a8ec4
--- /dev/null
+++ b/CondTools/Geometry/test/geSingleBigFile.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/CondTools/Geometry/test/writehelpers/GEMRECO_Geometry.txt b/CondTools/Geometry/test/writehelpers/GEMRECO_Geometry.txt
new file mode 100644
index 0000000000000..954f0be61c633
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/GEMRECO_Geometry.txt
@@ -0,0 +1,12 @@
+{
+ "destinationDatabase": "oracle://cms_orcoff_prep/CMS_COND_GEOMETRY",
+ "destinationTags": {
+ "GEMRECO_Geometry_TagXX": {
+ "dependencies": {},
+ "synchronizeTo": "offline"
+ }
+ },
+ "inputTag": "GEMRECO_Geometry_TagXX",
+ "since": null,
+ "userText": "GEM geometry payload config TagXX"
+}
diff --git a/CondTools/Geometry/test/writehelpers/GeometryFileExtended2019.txt b/CondTools/Geometry/test/writehelpers/GeometryFileExtended2019.txt
new file mode 100644
index 0000000000000..d0bb36b64851d
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/GeometryFileExtended2019.txt
@@ -0,0 +1,12 @@
+{
+ "destinationDatabase": "oracle://cms_orcoff_prep/CMS_COND_GEOMETRY",
+ "destinationTags": {
+ "XMLFILE_Geometry_TagXX_Extended2019_mc": {
+ "dependencies": {},
+ "synchronizeTo": "offline"
+ }
+ },
+ "inputTag": "XMLFILE_Geometry_TagXX_Extended2019_mc",
+ "since": null,
+ "userText": "Geometry payload for Full DDD XML Extended 2019 config TagXX"
+}
diff --git a/CondTools/Geometry/test/writehelpers/HCALRECO_Geometry.txt b/CondTools/Geometry/test/writehelpers/HCALRECO_Geometry.txt
new file mode 100644
index 0000000000000..0ae3224251753
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/HCALRECO_Geometry.txt
@@ -0,0 +1,12 @@
+{
+ "destinationDatabase": "oracle://cms_orcoff_prep/CMS_COND_GEOMETRY_000",
+ "destinationTags": {
+ "HCALRECO_Geometry_TagXX": {
+ "dependencies": {},
+ "synchronizeTo": "offline"
+ }
+ },
+ "inputTag": "HCALRECO_Geometry_TagXX",
+ "since": null,
+ "userText": "HCAL reco geometry with dense index TagXX"
+}
diff --git a/CondTools/Geometry/test/writehelpers/createExtended2019Payloads.sh b/CondTools/Geometry/test/writehelpers/createExtended2019Payloads.sh
new file mode 100755
index 0000000000000..6323981f3b542
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/createExtended2019Payloads.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+
+if [ $# -ne 1 ]
+then
+ echo Error: createExtended2019Payloads.sh requires exactly one argument which is the tag
+ exit 1
+fi
+mytag=$1
+echo ${mytag}
+
+# Set the tag in all the scripts and the metadata text files
+sed -i {s/TagXX/${mytag}/g} *.py
+sed -i {s/TagXX/${mytag}/g} *.txt
+sed -i {s/TagXX/${mytag}/g} splitExtended2019Database.sh
+
+# First read in the little XML files and create the
+# large XML file for the Phase1_R30F12_HCal Ideal scenario.
+# Input cff Output file
+# GeometryExtended2019_cff geSingleBigFile.xml
+cmsRun geometryExtended2019_xmlwriter.py
+
+# Now convert the content of the large XML file into
+# a "blob" and write it to the database.
+# Also reads in the little XML files again and fills
+# the DDCompactView. From the DDCompactView the
+# reco parts of the database are also filled.
+cmsRun geometryExtended2019_writer.py
+
+# All the database objects were written into one database
+# (myfile.db) in the steps above. Extract the different
+# pieces into separate database files. These are the payloads
+# that get uploaded to the dropbox. There is one for each tag
+./splitExtended2019Database.sh
diff --git a/CondTools/Geometry/test/writehelpers/createPayloads.sh b/CondTools/Geometry/test/writehelpers/createPayloads.sh
index 9a075c3f680fb..6f7544b6d9a56 100755
--- a/CondTools/Geometry/test/writehelpers/createPayloads.sh
+++ b/CondTools/Geometry/test/writehelpers/createPayloads.sh
@@ -89,6 +89,10 @@ sed -i '{s/Services30Percent/HFLibraryNoCastor/g}' geometryxmlwriter.py
sed -i '{s/\/geservices30percent/\/gehflibrarynocastor/g}' geometryxmlwriter.py
cmsRun geometryxmlwriter.py
+sed -i '{s/HFLibraryNoCastor/ZeroMaterial/g}' geometryxmlwriter.py
+sed -i '{s/\/gehflibrarynocastor/\/zeromaterial/g}' geometryxmlwriter.py
+cmsRun geometryxmlwriter.py
+
# Read the one big XML file and output a record to the
# database with the an identifying tag
# This is repeated several times below. The sed commands
@@ -151,6 +155,10 @@ sed -i '{s/Services30Percent/HFLibraryNoCastor/g}' xmlgeometrywriter.py
sed -i '{s/\/geservices30percent/\/gehflibrarynocastor/g}' xmlgeometrywriter.py
cmsRun xmlgeometrywriter.py
+sed -i '{s/HFLibraryNoCastor/ZeroMaterial/g}' xmlgeometrywriter.py
+sed -i '{s/\/gehflibrarynocastor/\/zeromaterial/g}' xmlgeometrywriter.py
+cmsRun xmlgeometrywriter.py
+
# All the database objects were written into one database
# (myfile.db) in the steps above. Extract the different
# pieces into separate database files. These are the payloads
diff --git a/CondTools/Geometry/test/writehelpers/geometryExtended2019_writer.py b/CondTools/Geometry/test/writehelpers/geometryExtended2019_writer.py
new file mode 100644
index 0000000000000..99360f3ecab30
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/geometryExtended2019_writer.py
@@ -0,0 +1,76 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("GeometryWriter")
+process.load("CondCore.DBCommon.CondDBCommon_cfi")
+
+# This will read all the little XML files and from
+# that fill the DDCompactView. The modules that fill
+# the reco part of the database need the DDCompactView.
+process.load('Configuration.Geometry.GeometryExtended2019_cff')
+process.load('Geometry.MuonNumbering.muonNumberingInitialization_cfi')
+process.load('Geometry.CaloEventSetup.CaloGeometryDBWriter_cfi')
+
+import Geometry.HcalEventSetup.hcalSLHCTopologyConstants_cfi as hcalTopologyConstants_cfi
+process.hcalTopologyIdeal.hcalTopologyConstants = cms.PSet(hcalTopologyConstants_cfi.hcalTopologyConstants)
+
+process.source = cms.Source("EmptyIOVSource",
+ lastValue = cms.uint64(1),
+ timetype = cms.string('runnumber'),
+ firstValue = cms.uint64(1),
+ interval = cms.uint64(1)
+ )
+
+# This reads the big XML file and the only way to fill the
+# nonreco part of the database is to read this file. It
+# somewhat duplicates the information read from the little
+# XML files, but there is no way to directly build the
+# DDCompactView from this.
+process.XMLGeometryWriter = cms.EDAnalyzer("XMLGeometryBuilder",
+ XMLFileName = cms.untracked.string("./geSingleBigFile.xml"),
+ ZIP = cms.untracked.bool(True)
+ )
+process.TrackerGeometricDetExtraESModule = cms.ESProducer( "TrackerGeometricDetExtraESModule",
+ fromDDD = cms.bool( True ),
+ )
+
+process.TrackerGeometryWriter = cms.EDAnalyzer("PGeometricDetBuilder")
+process.TrackerGeometryExtraWriter = cms.EDAnalyzer("PGeometricDetExtraBuilder")
+
+process.CaloGeometryWriter = cms.EDAnalyzer("PCaloGeometryBuilder")
+
+process.CSCGeometryWriter = cms.EDAnalyzer("CSCRecoIdealDBLoader")
+
+process.DTGeometryWriter = cms.EDAnalyzer("DTRecoIdealDBLoader")
+
+process.RPCGeometryWriter = cms.EDAnalyzer("RPCRecoIdealDBLoader")
+
+process.GEMGeometryWriter = cms.EDAnalyzer("GEMRecoIdealDBLoader")
+
+process.CondDBCommon.BlobStreamerName = cms.untracked.string('TBufferBlobStreamingService')
+process.CondDBCommon.timetype = cms.untracked.string('runnumber')
+process.CondDBCommon.connect = cms.string('sqlite_file:myfile.db')
+process.PoolDBOutputService = cms.Service("PoolDBOutputService",
+ process.CondDBCommon,
+ toPut = cms.VPSet(cms.PSet(record = cms.string('GeometryFileRcd'),tag = cms.string('XMLFILE_Geometry_TagXX_Extended2019_mc')),
+ cms.PSet(record = cms.string('IdealGeometryRecord'),tag = cms.string('TKRECO_Geometry_Extended2019_TagXX')),
+ cms.PSet(record = cms.string('PGeometricDetExtraRcd'),tag = cms.string('TKExtra_Geometry_Extended2019_TagXX')),
+ cms.PSet(record = cms.string('PEcalBarrelRcd'), tag = cms.string('EBRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('PEcalEndcapRcd'), tag = cms.string('EERECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('PEcalPreshowerRcd'),tag = cms.string('EPRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('PHcalRcd'), tag = cms.string('HCALRECO_Geometry_Extended2019_TagXX')),
+ cms.PSet(record = cms.string('PCaloTowerRcd'), tag = cms.string('CTRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('PZdcRcd'), tag = cms.string('ZDCRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('PCastorRcd'), tag = cms.string('CASTORRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('CSCRecoGeometryRcd'),tag = cms.string('CSCRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('CSCRecoDigiParametersRcd'),tag = cms.string('CSCRECODIGI_Geometry_TagXX')),
+ cms.PSet(record = cms.string('DTRecoGeometryRcd'),tag = cms.string('DTRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('RPCRecoGeometryRcd'),tag = cms.string('RPCRECO_Geometry_TagXX')),
+ cms.PSet(record = cms.string('GEMRecoGeometryRcd'),tag = cms.string('GEMRECO_Geometry_TagXX'))
+ )
+ )
+
+process.maxEvents = cms.untracked.PSet(
+ input = cms.untracked.int32(1)
+ )
+
+process.p1 = cms.Path(process.XMLGeometryWriter+process.TrackerGeometryWriter+process.TrackerGeometryExtraWriter+process.CaloGeometryWriter+process.CSCGeometryWriter+process.DTGeometryWriter+process.RPCGeometryWriter+process.GEMGeometryWriter)
diff --git a/CondTools/Geometry/test/writehelpers/geometryExtended2019_xmlwriter.py b/CondTools/Geometry/test/writehelpers/geometryExtended2019_xmlwriter.py
new file mode 100644
index 0000000000000..906d941da5844
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/geometryExtended2019_xmlwriter.py
@@ -0,0 +1,25 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("GeometryXMLWriter")
+process.load("CondCore.DBCommon.CondDBCommon_cfi")
+process.load('Configuration.Geometry.GeometryExtended2019_cff')
+
+process.source = cms.Source("EmptyIOVSource",
+ lastValue = cms.uint64(1),
+ timetype = cms.string('runnumber'),
+ firstValue = cms.uint64(1),
+ interval = cms.uint64(1)
+ )
+
+process.BigXMLWriter = cms.EDAnalyzer("OutputDDToDDL",
+ rotNumSeed = cms.int32(0),
+ fileName = cms.untracked.string("./geSingleBigFile.xml")
+ )
+
+
+process.maxEvents = cms.untracked.PSet(
+ input = cms.untracked.int32(1)
+ )
+
+process.p1 = cms.Path(process.BigXMLWriter)
+
diff --git a/CondTools/Geometry/test/writehelpers/mfwriter.py b/CondTools/Geometry/test/writehelpers/mfwriter.py
new file mode 100644
index 0000000000000..e0b3880938185
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/mfwriter.py
@@ -0,0 +1,40 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("MagneticFieldWriter")
+process.load("CondCore.DBCommon.CondDBCommon_cfi")
+
+# This will read all the little XML files and from
+# that fill the DDCompactView. The modules that fill
+# the reco part of the database need the DDCompactView.
+process.load('Configuration.Geometry.MagneticFieldGeometry_cff')
+
+process.source = cms.Source("EmptyIOVSource",
+ lastValue = cms.uint64(1),
+ timetype = cms.string('runnumber'),
+ firstValue = cms.uint64(1),
+ interval = cms.uint64(1)
+ )
+
+# This reads the big XML file and the only way to fill the
+# nonreco part of the database is to read this file. It
+# somewhat duplicates the information read from the little
+# XML files, but there is no way to directly build the
+# DDCompactView from this.
+process.XMLGeometryWriter = cms.EDAnalyzer("XMLGeometryBuilder",
+ XMLFileName = cms.untracked.string("./mfSingleBigFile.xml"),
+ ZIP = cms.untracked.bool(True)
+ )
+
+process.CondDBCommon.BlobStreamerName = cms.untracked.string('TBufferBlobStreamingService')
+process.CondDBCommon.timetype = cms.untracked.string('runnumber')
+process.CondDBCommon.connect = cms.string('sqlite_file:myfile.db')
+process.PoolDBOutputService = cms.Service("PoolDBOutputService",
+ process.CondDBCommon,
+ toPut = cms.VPSet(cms.PSet(record = cms.string('GeometryFileRcd'),tag = cms.string('XMLFILE_MagneticFieldGeometry_TagXX')))
+ )
+
+process.maxEvents = cms.untracked.PSet(
+ input = cms.untracked.int32(1)
+ )
+
+process.p1 = cms.Path(process.XMLGeometryWriter)
diff --git a/CondTools/Geometry/test/writehelpers/mfxmlwriter.py b/CondTools/Geometry/test/writehelpers/mfxmlwriter.py
new file mode 100644
index 0000000000000..d1b7635dddf25
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/mfxmlwriter.py
@@ -0,0 +1,25 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("MagneticFieldXMLWriter")
+process.load("CondCore.DBCommon.CondDBCommon_cfi")
+process.load('Configuration.Geometry.MagneticFieldGeometry_cff')
+
+process.source = cms.Source("EmptyIOVSource",
+ lastValue = cms.uint64(1),
+ timetype = cms.string('runnumber'),
+ firstValue = cms.uint64(1),
+ interval = cms.uint64(1)
+ )
+
+process.BigXMLWriter = cms.EDAnalyzer("OutputMagneticFieldDDToDDL",
+ rotNumSeed = cms.int32(0),
+ fileName = cms.untracked.string("./mfSingleBigFile.xml")
+ )
+
+
+process.maxEvents = cms.untracked.PSet(
+ input = cms.untracked.int32(1)
+ )
+
+process.p1 = cms.Path(process.BigXMLWriter)
+
diff --git a/CondTools/Geometry/test/writehelpers/splitExtended2019Database.sh b/CondTools/Geometry/test/writehelpers/splitExtended2019Database.sh
new file mode 100755
index 0000000000000..cc4b629a89248
--- /dev/null
+++ b/CondTools/Geometry/test/writehelpers/splitExtended2019Database.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:GeometryFileExtended2019.db -D CondFormatsGeometryObjects -t XMLFILE_Geometry_TagXX_Extended2019_mc -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:TKRECO_Geometry.db -D CondFormatsGeometryObjects -t TKRECO_Geometry_Extended2019_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:TKExtra_Geometry.db -D CondFormatsGeometryObjects -t TKExtra_Geometry_Extended2019_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:EBRECO_Geometry.db -D CondFormatsGeometryObjects -t EBRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:EERECO_Geometry.db -D CondFormatsGeometryObjects -t EERECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:EPRECO_Geometry.db -D CondFormatsGeometryObjects -t EPRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:HCALRECO_Geometry.db -D CondFormatsGeometryObjects -t HCALRECO_Geometry_Extended2019_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:CTRECO_Geometry.db -D CondFormatsGeometryObjects -t CTRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:ZDCRECO_Geometry.db -D CondFormatsGeometryObjects -t ZDCRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:CASTORRECO_Geometry.db -D CondFormatsGeometryObjects -t CASTORRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:CSCRECO_Geometry.db -D CondFormatsGeometryObjects -t CSCRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:CSCRECODIGI_Geometry.db -D CondFormatsGeometryObjects -t CSCRECODIGI_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:DTRECO_Geometry.db -D CondFormatsGeometryObjects -t DTRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:RPCRECO_Geometry.db -D CondFormatsGeometryObjects -t RPCRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
+cmscond_export_iov -s sqlite_file:myfile.db -d sqlite_file:GEMRECO_Geometry.db -D CondFormatsGeometryObjects -t GEMRECO_Geometry_TagXX -l sqlite_file:localpopconlog.db
diff --git a/Configuration/Geometry/python/MagneticFieldGeometryDB_cff.py b/Configuration/Geometry/python/MagneticFieldGeometryDB_cff.py
new file mode 100644
index 0000000000000..a73c556aef883
--- /dev/null
+++ b/Configuration/Geometry/python/MagneticFieldGeometryDB_cff.py
@@ -0,0 +1,6 @@
+import FWCore.ParameterSet.Config as cms
+
+#
+# Magnetic Field Geometry master configuration
+#
+from GeometryReaders.XMLIdealGeometryESSource.cmsMagneticFieldGeometryDB_cff import *
diff --git a/Configuration/Geometry/python/MagneticFieldGeometry_cff.py b/Configuration/Geometry/python/MagneticFieldGeometry_cff.py
new file mode 100644
index 0000000000000..a2515d307304c
--- /dev/null
+++ b/Configuration/Geometry/python/MagneticFieldGeometry_cff.py
@@ -0,0 +1,7 @@
+import FWCore.ParameterSet.Config as cms
+
+#
+# Magnetic Field Geometry master configuration
+#
+from Geometry.CMSCommonData.cmsMagneticFieldGeometryXML_cfi import *
+
diff --git a/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.cc b/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.cc
new file mode 100644
index 0000000000000..c54f70f407216
--- /dev/null
+++ b/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.cc
@@ -0,0 +1,252 @@
+#include "OutputMagneticFieldDDToDDL.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+bool
+ddsvaluesCmp::operator() ( const DDsvalues_type& sv1, const DDsvalues_type& sv2 )
+{
+ if( sv1.size() < sv2.size()) return true;
+ if( sv2.size() < sv1.size()) return false;
+ size_t ind = 0;
+ for( ; ind < sv1.size(); ++ind )
+ {
+ if( sv1[ ind ].first < sv2[ ind ].first ) return true;
+ if( sv2[ ind ].first < sv1[ ind ].first ) return false;
+ if( sv1[ ind ].second < sv2[ ind ].second ) return true;
+ if( sv2[ ind ].second < sv1[ ind ].second ) return false;
+ }
+ return false;
+}
+
+OutputMagneticFieldDDToDDL::OutputMagneticFieldDDToDDL( const edm::ParameterSet& iConfig )
+ : m_fname()
+{
+ m_rotNumSeed = iConfig.getParameter( "rotNumSeed" );
+ m_fname = iConfig.getUntrackedParameter( "fileName" );
+ if( m_fname == "" )
+ {
+ m_xos = &std::cout;
+ }
+ else
+ {
+ m_xos = new std::ofstream( m_fname.c_str());
+ }
+
+ ( *m_xos ) << "\n";
+ ( *m_xos ) << "\n";
+ ( *m_xos ) << std::fixed << std::setprecision( 18 );
+}
+
+OutputMagneticFieldDDToDDL::~OutputMagneticFieldDDToDDL()
+{
+ ( *m_xos ) << "\n";
+ ( *m_xos ) << std::endl;
+ m_xos->flush();
+}
+
+void
+OutputMagneticFieldDDToDDL::beginRun( const edm::Run&, edm::EventSetup const& es )
+{
+ edm::LogInfo( "OutputMagneticFieldDDToDDL" ) << "OutputMagneticFieldDDToDDL::beginRun";
+
+ edm::ESTransientHandle pDD;
+ es.get().get( pDD );
+
+ DDCompactView::DDCompactView::graph_type gra = pDD->graph();
+
+ // Temporary stores:
+ std::set lpStore;
+ std::set matStore;
+ std::set solStore;
+
+ std::map, ddsvaluesCmp > specStore;
+ std::set rotStore;
+
+ DDCoreToDDXMLOutput out;
+
+ std::string rn = m_fname;
+ size_t foundLastDot= rn.find_last_of('.');
+ size_t foundLastSlash= rn.find_last_of('/');
+
+ if( foundLastSlash > foundLastDot && foundLastSlash != std::string::npos )
+ {
+ edm::LogError( "OutputMagneticFieldDDToDDL" ) << "What? last . before last / in path for filename... this should die...";
+ }
+ if( foundLastDot != std::string::npos && foundLastSlash != std::string::npos )
+ {
+ out.ns_ = rn.substr( foundLastSlash, foundLastDot );
+ }
+ else if ( foundLastDot != std::string::npos )
+ {
+ out.ns_ = rn.substr(0, foundLastDot);
+ }
+ else
+ {
+ edm::LogError( "OutputMagneticFieldDDToDDL" ) << "What? no file name? Attempt at namespace =\"" << out.ns_ << "\" filename was " << m_fname;
+ }
+
+ edm::LogInfo( "OutputMagneticFieldDDToDDL" ) << "m_fname=" << m_fname << " namespace = " << out.ns_;
+ std::string ns_ = out.ns_;
+
+ ( *m_xos ) << std::fixed << std::setprecision( 18 );
+
+ typedef DDCompactView::graph_type::const_adj_iterator adjl_iterator;
+
+ adjl_iterator git = gra.begin();
+ adjl_iterator gend = gra.end();
+
+ DDCompactView::graph_type::index_type i=0;
+ ( *m_xos) << "\n";
+ git = gra.begin();
+ for( ; git != gend; ++git )
+ {
+ const DDLogicalPart & ddLP = gra.nodeData( git );
+ if( lpStore.find(ddLP) != lpStore.end())
+ {
+ addToSpecStore( ddLP, specStore );
+ }
+ lpStore.insert( ddLP );
+ addToMatStore( ddLP.material(), matStore );
+ addToSolStore( ddLP.solid(), solStore, rotStore );
+ ++i;
+ if( git->size())
+ {
+ // ask for children of ddLP
+ DDCompactView::graph_type::edge_list::const_iterator cit = git->begin();
+ DDCompactView::graph_type::edge_list::const_iterator cend = git->end();
+ for( ; cit != cend; ++cit )
+ {
+ const DDLogicalPart & ddcurLP = gra.nodeData( cit->first );
+ if( lpStore.find(ddcurLP) != lpStore.end())
+ {
+ addToSpecStore( ddcurLP, specStore );
+ }
+ lpStore.insert( ddcurLP );
+ addToMatStore( ddcurLP.material(), matStore );
+ addToSolStore( ddcurLP.solid(), solStore, rotStore );
+ rotStore.insert( gra.edgeData( cit->second )->rot_ );
+ out.position( ddLP, ddcurLP, gra.edgeData( cit->second ), m_rotNumSeed, *m_xos );
+ } // iterate over children
+ } // if (children)
+ } // iterate over graph nodes
+
+ ( *m_xos ) << "\n";
+
+ ( *m_xos ) << std::scientific << std::setprecision( 18 );
+ std::set::const_iterator it( matStore.begin()), ed( matStore.end());
+ ( *m_xos) << "\n";
+ for( ; it != ed; ++it )
+ {
+ if( ! it->isDefined().second ) continue;
+ out.material( *it, *m_xos );
+ }
+ ( *m_xos ) << "\n";
+
+ ( *m_xos ) << "\n";
+ ( *m_xos ) << std::fixed << std::setprecision( 18 );
+ std::set::iterator rit( rotStore.begin()), red( rotStore.end());
+ for( ; rit != red; ++rit )
+ {
+ if( ! rit->isDefined().second ) continue;
+ if( rit->toString() != ":" )
+ {
+ DDRotation r( *rit );
+ out.rotation( r, *m_xos );
+ }
+ }
+ ( *m_xos ) << "\n";
+
+ ( *m_xos ) << std::fixed << std::setprecision( 18 );
+ std::set::const_iterator sit( solStore.begin()), sed( solStore.end());
+ ( *m_xos ) << "\n";
+ for( ; sit != sed; ++sit)
+ {
+ if( ! sit->isDefined().second ) continue;
+ out.solid( *sit, *m_xos );
+ }
+ ( *m_xos ) << "\n";
+
+ std::set::iterator lpit( lpStore.begin()), lped( lpStore.end());
+ ( *m_xos ) << "\n";
+ for( ; lpit != lped; ++lpit )
+ {
+ if( ! lpit->isDefined().first ) continue;
+ const DDLogicalPart & lp = *lpit;
+ out.logicalPart( lp, *m_xos );
+ }
+ ( *m_xos ) << "\n";
+
+ ( *m_xos ) << std::fixed << std::setprecision( 18 );
+ std::map >::const_iterator mit( specStore.begin()), mend( specStore.end());
+ ( *m_xos ) << "\n";
+ for( ; mit != mend; ++mit )
+ {
+ out.specpar( *mit, *m_xos );
+ }
+ ( *m_xos ) << "\n";
+}
+
+void
+OutputMagneticFieldDDToDDL::addToMatStore( const DDMaterial& mat, std::set & matStore )
+{
+ matStore.insert( mat );
+ if( mat.noOfConstituents() != 0 )
+ {
+ DDMaterial::FractionV::value_type frac;
+ int findex( 0 );
+ while( findex < mat.noOfConstituents())
+ {
+ if( matStore.find( mat.constituent( findex ).first ) == matStore.end())
+ {
+ addToMatStore( mat.constituent( findex ).first, matStore );
+ }
+ ++findex;
+ }
+ }
+}
+
+void
+OutputMagneticFieldDDToDDL::addToSolStore( const DDSolid& sol, std::set & solStore, std::set& rotStore )
+{
+ solStore.insert( sol );
+ if( sol.shape() == ddunion || sol.shape() == ddsubtraction || sol.shape() == ddintersection )
+ {
+ const DDBooleanSolid& bs ( sol );
+ if( solStore.find(bs.solidA()) == solStore.end())
+ {
+ addToSolStore( bs.solidA(), solStore, rotStore );
+ }
+ if( solStore.find( bs.solidB()) == solStore.end())
+ {
+ addToSolStore( bs.solidB(), solStore, rotStore );
+ }
+ rotStore.insert( bs.rotation());
+ }
+}
+
+void
+OutputMagneticFieldDDToDDL::addToSpecStore( const DDLogicalPart& lp, std::map, ddsvaluesCmp > & specStore )
+{
+ std::vector >::const_iterator spit( lp.attachedSpecifics().begin()), spend( lp.attachedSpecifics().end());
+ for( ; spit != spend; ++spit )
+ {
+ specStore[ *spit->second ].insert( spit->first );
+ }
+}
+
+#include "FWCore/Framework/interface/MakerMacros.h"
+DEFINE_FWK_MODULE( OutputMagneticFieldDDToDDL );
diff --git a/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.h b/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.h
new file mode 100644
index 0000000000000..4da5a892e4c7c
--- /dev/null
+++ b/DetectorDescription/OfflineDBLoader/bin/stubs/OutputMagneticFieldDDToDDL.h
@@ -0,0 +1,42 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+class DDPartSelection;
+
+/// is sv1 < sv2
+struct ddsvaluesCmp
+{
+ bool operator() ( const DDsvalues_type& sv1, const DDsvalues_type& sv2 );
+};
+
+class OutputMagneticFieldDDToDDL : public edm::EDAnalyzer
+{
+public:
+ explicit OutputMagneticFieldDDToDDL( const edm::ParameterSet& iConfig );
+ ~OutputMagneticFieldDDToDDL( void );
+
+ virtual void beginRun( const edm::Run&, edm::EventSetup const& );
+ virtual void analyze( const edm::Event&, const edm::EventSetup& ){}
+ virtual void endJob( void ) {}
+
+private:
+ void addToMatStore( const DDMaterial& mat, std::set & matStore );
+ void addToSolStore( const DDSolid& sol, std::set & solStore, std::set& rotStore );
+ void addToSpecStore( const DDLogicalPart& lp, std::map, ddsvaluesCmp > & specStore );
+
+ std::string m_fname;
+ std::ostream* m_xos;
+ int m_rotNumSeed;
+ int m_specNameCount;
+};
+
diff --git a/Geometry/CMSCommonData/python/cmsMagneticFieldGeometryXML_cfi.py b/Geometry/CMSCommonData/python/cmsMagneticFieldGeometryXML_cfi.py
new file mode 100644
index 0000000000000..5f0ce16045a7a
--- /dev/null
+++ b/Geometry/CMSCommonData/python/cmsMagneticFieldGeometryXML_cfi.py
@@ -0,0 +1,12 @@
+import FWCore.ParameterSet.Config as cms
+
+XMLIdealGeometryESSource = cms.ESSource("XMLIdealGeometryESSource",
+ geomXMLFiles = cms.vstring('Geometry/CMSCommonData/data/normal/cmsextent.xml',
+ 'Geometry/CMSCommonData/data/cms.xml',
+ 'Geometry/CMSCommonData/data/cmsMagneticField.xml',
+ 'MagneticField/GeomBuilder/data/MagneticFieldVolumes_1103l.xml',
+ 'Geometry/CMSCommonData/data/materials.xml'),
+ rootNodeName = cms.string('cmsMagneticField:MAGF')
+)
+
+
diff --git a/GeometryReaders/XMLIdealGeometryESSource/python/cmsMagneticFieldGeometryDB_cff.py b/GeometryReaders/XMLIdealGeometryESSource/python/cmsMagneticFieldGeometryDB_cff.py
new file mode 100644
index 0000000000000..26c14ea537cc1
--- /dev/null
+++ b/GeometryReaders/XMLIdealGeometryESSource/python/cmsMagneticFieldGeometryDB_cff.py
@@ -0,0 +1,6 @@
+import FWCore.ParameterSet.Config as cms
+
+XMLFromDBSource = cms.ESProducer("XMLIdealMagneticFieldGeometryESProducer",
+ rootDDName = cms.string('cmsMagneticField:MAGF'),
+ label = cms.string('magfield')
+ )
diff --git a/GeometryReaders/XMLIdealGeometryESSource/src/XMLIdealMagneticFieldGeometryESProducer.cc b/GeometryReaders/XMLIdealGeometryESSource/src/XMLIdealMagneticFieldGeometryESProducer.cc
new file mode 100644
index 0000000000000..862aad12379bd
--- /dev/null
+++ b/GeometryReaders/XMLIdealGeometryESSource/src/XMLIdealMagneticFieldGeometryESProducer.cc
@@ -0,0 +1,85 @@
+#include "boost/shared_ptr.hpp"
+
+#include "FWCore/Framework/interface/ModuleFactory.h"
+#include "FWCore/Framework/interface/ESProducer.h"
+
+#include "FWCore/Framework/interface/ESHandle.h"
+#include "FWCore/Framework/interface/ESTransientHandle.h"
+
+#include "DetectorDescription/Core/interface/DDCompactView.h"
+#include "DetectorDescription/Core/interface/DDRoot.h"
+#include "DetectorDescription/Parser/interface/DDLParser.h"
+#include "CondFormats/Common/interface/FileBlob.h"
+#include "Geometry/Records/interface/GeometryFileRcd.h"
+#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
+
+#include "DetectorDescription/Core/interface/DDMaterial.h"
+#include "DetectorDescription/Core/interface/DDSolid.h"
+#include "DetectorDescription/Core/interface/DDSpecifics.h"
+#include "DetectorDescription/Base/interface/DDRotationMatrix.h"
+
+#include "DetectorDescription/Core/src/Material.h"
+#include "DetectorDescription/Core/src/Solid.h"
+#include "DetectorDescription/Core/src/LogicalPart.h"
+#include "DetectorDescription/Core/src/Specific.h"
+
+class XMLIdealMagneticFieldGeometryESProducer : public edm::ESProducer
+{
+public:
+ XMLIdealMagneticFieldGeometryESProducer( const edm::ParameterSet& );
+ ~XMLIdealMagneticFieldGeometryESProducer();
+
+ typedef std::auto_ptr ReturnType;
+
+ ReturnType produce( const IdealMagneticFieldRecord& );
+
+private:
+ std::string rootDDName_; // this must be the form namespace:name
+ std::string label_;
+
+ DDI::Store matStore_;
+ DDI::Store solidStore_;
+ DDI::Store lpStore_;
+ DDI::Store specStore_;
+ DDI::Store rotStore_;
+};
+
+XMLIdealMagneticFieldGeometryESProducer::XMLIdealMagneticFieldGeometryESProducer( const edm::ParameterSet& iConfig )
+ : rootDDName_(iConfig.getParameter( "rootDDName" )),
+ label_(iConfig.getParameter( "label" ))
+{
+ setWhatProduced( this );
+}
+
+
+XMLIdealMagneticFieldGeometryESProducer::~XMLIdealMagneticFieldGeometryESProducer( void )
+{}
+
+XMLIdealMagneticFieldGeometryESProducer::ReturnType
+XMLIdealMagneticFieldGeometryESProducer::produce( const IdealMagneticFieldRecord& iRecord )
+{
+ using namespace edm::es;
+
+ edm::ESTransientHandle gdd;
+ iRecord.getRecord().get( label_, gdd );
+
+ DDName ddName(rootDDName_);
+ DDLogicalPart rootNode(ddName);
+ DDRootDef::instance().set(rootNode);
+ ReturnType returnValue(new DDCompactView(rootNode));
+ DDLParser parser(*returnValue);
+ parser.getDDLSAX2FileHandler()->setUserNS(true);
+ parser.clearFiles();
+
+ std::vector* tb = (*gdd).getUncompressedBlob();
+
+ parser.parse(*tb, tb->size());
+
+ delete tb;
+
+ returnValue->lockdown();
+
+ return returnValue ;
+}
+
+DEFINE_FWK_EVENTSETUP_MODULE( XMLIdealMagneticFieldGeometryESProducer );