diff --git a/src/Smearceptance/Smearcepterton.cxx b/src/Smearceptance/Smearcepterton.cxx index 88a2c7d..192a1e9 100644 --- a/src/Smearceptance/Smearcepterton.cxx +++ b/src/Smearceptance/Smearcepterton.cxx @@ -1,342 +1,345 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Smearcepterton.h" #include "EfficiencyApplicator.h" #include "GaussianSmearer.h" #include "MetaSimpleSmearcepter.h" #include "ThresholdAccepter.h" #include "TrackedMomentumMatrixSmearer.h" #include "VisECoalescer.h" #include #ifdef __USE_DYNSAMPLES__ #include "TRegexp.h" #include // linux #include DynamicSmearceptorFactory::DynamicSmearceptorFactory() : NSmearceptors(0), NManifests(0) { LoadPlugins(); QLOG(FIT, "Loaded " << NSmearceptors << " from " << NManifests << " shared object libraries."); } DynamicSmearceptorFactory* DynamicSmearceptorFactory::glblDSF = NULL; DynamicSmearceptorFactory::PluginManifest::~PluginManifest() { for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { (*(DSF_DestroySmearceptor))(Instances[i_it]); } } std::string EnsureTrailingSlash(std::string const& inp) { if (!inp.length()) { return "/"; } if (inp[inp.length() - 1] == '/') { return inp; } return inp + "/"; } void DynamicSmearceptorFactory::LoadPlugins() { std::vector SearchDirectories; if (Config::HasPar("dynamic_smearceptor.path")) { SearchDirectories = GeneralUtils::ParseToStr( Config::GetParS("dynamic_smearceptor.path"), ":"); } char const* envPath = getenv("NUISANCE_DS_PATH"); if (envPath) { std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { SearchDirectories.push_back(envPaths[ep_it]); } } if (!SearchDirectories.size()) { char const* pwdPath = getenv("PWD"); if (pwdPath) { SearchDirectories.push_back(pwdPath); } } for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); QLOG(FIT, "Searching for dynamic smearceptor manifests in: " << dirpath); Ssiz_t len = 0; DIR* dir; struct dirent* ent; dir = opendir(dirpath.c_str()); if (dir != NULL) { TRegexp matchExp("*.so", true); while ((ent = readdir(dir)) != NULL) { if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { QLOG(FIT, "\tFound shared object: " << ent->d_name << " checking for relevant methods..."); void* dlobj = dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); char const* dlerr_cstr = dlerror(); std::string dlerr; if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tDL Load Error: " << dlerr); continue; } PluginManifest plgManif; plgManif.dllib = dlobj; plgManif.soloc = (dirpath + ent->d_name); plgManif.DSF_NSmearceptors = reinterpret_cast( dlsym(dlobj, "DSF_NSmearceptors")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_NSmearceptors\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSmearceptorName = reinterpret_cast( dlsym(dlobj, "DSF_GetSmearceptorName")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSmearceptorName\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSmearceptor = reinterpret_cast( dlsym(dlobj, "DSF_GetSmearceptor")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSmearceptor\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_DestroySmearceptor = reinterpret_cast( dlsym(dlobj, "DSF_DestroySmearceptor")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "Failed to load symbol \"DSF_DestroySmearceptor\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.NSmearceptors = (*(plgManif.DSF_NSmearceptors))(); QLOG(FIT, "\tSuccessfully loaded dynamic smearceptor manifest: " << plgManif.soloc << ". Contains " << plgManif.NSmearceptors << " smearceptors."); for (size_t smp_it = 0; smp_it < plgManif.NSmearceptors; ++smp_it) { char const* smp_name = (*(plgManif.DSF_GetSmearceptorName))(smp_it); if (!smp_name) { THROW("Could not load smearceptor " << smp_it << " / " << plgManif.NSmearceptors << " from " << plgManif.soloc); } if (Smearceptors.count(smp_name)) { ERROR(WRN, "Already loaded a smearceptor named: \"" << smp_name << "\". cannot load duplciates. This " "smearceptor will be skipped."); continue; } plgManif.SmearceptorsProvided.push_back(smp_name); Smearceptors[smp_name] = std::make_pair(plgManif.soloc, smp_it); QLOG(FIT, "\t\t" << smp_name); } if (plgManif.SmearceptorsProvided.size()) { Manifests[plgManif.soloc] = plgManif; NSmearceptors += plgManif.SmearceptorsProvided.size(); NManifests++; } else { dlclose(dlobj); } } } closedir(dir); } else { ERROR(WRN, "Tried to open non-existant directory."); } } } DynamicSmearceptorFactory& DynamicSmearceptorFactory::Get() { if (!glblDSF) { glblDSF = new DynamicSmearceptorFactory(); } return *glblDSF; } void DynamicSmearceptorFactory::Print() { std::map > ManifestSmearceptors; for (std::map >::iterator smp_it = Smearceptors.begin(); smp_it != Smearceptors.end(); ++smp_it) { if (!ManifestSmearceptors.count(smp_it->second.first)) { ManifestSmearceptors[smp_it->second.first] = std::vector(); } ManifestSmearceptors[smp_it->second.first].push_back(smp_it->first); } QLOG(FIT, "Dynamic smearceptor manifest: "); for (std::map >::iterator m_it = ManifestSmearceptors.begin(); m_it != ManifestSmearceptors.end(); ++m_it) { QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { QLOG(FIT, "\t\t" << m_it->second[s_it]); } } } bool DynamicSmearceptorFactory::HasSmearceptor(std::string const& name) { return Smearceptors.count(name); } bool DynamicSmearceptorFactory::HasSmearceptor(nuiskey& smearceptorkey) { return HasSmearceptor(smearceptorkey.GetElementName()); } ISmearcepter* DynamicSmearceptorFactory::CreateSmearceptor( nuiskey& smearceptorkey) { if (!HasSmearceptor(smearceptorkey)) { ERROR(WRN, "Asked to load unknown smearceptor: \"" << smearceptorkey.GetElementName() << "\"."); return NULL; } std::pair smearceptor = Smearceptors[smearceptorkey.GetElementName()]; QLOG(SAM, "\tLoading smearceptor " << smearceptor.second << " from " << smearceptor.first); ISmearcepter* smear = (*(Manifests[smearceptor.first].DSF_GetSmearceptor))( smearceptor.second, &smearceptorkey); return smear; } DynamicSmearceptorFactory::~DynamicSmearceptorFactory() { Manifests.clear(); } #endif Smearcepterton* Smearcepterton::_inst = NULL; Smearcepterton& Smearcepterton::Get() { if (!_inst) { _inst = new Smearcepterton(); } return *_inst; } Smearcepterton::Smearcepterton() { InitialiserSmearcepters(); } void Smearcepterton::InitialiserSmearcepters() { // hard coded list of tag name -> smearcepter factories, add here to add your // own. std::map factories; factories["ThresholdAccepter"] = &BuildSmearcepter; factories["EfficiencyApplicator"] = &BuildSmearcepter; factories["GaussianSmearer"] = &BuildSmearcepter; factories["TrackedMomentumMatrixSmearer"] = &BuildSmearcepter; factories["VisECoalescer"] = &BuildSmearcepter; factories["MetaSimpleSmearcepter"] = &BuildSmearcepter; std::vector smearcepterBlocks = Config::QueryKeys("smearcepters"); for (size_t smearB_it = 0; smearB_it < smearcepterBlocks.size(); ++smearB_it) { std::vector smearcepters = smearcepterBlocks[smearB_it].GetListOfChildNodes(); for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { std::string const& smearType = smearcepters[smear_it].GetElementName(); ISmearcepter* smearer = NULL; +#ifdef __USE_DYNSAMPLES__ if (DynamicSmearceptorFactory::Get().HasSmearceptor(smearType)) { smearer = DynamicSmearceptorFactory::Get().CreateSmearceptor( smearcepters[smear_it]); - } else { + } else +#endif + { if (!factories.count(smearType)) { ERROR(WRN, "No known smearer accepts elements named: \"" << smearType << "\""); continue; } smearer = factories[smearType](smearcepters[smear_it]); } if (!smearer) { THROW("Failed to load smearceptor."); } if (!smearer->GetName().length()) { THROW("Smearcepter type " << smearer->GetElementName() << " had no instance name."); } Smearcepters[smearer->GetName()] = smearer; QLOG(FIT, "Configured smearer named: " << smearer->GetName() << " of type: " << smearer->GetElementName()); } } }