From 9469618a5d65f4b3190dc1c10d9c46a1043d11ba Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Mon, 3 Jun 2013 17:46:28 +0000
Subject: [PATCH] Fix problems with invalid VisAttr objects and field object
 for the conversion to LCDD

---
 DDCore/src/GeoHandler.cpp                     | 17 +++++++-------
 DDCore/src/Volumes.cpp                        | 23 +++++++++++++------
 DDCore/src/plugins/LCDDConverter.cpp          | 10 +++-----
 DDCore/src/plugins/LCDDConverter.h            |  9 +++-----
 .../CLICSiD/compact/compact_polycones.xml     |  2 +-
 DDExamples/ILDExDet/compact/CLIC_ILD_CDR.xml  |  2 +-
 DDExamples/UtilityApps/src/converter.cpp      |  4 +++-
 DDExamples/UtilityApps/src/plugin_runner.cpp  |  3 ++-
 8 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp
index a34d6bf4f..b632d27ae 100644
--- a/DDCore/src/GeoHandler.cpp
+++ b/DDCore/src/GeoHandler.cpp
@@ -77,11 +77,6 @@ GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) {
       if ( v ) {
 	TGeoMedium* m = v->GetMedium();
 	Volume      vol = Ref_t(v);
-	VisAttr     vis = vol.visAttributes();
-	//Region      reg = vol.region();
-	//LimitSet    lim = vol.limitSet();
-	//SensitiveDetector det = vol.sensitiveDetector();
-
 	// Note : assemblies and the world do not have a real volume nor a material
 	if ( info.volumeSet.find(v) == info.volumeSet.end() )   {
 	  info.volumeSet.insert(v);
@@ -89,12 +84,16 @@ GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) {
 	}
 	if ( m ) info.materials.insert(m);
 	if ( dynamic_cast<Volume::Object*>(v) ) {
+	  VisAttr     vis = vol.visAttributes();
+	  //Region      reg = vol.region();
+	  //LimitSet    lim = vol.limitSet();
+	  //SensitiveDetector det = vol.sensitiveDetector();
+
 	  if ( vis.isValid() ) info.vis.insert(vis.ptr());
+	  //if ( lim.isValid() ) info.limits[lim.ptr()].insert(v);
+	  //if ( reg.isValid() ) info.regions[reg.ptr()].insert(v);
+	  //if ( det.isValid() ) info.sensitives[det.ptr()].insert(v);
 	}
-	//if ( lim.isValid() ) info.limits[lim.ptr()].insert(v);
-	//if ( reg.isValid() ) info.regions[reg.ptr()].insert(v);
-	//if ( det.isValid() ) info.sensitives[det.ptr()].insert(v);
-
 	collectSolid(info,v->GetName(),n->GetName(),v->GetShape(),n->GetMatrix());
       }
     }
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index e588752ad..056867ccb 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -263,7 +263,9 @@ PlacedVolume::VolIDs::insert(const string& name, int value)   {
 }
 
 static PlacedVolume::Object* _data(const PlacedVolume& v)  {
-  return dynamic_cast<PlacedVolume::Object*>(v.ptr());
+   PlacedVolume::Object* o = dynamic_cast<PlacedVolume::Object*>(v.ptr());
+   if ( o ) return o;
+   throw runtime_error("Attempt to access invalid handle of type: PlacedVolume");
 }
 
 /// Add identifier
@@ -316,9 +318,12 @@ Volume::Object::~Object()  {
 }
 
 /// Accessor to the data part of the Volume
