From c97f1820601b724acb21a87f5eaf6f32d2838ab7 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Thu, 31 Aug 2017 17:28:16 +0200
Subject: [PATCH] Try to fix some voverity errors

---
 DDAlign/include/DDAlign/AlignmentsCalib.h     |   4 +-
 DDAlign/src/AlignmentsCalib.cpp               |   4 +-
 DDCond/include/DDCond/ConditionsDataLoader.h  |   2 +
 DDCond/src/ConditionsDataLoader.cpp           |   5 +
 DDCond/src/ConditionsRepository.cpp           |  25 +-
 DDCore/include/DD4hep/Plugins.h               |  15 +-
 DDCore/src/Alignments.cpp                     |  15 +-
 DDCore/src/AlignmentsInterna.cpp              |   4 +-
 DDCore/src/ConditionsPrinter.cpp              |  11 +-
 DDCore/src/Plugins.cpp                        |   4 +-
 DDDB/src/plugins/DDDBDetectorDumps.cpp        |  42 ++--
 DDG4/src/Geant4ParticlePrint.cpp              |   8 +-
 doc/LaTex/DDConditionsManual.tex              | 221 ++++++++++++++++--
 .../src/ConditionExample_manual.cpp           |  79 +++----
 14 files changed, 313 insertions(+), 126 deletions(-)

