CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/CondFormats/PhysicsToolsObjects/src/MVAComputer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     PhysicsToolsObjects
00004 // Class  :     MVAComputer
00005 // 
00006 
00007 // Implementation:
00008 //     getProcessor() and addProcessor() methods to add processors to
00009 //     the discriminator computer calibration object. POOL doesn't support
00010 //     polymorph pointers, so this is implemented using multiple containers
00011 //     for each possible sub-class and an index array from which the
00012 //     array of pointers can be reconstructed. In order to avoid having
00013 //     to handle each sub-class container by hand here, the generated
00014 //     reflex dictionary is used to find and read/write the std::vector<...>
00015 //     containers for the individual classes in the private data members.
00016 //     So changes can be solely done in the header files and does not leave
00017 //     a trail elsewhere.
00018 //
00019 // Author:      Christophe Saout
00020 // Created:     Sat Apr 24 15:18 CEST 2007
00021 // $Id: MVAComputer.cc,v 1.10 2010/01/26 19:40:03 saout Exp $
00022 //
00023 #include <functional>
00024 #include <algorithm>
00025 #include <typeinfo>
00026 #include <iostream>
00027 #include <cstring>
00028 #include <cstddef>
00029 
00030 #include <boost/thread.hpp>
00031 
00032 #include <Reflex/Reflex.h>
00033 
00034 #include "FWCore/Utilities/interface/Exception.h"
00035 
00036 #include "CondFormats/PhysicsToolsObjects/interface/MVAComputer.h"
00037 
00038 namespace PhysicsTools {
00039 namespace Calibration {
00040 
00041 std::string VarProcessor::getInstanceName() const
00042 {
00043         static const char prefix[] = "PhysicsTools::Calibration::";
00044         std::string type = ROOT::Reflex::Tools::Demangle(typeid(*this));
00045         if (type.size() <= sizeof prefix - 1 ||
00046             type.substr(0, sizeof prefix - 1) != prefix)
00047                 throw cms::Exception("MVAComputerCalibration")
00048                         << "getInstanceName failed for "
00049                         << typeid(*this).name() << "." << std::endl;
00050 
00051         return type.substr(sizeof prefix - 1);
00052 }
00053 
00054 std::string ProcExternal::getInstanceName() const
00055 {
00056         return method;
00057 }
00058 
00059 static MVAComputer::CacheId getNextMVAComputerCacheId()
00060 {
00061         static boost::mutex mutex;
00062         static MVAComputer::CacheId nextCacheId = 0;
00063 
00064         boost::mutex::scoped_lock scoped_lock(mutex);
00065         return ++nextCacheId;
00066 }
00067 
00068 MVAComputer::MVAComputer() :
00069         cacheId(getNextMVAComputerCacheId())
00070 {
00071 }
00072 
00073 MVAComputer::MVAComputer(const MVAComputer &orig) :
00074         inputSet(orig.inputSet),
00075         output(orig.output),
00076         cacheId(orig.cacheId)
00077 {
00078         for(std::vector<VarProcessor*>::const_iterator iter =
00079                                                 orig.processors.begin();
00080             iter != orig.processors.end(); ++iter)
00081                 addProcessor(*iter);
00082 }
00083 
00084 MVAComputer::~MVAComputer()
00085 {
00086         for(std::vector<VarProcessor*>::iterator iter = processors.begin();
00087             iter != processors.end(); ++iter)
00088                 delete *iter;
00089         processors.clear();
00090 }
00091 
00092 MVAComputer &MVAComputer::operator = (const MVAComputer &orig)
00093 {
00094         inputSet = orig.inputSet;
00095         output = orig.output;
00096         cacheId = orig.cacheId;
00097 
00098         for(std::vector<VarProcessor*>::iterator iter = processors.begin();
00099             iter != processors.end(); ++iter)
00100                 delete *iter;
00101         processors.clear();
00102 
00103         for(std::vector<VarProcessor*>::const_iterator iter =
00104                                                 orig.processors.begin();
00105             iter != orig.processors.end(); ++iter)
00106                 addProcessor(*iter);
00107 
00108         return *this;
00109 }
00110 
00111 std::vector<VarProcessor*> MVAComputer::getProcessors() const
00112 {
00113         return processors;
00114 }
00115 
00116 void MVAComputer::addProcessor(const VarProcessor *proc)
00117 {
00118         cacheId = getNextMVAComputerCacheId();
00119 
00120         ROOT::Reflex::Type baseType = ROOT::Reflex::GetType<VarProcessor>();
00121         ROOT::Reflex::Type type =
00122                                 ROOT::Reflex::Type::ByTypeInfo(typeid(*proc));
00123         ROOT::Reflex::Type refType(type,
00124                                 ROOT::Reflex::CONST & ROOT::Reflex::REFERENCE);
00125         if (!type.Name().size())
00126                 throw cms::Exception("MVAComputerCalibration")
00127                         << "Calibration class " << typeid(*proc).name()
00128                         << " not registered with ROOT::Reflex."
00129                         << std::endl;
00130 
00131         ROOT::Reflex::Object obj =
00132                 ROOT::Reflex::Object(baseType, const_cast<void*>(
00133                         static_cast<const void*>(proc))).CastObject(type);
00134 
00135         // find and call copy constructor
00136         for(ROOT::Reflex::Member_Iterator iter = type.FunctionMember_Begin();
00137             iter != type.FunctionMember_End(); iter++) {
00138                 const ROOT::Reflex::Type &ctor = iter->TypeOf();
00139                 if (!iter->IsConstructor() ||
00140                     ctor.FunctionParameterSize() != 1 ||
00141                     ctor.FunctionParameterAt(0).Id() != refType.Id())
00142                         continue;
00143 
00144                 ROOT::Reflex::Object copy = type.Construct(ctor,
00145                         ROOT::Reflex::Tools::MakeVector<void*>(obj.Address()));
00146 
00147                 processors.push_back(static_cast<VarProcessor*>(copy.Address()));
00148                 return;
00149         }
00150 
00151         throw cms::Exception("MVAComputerCalibration")
00152                         << "Calibration class " << typeid(*proc).name()
00153                         << " has no copy ctor registered with ROOT::Reflex."
00154                         << std::endl;
00155 }
00156 
00157 static MVAComputerContainer::CacheId getNextMVAComputerContainerCacheId()
00158 {
00159         static MVAComputerContainer::CacheId nextCacheId = 0;
00160         return ++nextCacheId;
00161 }
00162 
00163 MVAComputerContainer::MVAComputerContainer() :
00164         cacheId(getNextMVAComputerContainerCacheId())
00165 {
00166 }
00167 
00168 MVAComputer &MVAComputerContainer::add(const std::string &label)
00169 {
00170         cacheId = getNextMVAComputerContainerCacheId();
00171 
00172         entries.push_back(std::make_pair(label, MVAComputer()));
00173         return entries.back().second;
00174 }
00175 
00176 namespace {
00177         struct Comparator :
00178                 public std::unary_function<const std::string&, bool> {
00179 
00180                 inline Comparator(const std::string &label) : label(label) {}
00181 
00182                 inline bool
00183                 operator () (const MVAComputerContainer::Entry &entry) const
00184                 { return entry.first == label; }
00185 
00186                 const std::string &label;
00187         };
00188 }
00189 
00190 const MVAComputer &MVAComputerContainer::find(const std::string &label) const
00191 {
00192         std::vector<Entry>::const_iterator pos =
00193                                 std::find_if(entries.begin(), entries.end(),
00194                                              Comparator(label));
00195 
00196         if (pos == entries.end())
00197                 throw cms::Exception("MVAComputerCalibration")
00198                         << "Calibration record " << label
00199                         << " not found in MVAComputerContainer." << std::endl;
00200 
00201         return pos->second;
00202 }
00203 
00204 } // namespace Calibration
00205 } // namespace PhysicsTools