-Volume::Object* _data(const Volume& v) {
+Volume::Object* _data(const Volume& v, bool throw_exception = true) {
   //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
-  return dynamic_cast<Volume::Object*>(v.ptr());
+  Volume::Object* o = dynamic_cast<Volume::Object*>(v.ptr());
+  if ( o ) return o;
+  else if ( !throw_exception ) return 0;
+  throw runtime_error("Attempt to access invalid handle of type: PlacedVolume");
 }
 
 /// Constructor to be used when creating a new geometry tree.
@@ -535,12 +540,16 @@ Material Volume::material() const
 {  return Ref_t(m_element->GetMedium());   }
 
 /// Access the visualisation attributes
-VisAttr Volume::visAttributes() const
-{  return _data(*this)->vis;                              }
+VisAttr Volume::visAttributes() const  {  
+  Object* o = _data(*this,false);
+  if ( o ) return o->vis;
+  return VisAttr();
+}
 
 /// Access to the handle to the region structure
-Region Volume::region() const   
-{  return _data(*this)->region;                           }
+Region Volume::region() const    {
+  return _data(*this)->region;
+}
 
 /// Access to the limit set
 LimitSet Volume::limitSet() const   
diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp
index 358123f0a..a121fd6e3 100644
--- a/DDCore/src/plugins/LCDDConverter.cpp
+++ b/DDCore/src/plugins/LCDDConverter.cpp
@@ -72,7 +72,6 @@ void LCDDConverter::GeometryInfo::check(const string& name, const TNamed* n,map<
 
 /// Initializing Constructor
 LCDDConverter::LCDDConverter( LCDD& lcdd ) : m_lcdd(lcdd), m_dataPtr(0) {
-  m_checkOverlaps = true;
 }
 
 LCDDConverter::~LCDDConverter()   {
@@ -952,10 +951,9 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) {
   }
   GeometryInfo& geo = *(m_dataPtr=new GeometryInfo);
   m_data->clear();
-
   collect(top,geo);
-  m_checkOverlaps = false;
 
+  cout << "++ ==> Converting in memory detector description to GDML format..." << endl;
   const char* comment = "\n"
     "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
     "      ++++   Linear collider detector description GDML in C++  ++++\n"
@@ -1020,8 +1018,7 @@ xml_doc_t LCDDConverter::createVis(DetElement top) {
   GeometryInfo& geo = *(m_dataPtr=new GeometryInfo);
   m_data->clear();
   collect(top,geo);
-  m_checkOverlaps = false;
-
+  cout << "++ ==> Dump visualisation attributes from in memory detector description..." << endl;
   const char comment[] = "\n"
     "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
     "      ++++   Linear collider detector description LCDD in C++  ++++\n"
@@ -1054,8 +1051,6 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
   GeometryInfo& geo = *(m_dataPtr=new GeometryInfo);
   m_data->clear();
   collect(top,geo);
-  m_checkOverlaps = false;
-
   const char comment[] = "\n"
     "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
     "      ++++   Linear collider detector description LCDD in C++  ++++\n"
@@ -1098,6 +1093,7 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
   for(LCDD::HandleMap::const_iterator i=fld.begin(); i!=fld.end(); ++i)
     geo.fields.insert((*i).second.ptr());
 
+  cout << "++ ==> Converting in memory detector description to LCDD format..." << endl;
   handleHeader();
   // Start creating the objects for materials, solids and log volumes.
   handle(this, geo.materials, &LCDDConverter::handleMaterial);
diff --git a/DDCore/src/plugins/LCDDConverter.h b/DDCore/src/plugins/LCDDConverter.h
index 1ae298d66..ac1065b8a 100644
--- a/DDCore/src/plugins/LCDDConverter.h
+++ b/DDCore/src/plugins/LCDDConverter.h
@@ -94,20 +94,17 @@ namespace DD4hep {
 	  doc_display, doc_gdml, doc_fields, doc_define, doc_materials, doc_solids, doc_structure, doc_setup;
 	GeometryInfo();
       };
+      typedef std::set<std::string> NameSet;
+
       /// Reference to detector description
       LCDD&           m_lcdd;
-      /// Processing flag
-      bool            m_checkOverlaps;
-
-      typedef std::set<std::string> NameSet;
       mutable NameSet m_checkNames;
+      GeometryInfo*   m_dataPtr;
 
-      GeometryInfo* m_dataPtr;
       GeometryInfo& data() const { return *m_dataPtr; }
 
       /// Data integrity checker
       void checkVolumes(const std::string& name, const TGeoVolume* volume) const;
-
       
       /// Initializing Constructor
       LCDDConverter( LCDD& lcdd );
diff --git a/DDExamples/CLICSiD/compact/compact_polycones.xml b/DDExamples/CLICSiD/compact/compact_polycones.xml
index 2ee0b5fa6..94aa2bde2 100644
--- a/DDExamples/CLICSiD/compact/compact_polycones.xml
+++ b/DDExamples/CLICSiD/compact/compact_polycones.xml
@@ -835,7 +835,7 @@
         </readout>
     </readouts>
     <fields>
-        <field name="GlobalSolenoid" type="SolenoidMagnet" 
+        <field name="GlobalSolenoid" type="solenoid" 
           inner_field="5.0*tesla"
           outer_field="-1.5*tesla" 
           zmax="SolenoidCoilOuterZ"
diff --git a/DDExamples/ILDExDet/compact/CLIC_ILD_CDR.xml b/DDExamples/ILDExDet/compact/CLIC_ILD_CDR.xml
index 73bc17df1..d7e39eda8 100644
--- a/DDExamples/ILDExDet/compact/CLIC_ILD_CDR.xml
+++ b/DDExamples/ILDExDet/compact/CLIC_ILD_CDR.xml
@@ -963,7 +963,7 @@
     </readouts>
 
     <fields>
-        <field type="SolenoidMagnet" name="GlobalSolenoid" inner_field="5.0*tesla"
+        <field type="solenoid" name="GlobalSolenoid" inner_field="5.0*tesla"
                outer_field="-1.5*tesla" zmax="SolenoidCoilOuterZ"
                outer_radius="SolenoidalFieldRadius" />
     </fields>
diff --git a/DDExamples/UtilityApps/src/converter.cpp b/DDExamples/UtilityApps/src/converter.cpp
index 66ee4b994..84ab53f25 100644
--- a/DDExamples/UtilityApps/src/converter.cpp
+++ b/DDExamples/UtilityApps/src/converter.cpp
@@ -79,6 +79,9 @@ int main(int argc,char** argv)  {
   LCDD& lcdd = dd4hep_instance();
   // Load compact files
   run_plugin(lcdd,"DD4hepCompactLoader",int(geo_files.size()),&geo_files[0]);
+  // Create volume manager and populate it required
+  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
+  // Execute data converter.
   if ( compact2lcdd )
     run_plugin(lcdd,"DD4hepGeometry2LCDD",output,&argv[output]);
   else if ( compact2gdml )
@@ -89,7 +92,6 @@ int main(int argc,char** argv)  {
     run_plugin(lcdd,"DD4hepGeometry2VISASCII",output,&argv[output]);
   else if ( compact2vis )
     run_plugin(lcdd,"DD4hepGeometry2VIS",output,&argv[output]);
-  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
   if ( destroy ) delete &lcdd;
   return 0;
 }
diff --git a/DDExamples/UtilityApps/src/plugin_runner.cpp b/DDExamples/UtilityApps/src/plugin_runner.cpp
index 5c98e619c..b6eb0bd1d 100644
--- a/DDExamples/UtilityApps/src/plugin_runner.cpp
+++ b/DDExamples/UtilityApps/src/plugin_runner.cpp
@@ -54,9 +54,10 @@ int main(int argc,char** argv)  {
   LCDD& lcdd = dd4hep_instance();
   // Load compact files
   run_plugin(lcdd,"DD4hepCompactLoader",int(geo_files.size()),&geo_files[0]);
+  // Create volume manager and populate it required
+  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
   // Execute plugin
   run_plugin(lcdd,plugin.c_str(),0,0);
-  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
   if ( destroy ) delete &lcdd;
   return 0;
 }
-- 
GitLab