diff --git a/DDAlign/include/DDAlign/AlignmentsCalib.h b/DDAlign/include/DDAlign/AlignmentsCalib.h
index 7e9259194..2e3737aa1 100644
--- a/DDAlign/include/DDAlign/AlignmentsCalib.h
+++ b/DDAlign/include/DDAlign/AlignmentsCalib.h
@@ -72,7 +72,7 @@ namespace dd4hep {
       /// Initializing constructor
       AlignmentsCalib(Detector& description, ConditionsMap& mapping);
       /// Default destructor
-      virtual ~AlignmentsCalib();
+      virtual ~AlignmentsCalib() noexcept(false);
       /// No assignment operator
       AlignmentsCalib& operator=(const AlignmentsCalib& copy) = delete;
       /// No move assignment operator
@@ -116,7 +116,7 @@ namespace dd4hep {
       void clearDeltas();
 
       /// We clear the entire cached stack of used entries.
-      void clear();
+      void clear() noexcept(false);
 
       /// Convenience only: Access detector element by path
       DetElement detector(const std::string& path)  const;
diff --git a/DDAlign/src/AlignmentsCalib.cpp b/DDAlign/src/AlignmentsCalib.cpp
index 5b809d470..3ce1c5617 100644
--- a/DDAlign/src/AlignmentsCalib.cpp
+++ b/DDAlign/src/AlignmentsCalib.cpp
@@ -51,7 +51,7 @@ AlignmentsCalib::AlignmentsCalib(Detector& l, ConditionsMap& m) : description(l)
 }
 
 /// Default destructor
-AlignmentsCalib::~AlignmentsCalib()   {
+AlignmentsCalib::~AlignmentsCalib()   noexcept(false)  {
   clear();
 }
 
@@ -124,7 +124,7 @@ void AlignmentsCalib::clearDeltas()   {
 }
 
 /// Clear all pending entries in the working cache
-void AlignmentsCalib::clear()   {
+void AlignmentsCalib::clear()   noexcept(false)  {
   for(auto& e : used)   {
     e.second->source.get<Delta>() = e.second->delta;
     detail::deletePtr(e.second);
diff --git a/DDCond/include/DDCond/ConditionsDataLoader.h b/DDCond/include/DDCond/ConditionsDataLoader.h
index 16f08716e..8787fb4be 100644
--- a/DDCond/include/DDCond/ConditionsDataLoader.h
+++ b/DDCond/include/DDCond/ConditionsDataLoader.h
@@ -73,6 +73,8 @@ namespace dd4hep {
       /// Default destructor
       virtual ~ConditionsDataLoader();
       /// Add data source definition to loader
+      void addSource(const std::string& source);
+      /// Add data source definition to loader for data corresponding to a given IOV
       void addSource(const std::string& source, const IOV& iov);
 #if 0
       /// Load  a condition set given the conditions key according to their validity
diff --git a/DDCond/src/ConditionsDataLoader.cpp b/DDCond/src/ConditionsDataLoader.cpp
index 3b7e43ee9..b7380c0b4 100644
--- a/DDCond/src/ConditionsDataLoader.cpp
+++ b/DDCond/src/ConditionsDataLoader.cpp
@@ -39,6 +39,11 @@ void ConditionsDataLoader::addSource(const string& source, const IOV& iov)   {
   m_sources.push_back(make_pair(source,iov));
 }
 
+/// Add data source definition to loader
+void ConditionsDataLoader::addSource(const string& source)   {
+  m_sources.push_back(make_pair(source,IOV(0,0)));
+}
+
 /// Queue update to manager.
 //Condition ConditionsDataLoader::queueUpdate(Entry* data)   {
 //  return m_mgr->__queue_update(data);
diff --git a/DDCond/src/ConditionsRepository.cpp b/DDCond/src/ConditionsRepository.cpp
index 4a17f22b2..b092b9311 100644
--- a/DDCond/src/ConditionsRepository.cpp
+++ b/DDCond/src/ConditionsRepository.cpp
@@ -157,22 +157,27 @@ namespace {
       if ( in.good() )  {
         if ( siz_tot )  {
           // Direct access mode with fixed record size
-          text[8] = text[9+siz_nam] = text[10+siz_nam+siz_add] = 0;
-          e.name = text+9;
-          e.address = text+10+siz_nam;  
-          if ( (idx=e.name.find(' ')) != string::npos )
-            e.name[idx] = 0;
-          if ( (idx=e.address.find(' ')) != string::npos )
-            e.address[idx] = 0;
+          if ( siz_nam+9 < (long)sizeof(text) )  {
+            text[8] = text[9+siz_nam] = text[10+siz_nam+siz_add] = 0;
+            e.name = text+9;
+            e.address = text+10+siz_nam;  
+            if ( (idx=e.name.find(' ')) != string::npos && idx < e.name.length() )
+              e.name[idx] = 0;
+            if ( (idx=e.address.find(' ')) != string::npos && idx < e.address.length() )
+              e.address[idx] = 0;
+          }
+          else  {
+            except("ConditionsRepository","+++ Invalid record encountered. [Sever error]");
+          }
         }
         else  {
           // Variable record size
           e.name=text+9;
-          if ( (idx=e.name.find(sep)) != string::npos )
+          if ( (idx=e.name.find(sep)) != string::npos && idx < sizeof(text)-9 )
             text[9+idx] = 0, e.address=text+idx+10, e.name=text+9;
-          if ( (idx=e.address.find(sep)) != string::npos )
+          if ( (idx=e.address.find(sep)) != string::npos && idx < e.address.length() )
             e.address[idx] = 0;
-          else if ( (idx=e.address.find('\n')) != string::npos )
+          else if ( (idx=e.address.find('\n')) != string::npos && idx < e.address.length() )
             e.address[idx] = 0;
         }
         size_t cap = data.capacity();
diff --git a/DDCore/include/DD4hep/Plugins.h b/DDCore/include/DD4hep/Plugins.h
index 6ee358076..ceb6c62a9 100644
--- a/DDCore/include/DD4hep/Plugins.h
+++ b/DDCore/include/DD4hep/Plugins.h
@@ -33,18 +33,8 @@ namespace dd4hep {
   class NamedObject;
   template <typename T> class Handle;
 
-  /// Namespace for the AIDA detector description toolkit supporting XML utilities
-  namespace xml  {
-    //class Handle;
-    //class Collection_t;
-    //class Document;
-    //class Element;
-  }
-
   /// Factory base class implementing some utilities
   struct PluginFactoryBase  {
-    //typedef xml::Handle_t xml_h;
-    //typedef xml::Element  xml_e;
     typedef std::string   str_t;
 
     template <typename T> static T* ptr(const T* _p)     { return (T*)_p;  }
@@ -74,7 +64,7 @@ namespace dd4hep {
     /// Default constructor
     PluginDebug(int dbg = 2)  noexcept(false);
     /// Default destructor
-    ~PluginDebug();
+    ~PluginDebug()  noexcept(false);
     /// Helper to check factory existence
     std::string missingFactory(const std::string& name) const;
   };
@@ -245,8 +235,5 @@ namespace dd4hep {
     };                                                                  \
     template <typename P> inline R Factory<P,R(A0,A1,A2,A3,A4)>::call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
   
-
-
-
 #endif    /* __CINT__          */
 #endif    /* DD4HEP_PLUGINS_H  */
diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp
index d34c0c93d..d870e1ab1 100644
--- a/DDCore/src/Alignments.cpp
+++ b/DDCore/src/Alignments.cpp
@@ -23,11 +23,11 @@
 using namespace std;
 using namespace dd4hep;
 
-const std::string dd4hep::align::Keys::deltaName("alignment_delta");
+const string dd4hep::align::Keys::deltaName("alignment_delta");
 const dd4hep::Condition::itemkey_type  dd4hep::align::Keys::deltaKey =
   dd4hep::ConditionKey::itemCode("alignment_delta");
 
-const std::string dd4hep::align::Keys::alignmentName("alignment");
+const string dd4hep::align::Keys::alignmentName("alignment");
 const dd4hep::Condition::itemkey_type dd4hep::align::Keys::alignmentKey =
   dd4hep::ConditionKey::itemCode("alignment");
 
@@ -77,7 +77,7 @@ const TGeoHMatrix& Alignment::detectorTransformation() const   {
 }
 
 /// Access to the node list
-const std::vector<PlacedVolume>& Alignment::nodes() const   {
+const vector<PlacedVolume>& Alignment::nodes() const   {
   return access()->values().nodes;
 }
 
@@ -157,20 +157,17 @@ AlignmentCondition::key_type AlignmentCondition::key() const   {
 
 /// Data accessor for the use of decorators
 AlignmentData& AlignmentCondition::data()              {
-  Object* o = access();
-  return o->alignment_data ? *o->alignment_data : o->values();
+  return *(access()->alignment_data);
 }
 
 /// Data accessor for the use of decorators
 const AlignmentData& AlignmentCondition::data() const  {
-  Object* o = access();
-  return o->alignment_data ? *o->alignment_data : o->values();
+  return *(access()->alignment_data);
 }
 
 /// Access the delta value of the object
 const Delta& AlignmentCondition::delta() const   {
-  Object* o = access();
-  return (o->alignment_data ? *o->alignment_data : o->values()).delta;
+  return access()->alignment_data->delta;
 }
 
 /// Check if object is already bound....
diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp
index 65ae9c138..8aa2ffa49 100644
--- a/DDCore/src/AlignmentsInterna.cpp
+++ b/DDCore/src/AlignmentsInterna.cpp
@@ -24,8 +24,8 @@ using namespace std;
 using namespace dd4hep;
 using namespace dd4hep::detail;
 
-DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentObject,ConditionObject);
 DD4HEP_INSTANTIATE_HANDLE_UNNAMED(AlignmentData);
+DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentObject,ConditionObject);
 
 /// Default constructor
 AlignmentObject::AlignmentObject()
@@ -39,7 +39,7 @@ AlignmentObject::AlignmentObject()
 
 /// Standard constructor
 AlignmentObject::AlignmentObject(const string& nam, const string& tit, void* p, size_t len)
-  : ConditionObject(nam, tit), alignment_data(0)//, source_key(0)
+  : ConditionObject(nam, tit), alignment_data(0)
 {
   InstanceCount::increment(this);
   flags  = Condition::ALIGNMENT_DERIVED|Condition::ONSTACK;
diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp
index 4b51672c8..d7ab23d40 100644
--- a/DDCore/src/ConditionsPrinter.cpp
+++ b/DDCore/src/ConditionsPrinter.cpp
@@ -49,12 +49,12 @@ protected:
   ConditionsPrinter* m_parent = 0;
 public:
   std::string        prefix;
-  PrintLevel         printLevel;
+  PrintLevel         printLevel = INFO;
 public:
   /// Copy constructor
   ParamPrinter(const ParamPrinter& copy) = default;
   /// Initializing constructor
-  ParamPrinter(ConditionsPrinter* p);
+  ParamPrinter(ConditionsPrinter* p, PrintLevel lvl);
   /// Default destructor
   virtual ~ParamPrinter() = default;
   /// Assignment operator
@@ -65,7 +65,9 @@ public:
 
 
 /// Initializing constructor
-ConditionsPrinter::ParamPrinter::ParamPrinter(ConditionsPrinter* p)  : m_parent(p)  {
+ConditionsPrinter::ParamPrinter::ParamPrinter(ConditionsPrinter* p, PrintLevel lvl)
+  : m_parent(p), printLevel(lvl)
+{
 }
 
 /// Callback to output conditions information
@@ -112,8 +114,7 @@ void ConditionsPrinter::ParamPrinter::operator()(const AbstractMap::Params::valu
 ConditionsPrinter::ConditionsPrinter(ConditionsMap* m, const string& pref, int flg)
   : mapping(m), m_flag(flg), name("Condition"), prefix(pref)
 {
-  m_print = new ParamPrinter(this);
-  m_print->printLevel = printLevel;
+  m_print = new ParamPrinter(this, printLevel);
 }
 
 /// Default destructor
diff --git a/DDCore/src/Plugins.cpp b/DDCore/src/Plugins.cpp
index c953e6810..8297424ff 100644
--- a/DDCore/src/Plugins.cpp
+++ b/DDCore/src/Plugins.cpp
@@ -49,7 +49,7 @@ PluginDebug::PluginDebug(int dbg)
 }
 
 /// Default destructor
-PluginDebug::~PluginDebug() {
+PluginDebug::~PluginDebug() noexcept(false) {
   ROOT::Reflex::PluginService::SetDebug (m_debug);
 }
 
@@ -140,7 +140,7 @@ PluginDebug::PluginDebug(int dbg)  noexcept(false) : m_debug(0) {
 }
 
 /// Default destructor
-PluginDebug::~PluginDebug()  {
+PluginDebug::~PluginDebug()   noexcept(false)   {
   PluginInterface::instance().setDebug(m_debug);
 }
 
diff --git a/DDDB/src/plugins/DDDBDetectorDumps.cpp b/DDDB/src/plugins/DDDBDetectorDumps.cpp
index 0f12728d2..bf3deb496 100644
--- a/DDDB/src/plugins/DDDBDetectorDumps.cpp
+++ b/DDDB/src/plugins/DDDBDetectorDumps.cpp
@@ -63,7 +63,7 @@ DECLARE_APPLY(DDDB_PluginLevel,dddb_plugin_print_level)
 namespace {
 
   using namespace dd4hep::cond;
-  
+
   /// Basic entry point to print out the detector element hierarchy
   /**
    *  \author  M.Frank
@@ -75,7 +75,31 @@ namespace {
     using align::deltaCollector;    
     using DDDB::DDDBCatalog;
 
-
+    /// Access the test's name
+    /**
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \date    01/04/2014
+     */
+    struct naming  {
+      /// Access the name of the test
+      static const char* get(int flag)   {
+        const char* n = "DDDBDetectorDump";
+        if ( flag == 1 )
+          n = "DDDBDetVolumeDump";
+        else if ( flag == 2 )
+          n = "DDDBDetConditionKeyDump";
+        else if ( flag == 3 )
+          n = "DDDBDetConditionDump";
+        else if ( flag == 4 )
+          n = "DDDBDetectorDump";
+        else if ( flag == 5 )
+          n = "DetElementConditionDump";
+        else if ( flag == 5 )
+          n = "DDDBDetectorDumpAll";
+        return n;
+      }
+    };
     /// Callback object to print selective information
     /**
      *  \author  M.Frank
@@ -121,6 +145,7 @@ namespace {
           m_alignPrinter(0,"DDDBAlignments"),
           m_flag(flg), m_sensitivesOnly(sens), m_dumpConditions(dmp), m_detDesc(l)
       {
+        m_name = naming::get(flg);
         m_manager = ConditionsManager::from(m_detDesc);
         m_slice.reset(new ConditionsSlice(m_manager,shared_ptr<ConditionsContent>(new ConditionsContent())));
         m_detElementPrinter.printLevel   = s_PrintLevel;
@@ -371,19 +396,6 @@ namespace {
       }
     }
     DumpActor actor(description, flag, dump_sensitive_only, dump_all_cond);
-    actor.m_name = "DDDBDetectorDump";
-    if ( flag == 1 )
-      actor.m_name = "DDDBDetVolumeDump";
-    else if ( flag == 2 )
-      actor.m_name = "DDDBDetConditionKeyDump";
-    else if ( flag == 3 )
-      actor.m_name = "DDDBDetConditionDump";
-    else if ( flag == 4 )
-      actor.m_name = "DDDBDetectorDump";
-    else if ( flag == 5 )
-      actor.m_name = "DetElementConditionDump";
-    else if ( flag == 5 )
-      actor.m_name = "DDDBDetectorDumpAll";
     printout(INFO,actor.m_name,"**************** DDDB Detector dump *****************************");
     return actor.init().dump(description.world(), 0);
   }
diff --git a/DDG4/src/Geant4ParticlePrint.cpp b/DDG4/src/Geant4ParticlePrint.cpp
index 922402a6f..c7d62afde 100644
--- a/DDG4/src/Geant4ParticlePrint.cpp
+++ b/DDG4/src/Geant4ParticlePrint.cpp
@@ -201,9 +201,11 @@ void Geant4ParticlePrint::printParticleTree(const G4Event* e,
   ::memset(txt+6,' ',len-6);
   txt[len-1] = 0;
   txt[len-2] = '>';
-  txt[level+6]='+';
-  ::memset(txt+level+6+1,'-',len-level-3-6);
-
+  if ( size_t(level + 6) < len )    {
+    txt[level+6]='+';
+    ::memset(txt+level+6+1,'-',len-level-3-6);
+  }
+  
   printParticle(txt, e, p);
   const set<int>& daughters = p->daughters;
   // For all particles, the set of daughters must be contained in the record.
diff --git a/doc/LaTex/DDConditionsManual.tex b/doc/LaTex/DDConditionsManual.tex
index 1258bae14..a81e05715 100644
--- a/doc/LaTex/DDConditionsManual.tex
+++ b/doc/LaTex/DDConditionsManual.tex
@@ -609,55 +609,244 @@ the requested items.
 \label{sec:ddcond-example}
 %=============================================================================
 
+
 %=============================================================================
-\subsection{Example to Load and Prepare Conditions(Slices)}
-\label{subsec:ddcond-example-loading}
+\subsection{Example to Save Conditions to a ROOT File}
+\label{subsec:ddcond-example-saving}
 %=============================================================================
 
 \noindent
-To illustrate the usage of the \DDC package an example is discussed here in detail.
+To illustrate the usage of the \DDC package when saving conditions,
+an example is discussed here in detail.
 The full example is part of the conditions unit tests and can be found in the 
 \DDH examples.\\
-(See examples/Conditions/src/ConditionExample\_manual.cpp).
+(See examples/Conditions/src/ConditionExample\_manual\_save.cpp).
 
 \noindent
 The examples uses conditions names and detector element names explicitly and
 hence requires a fixed detector description being loaded in memory.
-For simplicity we use here the Minitel example from the example/ClientTests.
+For simplicity we use here the Minitel example from the examples/ClientTests.
+However, the example is very generic and also the conditions are "generic",
+hence any geometry would work.
+
+
+\vspace{0.6cm}
+
+\noindent
+{\bf{Prerequisites:}} \\
+\\
+A valid compact geometry description to be loaded during the program startup.
+
+\vspace{0.6cm}
+
+\noindent
+{\bf{Plugin Invocation:}} \\
+\\
+A valid example conditions data file is required. Then use the default way
+to invoke plugins:\\
+\tw{\$ > geoPluginRun\ \textrm{-}destroy  \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}plugin\ DD4hep\_ConditionExample\_manual\_save \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}input\ file:\$\{DD4hep\_DIR\}/examples/AlignDet/compact/Telescope.xml
+    \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}conditions\ Conditions.root\ \textrm{-}runs\ 10}
+
+
+\vspace{0.6cm}
+
+\noindent
+{\bf{Example Code:}} \\
 
 \begin{code}
-  description.fromXML("examples/ClientTests/compact/MiniTel.xml");
+  int          num_run    = <number of condition loads>;
+  const string conditions = <conditions file name>;
+  const string geometry   = <geometry compact xml description";
+
+  description.fromXML(geometry);
   description.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0);
 
   ConditionsManager manager = ConditionsManager::from(description);
   manager["PoolType"]       = "DD4hep_ConditionsLinearPool";
   manager["UserPoolType"]   = "DD4hep_ConditionsMapUserPool";
   manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool";
-  manager["LoaderType"]     = "root";
   manager.initialize();
 
   shared_ptr<ConditionsContent> content(new ConditionsContent());
   shared_ptr<ConditionsSlice>   slice(new ConditionsSlice(manager,content));
 
- \end{code}
+  const IOVType*    iov_typ = manager.registerIOVType(0,"run").second;
+  if ( 0 == iov_typ )
+    except("ConditionsPrepare","++ Conditions IOV type registration failed!");
+
+  Scanner(ConditionsKeys(*content,INFO),description.world());
+  Scanner(ConditionsDependencyCreator(*content,DEBUG),description.world());
+
+  // Have 10 run-slices [11,20] .... [91,100]
+  for(int i=0; i<num_run; ++i)  {
+    IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10));
+    ConditionsPool*   iov_pool = manager.registerIOV(*iov.iovType, iov.key());
+    // Create conditions with all deltas. Use a generic creator
+    Scanner(ConditionsCreator(*slice, *iov_pool, INFO),description.world(),0,true);
+  }
+
+\end{code}
 
 \noindent
 {\bf{Explanation:}} \\
 \begin{tabular} {l||p{0cm}}
 \docline{Line}{}
-\docline{1}{Load the MiniTel detector description using the compact notation.}
-\docline{2}{Install the conditions manager implementation using the plugin mechanism.}
-\docline{4}{Access conditions manager instance from the Detector interface.}
-\docline{5-8}{Configure the properties of the conditions manager.}
-\docline{9}{Initialize the conditions manager instance.}
-\docline{11-12}{Create empty $ConditionsSlice$ and $ConditionsContent$ instances.}
-\docline{14}{}
+\docline{1-3}{Definition of processing parameters.}
+\docline{5}{Load the detector description using the compact notation.}
+\docline{6}{Install the conditions manager implementation using the plugin mechanism.}
+\docline{8}{Access conditions manager instance from the Detector interface.}
+\docline{9-11}{Configure the properties of the conditions manager.}
+\docline{12}{Initialize the conditions manager instance.}
+\docline{14-15}{Create an empty $ConditionsSlice$ instance the container with 
+                the desired conditions content.}
+\docline{17}{Register IOV type the Conditions Manager. The IOV types are part of the conditions
+            persistency mechanism. They may not change with time and have to be defined 
+            by the experiment once and for all!}
+\docline{18-19}{This is example specific and only a shortcut to fill the 
+             required conditions content and the derivation rules.\\
+             In real life this would be intrinsic to the experiment's 
+             data processing framework.}
+\docline{18}{Populate the $ConditionsContent$ instance with the addresses (keys) 
+             of the conditions required:
+             We scan the $DetElement$ hierarchy and add a couple of conditions
+             for each $DetElement$}
+\docline{19}{Add for each $DetElement$ 3 derived conditions,
+             which all depend on the persistent condition derived\_data.\\
+             In the real world this would be very specific derived actions.}
 
 \end{tabular}
 
+\newpage
+
+
+%=============================================================================
+\subsection{Example to Load and Prepare Conditions(Slices)}
+\label{subsec:ddcond-example-loading}
+%=============================================================================
+
+\noindent
+To illustrate the usage of the \DDC package when loading conditions,
+an example is discussed here in detail.
+The full example is part of the conditions unit tests and can be found in the 
+\DDH examples.\\
+(See examples/Conditions/src/ConditionExample\_manual\_load.cpp).
+
+\noindent
+The examples uses conditions names and detector element names explicitly and
+hence requires a fixed detector description being loaded in memory.
+For simplicity we use here the Minitel example from the examples/ClientTests.
+However, the example is very generic and also the conditions are "generic",
+hence any geometry would work.
+
+\vspace{0.6cm}
+
+\noindent
+{\bf{Prerequisites:}} \\
+\\
+A valid example conditions data file is required, since in this example we 
+load the conditions and inject them to the store from an already existing root file.
+To obtain such a file for a given geometry, execute the example plugin:\\
+\tw{\$ > geoPluginRun\ \textrm{-}destroy  \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}plugin\ DD4hep\_ConditionExample\_manual\_save \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}input\ file:\$\{DD4hep\_DIR\}/examples/AlignDet/compact/Telescope.xml
+    \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}conditions Conditions.root\ \textrm{-}runs\ 10}
+
+\vspace{0.6cm}
+
+\noindent
+{\bf{Plugin Invocation:}} \\
+\\
+A valid example conditions data file is required. Then use the default way
+to invoke plugins:\\
+\tw{\$ > geoPluginRun\ \textrm{-}destroy  \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}plugin\ DD4hep\_ConditionExample\_manual\_load \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}input\ file:\$\{DD4hep\_DIR\}/examples/AlignDet/compact/Telescope.xml
+    \ \ \ \char`\\} \\
+\tw{\hspace{3cm} \textrm{-}conditions\ Conditions.root\ \textrm{-}runs\ 10}
 
-TO BE COMPLETED!
 
+\vspace{0.6cm}
+
+\noindent
+{\bf{Example Code:}} \\
+
+\begin{code}
+  int          num_run    = <number of condition loads>;
+  const string conditions = <conditions file name>;
+  const string geometry   = <geometry compact xml description";
+
+  description.fromXML(geometry);
+  description.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0);
+
+  ConditionsManager manager = ConditionsManager::from(description);
+  manager["PoolType"]       = "DD4hep_ConditionsLinearPool";
+  manager["UserPoolType"]   = "DD4hep_ConditionsMapUserPool";
+  manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool";
+  manager["LoaderType"]     = "root";
+  manager.initialize();
+
+  shared_ptr<ConditionsContent> content(new ConditionsContent());
+  shared_ptr<ConditionsSlice>   slice(new ConditionsSlice(manager,content));
+
+  Scanner(ConditionsKeys(*content,INFO),description.world());
+  Scanner(ConditionsDependencyCreator(*content,DEBUG),description.world());
+
+  const IOVType* iov_typ = manager.iovType("run");
+  for ( int irun=0; irun < num_runs; ++irun )  {
+    IOV iov(iov_typ,irun*10+5);
+    ConditionsManager::Result r = manager.prepare(iov,*slice);
+    if ( r.missing != 0 )  {
+       except("Example", 
+              "Conditions prepare step for IOV %s FAILED. There are %ld missing conditions.",
+              r.missing, iov.str().c_str());
+    }
+    Scanner(ConditionsPrinter(slice.get(),"Example"),description.world());
+  }
+\end{code}
+
+\noindent
+{\bf{Explanation:}} \\
+\begin{tabular} {l||p{0cm}}
+\docline{Line}{}
+\docline{1-3}{Definition of processing parameters.}
+\docline{5}{Load the detector description using the compact notation.}
+\docline{6}{Install the conditions manager implementation using the plugin mechanism.}
+\docline{8}{Access conditions manager instance from the Detector interface.}
+\docline{9-12}{Configure the properties of the conditions manager.}
+\docline{13}{Initialize the conditions manager instance.}
+\docline{15-16}{Create an empty $ConditionsSlice$ instance the container with 
+                the desired conditions content.}
+\docline{18-19}{This is example specific and only a shortcut to fill the 
+             required conditions content and the derivation rules.\\
+             In real life this would be intrinsic to the experiment's 
+             data processing framework.}
+\docline{18}{Populate the $ConditionsContent$ instance with the addresses (keys) 
+             of the conditions required:
+             We scan the $DetElement$ hierarchy and add a couple of conditions
+             for each $DetElement$}
+\docline{19}{Add for each $DetElement$ 3 derived conditions,
+             which all depend on the persistent condition derived\_data.\\
+             In the real world this would be very specific derived actions.}
+
+\docline{22-31}{Emulate a pseudo event loop: Our conditions are of type "run".}
+\docline{23}{This is the IOV we want to use for this "processing step". 
+            The conditions filled into the slice during the prepare step will 
+            satisfy this IOV requirement.}
+\docline{24}{Conditions prepare step. Select the proper set of conditions 
+            from the store (or load them if needed). Attach the selected 
+            conditions to the user pool.}
+\docline{25-29}{Check the result of the prepare step. If anything would be missing,
+            the parameter r.missing of the return code would be non-zero.}
+\docline{30}{Emulate data processing algorithms: Here we only scan the 
+            $DetElement$ tree and print all conditions.\\
+            We know what we expect since we defined the content the same way!
+            In the printer we can access the conditions directly from the slice,
+            since the slice implements the $ConditionsMap$ interface.}
+\end{tabular}
 
 \newpage
 %=============================================================================
diff --git a/examples/Conditions/src/ConditionExample_manual.cpp b/examples/Conditions/src/ConditionExample_manual.cpp
index 11e96e403..7666223e6 100644
--- a/examples/Conditions/src/ConditionExample_manual.cpp
+++ b/examples/Conditions/src/ConditionExample_manual.cpp
@@ -17,9 +17,9 @@
    This plugin behaves like a main program.
    Invoke the plugin with something like this:
 
-   geoPluginRun -volmgr -destroy -plugin DD4hep_ConditionExample_manual \
+   geoPluginRun -volmgr -destroy -plugin DD4hep_ConditionExample_manual_load \
    -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml \
-   -conditions Conditions.root
+   -conditions Conditions.root -runs 10
 
    Save the conditions store by hand for a set of IOVs.
    Then compute the corresponding alignment entries....
@@ -29,6 +29,7 @@
 #include "ConditionExampleObjects.h"
 #include "DDCond/ConditionsIOVPool.h"
 #include "DDCond/ConditionsManager.h"
+#include "DDCond/ConditionsDataLoader.h"
 #include "DDCond/ConditionsRootPersistency.h"
 #include "DD4hep/Factories.h"
 
@@ -40,36 +41,33 @@ static void help(int argc, char** argv)  {
   /// Help printout describing the basic command line interface
   cout <<
     "Usage: -plugin <name> -arg [-arg]                                             \n"
-    "     name:   factory name     DD4hep_ConditionExample_manual                  \n"
+    "     name:   factory name     DD4hep_ConditionExample_manual_load             \n"
     "     -input       <string>    Geometry file                                   \n"
     "     -conditions  <string>    Conditions input file                           \n"
-    "     -iovs        <number>    Number of parallel IOV slots for processing.    \n"
-    "     -restore     <string>    Restore strategy: iovpool, userpool or condpool.\n"
+    "     -runs        <number>    Number of parallel IOV slots for processing.    \n"
     "\tArguments given: " << arguments(argc,argv) << endl << flush;
   ::exit(EINVAL);
 }
 
 /// Plugin function: Condition program example
 /**
- *  Factory: DD4hep_ConditionExample_manual
+ *  Factory: DD4hep_ConditionExample_manual_load
  *
  *  \author  M.Frank
  *  \version 1.0
  *  \date    01/12/2016
  */
 static int condition_example (Detector& description, int argc, char** argv)  {
-  string input, conditions, restore="iovpool";
-  int    num_iov = 10;
+  string input, conditions;
+  int    num_runs = 10;
   bool   arg_error = false;
   for(int i=0; i<argc && argv[i]; ++i)  {
     if ( 0 == ::strncmp("-input",argv[i],4) )
       input = argv[++i];
     else if ( 0 == ::strncmp("-conditions",argv[i],4) )
       conditions = argv[++i];
-    else if ( 0 == ::strncmp("-restore",argv[i],4) )
-      restore = argv[++i];
-    else if ( 0 == ::strncmp("-iovs",argv[i],4) )
-      num_iov = ::atol(argv[++i]);
+    else if ( 0 == ::strncmp("-runs",argv[i],4) )
+      num_runs = ::atol(argv[++i]);
     else
       arg_error = true;
   }
@@ -78,8 +76,7 @@ static int condition_example (Detector& description, int argc, char** argv)  {
   // First we load the geometry
   description.fromXML(input);
 
-  /******************** Initialize the conditions manager *****************/
-  // Now we instantiate the conditions manager
+  // Now we instantiate and initialize the conditions manager
   description.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0);
 
   ConditionsManager manager = ConditionsManager::from(description);
@@ -89,48 +86,38 @@ static int condition_example (Detector& description, int argc, char** argv)  {
   manager["LoaderType"]     = "root";
   manager.initialize();
 
+  printout(ALWAYS,"Example","Load conditions data from file:%s",conditions.c_str());
+  manager.loader()->addSource(conditions);
+
+  /// Create the container with the desired conditions content and an empty conditions slice
   shared_ptr<ConditionsContent> content(new ConditionsContent());
   shared_ptr<ConditionsSlice>   slice(new ConditionsSlice(manager,content));
-
+  
+  // Populate the content of required conditions:
+  // We scan the DetElement hierarchy and add a couple of conditions
+  // for each DetElement
   Scanner(ConditionsKeys(*content,INFO),description.world());
-  Scanner(ConditionsDependencyCreator(*content,DEBUG),description.world());
 
-  /******************** Load the conditions from file *********************/
-  {
-    auto pers = cond::ConditionsRootPersistency::load(conditions.c_str(),"DD4hep Conditions");
-    printout(ALWAYS,"Statistics","+=========================================================================");
-    printout(ALWAYS,"Statistics","+  Loaded conditions object from file %s. Took %8.3f seconds.",
-             conditions.c_str(),pers->duration);
-    size_t num_cond = 0;
-    if      ( restore == "iovpool" )
-      num_cond = pers->importIOVPool("ConditionsIOVPool No 1","run",manager);
-    else if ( restore == "userpool" )
-      num_cond = pers->importUserPool("*","run",manager);
-    else if ( restore == "condpool" )
-      num_cond = pers->importConditionsPool("*","run",manager);
-    else
-      help(argc,argv);
+  // Add for each DetElement 3 derived conditions,
+  // which all depend on the persistent condition "derived_data"
+  // (In the real world this would be very specific derived actions)
+  Scanner(ConditionsDependencyCreator(*content,DEBUG),description.world());
 
-    printout(ALWAYS,"Statistics","+  Imported %ld conditions from %s to IOV pool. Took %8.3f seconds.",
-             num_cond, restore.c_str(), pers->duration);
-    printout(ALWAYS,"Statistics","+=========================================================================");
-  }
-  // ++++++++++++++++++++++++ Now compute the conditions for each of these IOVs
+  // Now emulate a pseudo event loop: Our conditions are of type "run"
   const IOVType* iov_typ = manager.iovType("run");
-  cond::ConditionsIOVPool* pool = manager.iovPool(*iov_typ);
-  for( const auto& p : pool->elements )
-    p.second->print("*");
-
   ConditionsManager::Result total;
-  for(int i=0; i<num_iov; ++i)  {
-    IOV req_iov(iov_typ,i*10+5);
-    // Select the proper set of conditions and attach them to the user pool
+  for ( int irun=0; irun < num_runs; ++irun )  {
+    IOV req_iov(iov_typ,irun*10+5);
+    // Select the proper set of conditions from the store (or load them if needed)
+    // Attach the selected conditions to the user pool
     ConditionsManager::Result r = manager.prepare(req_iov,*slice);
     total += r;
-    if ( 0 == i )  { // First one we print...
+    if ( 0 == irun )  { // First one we print...
+      // We can access the conditions directly from the slice, since the slice
+      // implements the ConditionsMap interface.
       Scanner(ConditionsPrinter(slice.get(),"Example"),description.world());
     }
-    // Now compute the tranformation matrices
+    // Print summary
     printout(ALWAYS,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s",
              r.total(), r.selected, r.loaded, r.computed, r.missing, req_iov.str().c_str());
   }  
@@ -143,4 +130,4 @@ static int condition_example (Detector& description, int argc, char** argv)  {
 }
 
 // first argument is the type from the xml file
-DECLARE_APPLY(DD4hep_ConditionExample_manual,condition_example)
+DECLARE_APPLY(DD4hep_ConditionExample_manual_load,condition_example)
-- 
GitLab