diff --git a/plotting/plottingUtils/CMakeLists.txt b/plotting/plottingUtils/CMakeLists.txt index 004c0337..dceb7be4 100644 --- a/plotting/plottingUtils/CMakeLists.txt +++ b/plotting/plottingUtils/CMakeLists.txt @@ -17,7 +17,7 @@ set_target_properties( Plotting PROPERTIES EXPORT_NAME Plotting ) -target_link_libraries( Plotting ${ROOT_LIBRARIES} MaCh3::Manager ) +target_link_libraries( Plotting MaCh3::Manager MaCh3::MCMC ) ## to be compiled into python module needs to be compiled as position independent library if( MaCh3_PYTHON_ENABLED ) diff --git a/plotting/plottingUtils/inputManager.cpp b/plotting/plottingUtils/inputManager.cpp index 8e9e6981..a2102d39 100644 --- a/plotting/plottingUtils/inputManager.cpp +++ b/plotting/plottingUtils/inputManager.cpp @@ -1,7 +1,5 @@ #include "inputManager.h" -// EM: will move this somewhere more sensible -#define BAD_FLOAT -999.999 namespace MaCh3Plotting { // this is the constructor with user specified translation config file @@ -71,14 +69,13 @@ InputManager::InputManager(const std::string &translationConfigName) { /// - Push back a pointer to the InputFile objcet to the vector of files known to this /// InputManager. void InputManager::addFile(const std::string &fileName) { - InputFile fileInfo(fileName); + _fileVec.emplace_back(fileName); // EM: need to be done in this order since fillFileData needs to know info about the file, e.g. // fitter and what things are in it + InputFile &fileInfo = _fileVec.back(); fillFileInfo(fileInfo); fillFileData(fileInfo); - - _fileVec.push_back(fileInfo); } /// If printLevel is "summary", will loop through all the files known to this InputManager and call @@ -135,9 +132,9 @@ float InputManager::getPostFitError(int fileNum, const std::string ¶mName, return inputFileDef.postFitErrors.at(errorType).at(paramName); } - MACH3LOG_WARN("Didn't fnd {} post fit error for {}. Returning {}", errorType, paramName, BAD_FLOAT); + MACH3LOG_WARN("Didn't fnd {} post fit error for {}. Returning {}", errorType, paramName, _BAD_DOUBLE_); - return BAD_FLOAT; + return _BAD_DOUBLE_; } float InputManager::getPostFitValue(int fileNum, const std::string ¶mName, @@ -164,9 +161,9 @@ float InputManager::getPostFitValue(int fileNum, const std::string ¶mName, return inputFileDef.postFitValues.at(errorType).at(paramName); } - MACH3LOG_WARN("Didn't fnd {} post fit value for {}. Returning {}", errorType, paramName, BAD_FLOAT); + MACH3LOG_WARN("Didn't fnd {} post fit value for {}. Returning {}", errorType, paramName, _BAD_DOUBLE_); - return BAD_FLOAT; + return _BAD_DOUBLE_; } @@ -238,7 +235,7 @@ std::vector InputManager::getTaggedValues(const std::vector InputManager::parseLocation(const std::string &rawLocationString, std::string &fitter, fileTypeEnum fileType, const std::string ¶meter, - const std::string &sample) const { + const std::string &sample, const std::string ¶meter2) const { std::string locationString(rawLocationString); std::vector tokens; @@ -263,6 +260,15 @@ std::vector InputManager::parseLocation(const std::string &rawLocat getFitterSpecificSampleName(fitter, fileType, sample)); } + // loop through the raw location string and replace any instance of {PARAMETER2} with the name of + // the second specified parameter + toReplace = "{PARAMETER2}"; + while ((pos = locationString.find(toReplace)) != std::string::npos) + { + locationString.replace(pos, toReplace.length(), + getFitterSpecificParamName(fitter, fileType, parameter2)); + } + // Now we go through and look for ":" and split the location into two parts // first part should be the directory to look for the parameter // lats part should be the end of the name of the object to look for @@ -400,6 +406,77 @@ bool InputManager::findBySampleLLH(InputFile &inputFileDef, const std::string &p return true; } +// check the input file for raw MCMC step values for a particular parameter +bool InputManager::findRawChainSteps(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, bool setInputBranch) const { + // we'll assume for now that the chain is in the form of a TTree and the branch names are parameter names + + bool wasFound = false; + + // make sure that the filedef object has all the necessary stuff to read from the posterior tree + if ( (inputFileDef.mcmcProc != nullptr) && (inputFileDef.posteriorTree != nullptr) ) + { + + const std::vector branchNames = inputFileDef.mcmcProc->GetBranchNames(); + + std::string specificName = getFitterSpecificParamName(fitter, kMCMC, parameter); + + // loop over possible parameters and compare names + for ( int paramIdx = 0; paramIdx < inputFileDef.mcmcProc->GetNParams() -1 ; paramIdx ++ ) + { + TString title; + double prior, priorError; // <- will be discarded + inputFileDef.mcmcProc->GetNthParameter(paramIdx, prior, priorError, title); + + if ( strEndsWith(title.Data(), specificName) ) + { + wasFound = true; + if ( setInputBranch ) + { + // EM: should probably use MCMCProcessor for this so we can use caching, gpu etc. + inputFileDef.MCMCstepParamsMap[parameter] = new double( _BAD_DOUBLE_ ); // <- initialise the parameter step values + inputFileDef.posteriorTree->SetBranchAddress( branchNames[paramIdx], inputFileDef.MCMCstepParamsMap.at(parameter) ); + } + + break; + } + } + } + + return wasFound; + +} + +// check the input file for processed 1d posteriors for a particular parameter +bool InputManager::find1dPosterior(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, bool setFileData) const { + + bool wasFound = false; + + YAML::Node thisFitterSpec_config = _fitterSpecConfig[fitter]; + + if ( thisFitterSpec_config["1dPosteriors"] ) { + std::vector rawLocations = thisFitterSpec_config["1dPosteriors"]["location"].as>(); + + for ( const std::string &rawLoc : rawLocations) + { + std::shared_ptr posterior1d = std::static_pointer_cast(findRootObject(inputFileDef, parseLocation(rawLoc, fitter, kMCMC, parameter))); + + if ( posterior1d != nullptr ) + { + wasFound = true; + + if ( setFileData ) + { + inputFileDef.posteriors1d_map[parameter] = std::make_shared(posterior1d.get()); + } + break; + } + } + + } + + return wasFound; +} + bool InputManager::findPostFitParamError(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, const std::string &errorType, bool setInputFileError) { @@ -616,6 +693,95 @@ void InputManager::fillFileInfo(InputFile &inputFileDef, bool printThoughts) { } } + // ######### Now for the main event: Look for MCMC chains and processed posteriors ########### + + // EM: if "MCMCsteps" was defined for this fitter, we assume that it is a MaCh3 raw MCMC file + // thus it needs an MCMCProcessor to read from it. This isn't super general and it would probably + // be good to have some additional "isMaCh3" option that can decide whether or not to use MCMCProcessor + // but hey ho it's good enough for now + if ( thisFitterSpec_config["MCMCsteps"] ) + { + MACH3LOG_DEBUG("Initialising MCMCProcessor for the input file"); + std::vector posteriorTreeRawLocations = thisFitterSpec_config["MCMCsteps"]["location"].as>(); + + TTree *postTree = NULL; + for ( const std::string &rawLoc: posteriorTreeRawLocations ) + { + MACH3LOG_DEBUG(" - Looking for MCMC chain parameter values at: {}", rawLoc); + + TObject *postTreeObj = inputFileDef.file->Get(rawLoc.c_str()); + + if ( postTreeObj != NULL ) + { + postTree = (TTree *) postTreeObj; + inputFileDef.mcmcProc = new MCMCProcessor(inputFileDef.fileName); + inputFileDef.mcmcProc->Initialise(); + + MACH3LOG_DEBUG(" - FOUND!"); + break; + } + } + + if ( postTree != NULL ) + { + inputFileDef.posteriorTree = postTree; + inputFileDef.nMCMCentries = postTree->GetEntries(); + } + } + + if (printThoughts) + { + MACH3LOG_INFO("....Searching for MCMC related things"); + } + + size_t num1dPosteriors = 0; + std::vector enabled1dPosteriorParams; + + size_t numMCMCchainParams = 0; + std::vector enabledMCMCchainParams; + + for ( const std::string ¶meter : _knownParameters ) + { + MACH3LOG_DEBUG(" - for {}", parameter); + // check for 1d post processing posterior.q + inputFileDef.availableParams_map_1dPosteriors[parameter] = false; + if ( thisFitterSpec_config["1dPosteriors"] && find1dPosterior(inputFileDef, parameter, fitter) ) + { + MACH3LOG_DEBUG(" Found 1d processed posterior!"); + enabled1dPosteriorParams.push_back(parameter); + num1dPosteriors++; + inputFileDef.availableParams_map_1dPosteriors[parameter] = true; + } + // now check for parameters in chain + inputFileDef.availableParams_map_MCMCchain[parameter] = false; + if ( thisFitterSpec_config["MCMCsteps"] && findRawChainSteps(inputFileDef, parameter, fitter) ) + { + MACH3LOG_DEBUG(" Found raw MCMC steps!"); + enabledMCMCchainParams.push_back(parameter); + numMCMCchainParams++; + inputFileDef.availableParams_map_MCMCchain[parameter] = true; + } + } + + if (num1dPosteriors > 0 ) + { + foundFitter = true; + inputFileDef.has1dPosteriors = true; + inputFileDef.availableParams_1dPosteriors = enabled1dPosteriorParams; + + if (printThoughts) + MACH3LOG_INFO("........ Found {} 1d processed posteriors", num1dPosteriors); + } + if ( numMCMCchainParams > 0 ) + { + foundFitter = true; + inputFileDef.hasMCMCchain = true; + inputFileDef.availableParams_MCMCchain = enabledMCMCchainParams; + + if (printThoughts) + MACH3LOG_INFO("........ Found {} parameters in MCMC chain", numMCMCchainParams); + } + /* switch (i) { // any other weird fitter specific conditions/ edge cases should go in here @@ -732,6 +898,16 @@ void InputManager::fillFileData(InputFile &inputFileDef, bool printThoughts) { findPostFitParamError(inputFileDef, parameter, inputFileDef.fitter, errorType, true); } } + + // ########## Get the MCMC related posteriors ########### + for (const std::string ¶meter : inputFileDef.availableParams_MCMCchain) + { + findRawChainSteps(inputFileDef, parameter, inputFileDef.fitter, true); + } + for (const std::string ¶meter : inputFileDef.availableParams_1dPosteriors) + { + find1dPosterior(inputFileDef, parameter, inputFileDef.fitter, true); + } } } // namespace MaCh3Plotting diff --git a/plotting/plottingUtils/inputManager.h b/plotting/plottingUtils/inputManager.h index aad81e79..46446e1a 100644 --- a/plotting/plottingUtils/inputManager.h +++ b/plotting/plottingUtils/inputManager.h @@ -4,6 +4,8 @@ #include "manager/MaCh3Logger.h" #include "manager/YamlHelper.h" #include "manager/MaCh3Exception.h" +#include "mcmc/MCMCProcessor.h" +#include "samplePDF/Structs.h" // Other plotting includes #include "plottingUtils.h" @@ -14,7 +16,7 @@ namespace MaCh3Plotting { enum fileTypeEnum { kLLH, //!< Log Likelihood scan kPostFit, //!< Processed post fit errors - kMarkovChain, //!< MCMC chain + kMCMC, //!< MCMC chain kSigmaVar, //!< Sigma variations kNFileTypes //!< Number of types of file @@ -54,14 +56,25 @@ struct InputFile { } } + // NO COPYING!! + InputFile( const InputFile& ) = delete; + // Moving ok + InputFile( InputFile&& ) = default; + // EM: ^^ there should only really be one instance of an InputFile for each + // underlying root file. If copying is allowed then it can lead to bad bad things + // like pointers getting deleted and then trying to be accessed by a copied + // InputFile instance + /// @brief Destructor. ~InputFile() { + MACH3LOG_DEBUG("###### Deleting InputFile Object holding file ######"); LLHScans_map.clear(); } /// @brief Close out the underlying root file /// @details Should only be done once this InputFile is *done* with, should only really ever be done by the InputManager that holds this object void Close(){ + MACH3LOG_DEBUG("[InputFile] closing file {}", fileName); file->Close(); } @@ -92,6 +105,10 @@ struct InputFile { } } + /// ptr to an MCMCProcessor instance to be used if this is a MaCh3 input file + MCMCProcessor *mcmcProc; + TTree *posteriorTree; + std::shared_ptr file; //!< Pointer to the underlying file for this InputFile instance. std::string fileName; //!< The location of the underlying file. @@ -146,9 +163,28 @@ struct InputFile { postFitValues; //!< The post fit values of the parameters, organised as //!< postFitValues.at(errorType).at(parameter). std::string defaultErrorType; - // TH1D *postFitErrors; //!< Pointer to the TH1D with named bins that contain the post fit value - // and errors. + // Stuff relating to MCMC + /// Whether or not the file has processed 1d posteriors + bool has1dPosteriors; + /// Whether or not the file has unprocessed MCMC chain steps + bool hasMCMCchain; + + /// The number of steps in the MCMC chain + int nMCMCentries; + + /// whether or not specific parameters exist in the MCMC posterior chain + std::unordered_map availableParams_map_MCMCchain; + std::unordered_map availableParams_map_1dPosteriors; + + std::vector availableParams_1dPosteriors; + std::vector availableParams_MCMCchain; + + std::unordered_map MCMCstepParamsMap; + std::unordered_map MCMCstepTreeIndicesMap; + + std::unordered_map> posteriors1d_map; + // EM: almost certainly won't want to load all of these into memory at the start bool hasSigmaVars; //!< Whether or not this file contains Sigma variations. }; @@ -195,7 +231,8 @@ class InputManager { /// @details Close out all the files that the manager is responsible for ~InputManager() { - for (InputFile file: _fileVec) + MACH3LOG_DEBUG("##### Deleting InputManager Instance #####"); + for (InputFile &file: _fileVec) { file.Close(); } @@ -203,6 +240,15 @@ class InputManager { _fileVec.clear(); } + // NO COPYING! + InputManager(const InputManager&) = delete; + // moving is ok + InputManager(InputManager&&) = default; + // EM: ^^ Do this as there should only ever really be one instance of the + // InputManager (should maybe make it a singleton actually) + // if copied then it can lead to things being deleted that we really don't + // want to be deleted + /// @brief Convert from fileTypeEnum to the name of the file type. /// @param fileType The file type ID to convert. /// @return The name of the file type, or "UNKNOWN_FILE_TYPE" if the fileType does not match any @@ -214,8 +260,8 @@ class InputManager { return "LLH"; case kPostFit: return "PostFit"; - case kMarkovChain: - return "MarkovChain"; + case kMCMC: + return "MCMC"; case kSigmaVar: return "SigmaVar"; @@ -246,6 +292,61 @@ class InputManager { return TGraphToVector(*_fileVec[fileNum].LLHScans_map.at(LLHType).at(paramName)); } + /// @brief Get the MCMC chain entry in an InputFile. + /// @param fileNum The index of the file you want the data from. + /// @param entry The entry to get. + void getMCMCentry(int fileNum, int entry) const { + // EM: the const here is a little bit of a lie since GetEntry will in fact modify + // the pointers to the stored data for the MCMC chain values but hopefully this should be ok + const InputFile &file = _fileVec[fileNum]; + + if( entry > file.nMCMCentries ) + { + MACH3LOG_ERROR("Trying to access entries beyond what exist in file {}. No-can-do!", file.fileName); + } + else + { + MACH3LOG_TRACE("Getting entry {} in MCMC tree for file at index {}", entry, fileNum); + file.posteriorTree->GetEntry(entry); + MACH3LOG_TRACE(" Got successfuly"); + } + } + + /// @brief Get the parameter value for the current step for a particular parameter from a particular input file. + /// @param fileNum The index of the file you want the data from. + /// @param paramName The parameter you want the value of. + double getMCMCvalue(int fileNum, std::string paramName) const { + if (!getEnabledMCMCchain(fileNum, paramName)) + { + MACH3LOG_WARN("file at index {} does not have an MCMC entry for parameter {}", fileNum, paramName); + MACH3LOG_WARN("am returning a bad float"); + return _BAD_DOUBLE_; + } + + return *_fileVec[fileNum].MCMCstepParamsMap.at(paramName); + + } + + /// @brief Get the 1d posterior particular parameter from a particular input file. + /// @param fileNum The index of the file you want the data from. + /// @param paramName The parameter you want the information about. + /// @return A vector of vectors containing the posterior data. First entry is x axis (i.e. the parameter values), 2nd is y axis + std::vector> get1dPosterior(int fileNum, std::string paramName) const { + if (!getEnabled1dPosteriors(fileNum, paramName)) + { + MACH3LOG_WARN("file at index {} does not have a 1d posterior for parameter {}", fileNum, paramName); + MACH3LOG_WARN("am returning an empty vector"); + return std::vector>(2); + } + return TGraphToVector(*_fileVec[fileNum].posteriors1d_map.at(paramName)); + } + + /// @brief Get the number of entries in the MCMC chain in a particular file. + /// @param fileNum The index of the file you want the number of steps from. + int getnMCMCentries(int fileNum) const { + return _fileVec[fileNum].nMCMCentries; + } + /// @brief Get the log likelihood scan for a particular parameter from a particular input file. /// @param fileNum The index of the file that you would like to get the scan from. /// @param paramName The name of the parameter whose LLH scan you would like. @@ -331,6 +432,22 @@ class InputManager { return _fileVec[fileNum].availableParams_map_LLHBySample.at(sample).at(paramName); } + /// @brief Get whether or not a particular parameter has MCMC chain entries in a particular input file. + /// @param fileNum The index of the file that you would like to know about. + /// @param paramName The name of the parameter whose LLH scan you would like to check for. + /// @return true if scan exists, false if not. + inline bool getEnabledMCMCchain(int fileNum, std::string paramName) const { + return _fileVec[fileNum].availableParams_map_MCMCchain.at(paramName); + } + + /// @brief Get whether or not a particular parameter has 1d posteriors in a particular input file. + /// @param fileNum The index of the file that you would like to know about. + /// @param paramName The name of the parameter whose 1d posterior you would like to check for. + /// @return true if scan exists, false if not. + inline bool getEnabled1dPosteriors(int fileNum, std::string paramName) const { + return _fileVec[fileNum].availableParams_map_1dPosteriors.at(paramName); + } + /// @brief Get the post fit error for a particular parameter from a particular input file. /// @param fileNum The index of the file that you would like to get the value from. /// @param paramName The name of the parameter whose error you would like. @@ -380,7 +497,7 @@ class InputManager { /// @name File Specific Getters /// @{ - inline InputFile getFile(int fileId) const { return _fileVec[fileId]; } + inline InputFile const &getFile(int fileId) const { return _fileVec[fileId]; } inline std::string translateName(int fileId, fileTypeEnum fileType, std::string paramName) const { return getFitterSpecificParamName(_fileVec[fileId].fitter, fileType, paramName); } @@ -393,6 +510,12 @@ class InputManager { inline const std::vector &getKnownPostFitParameters(int fileId) const { return _fileVec[fileId].availableParams_postFitErrors; } + inline const std::vector &getKnownMCMCParameters(int fileId) const { + return _fileVec[fileId].availableParams_MCMCchain; + } + inline const std::vector &getKnown1dPosteriorParameters(int fileId) const { + return _fileVec[fileId].availableParams_1dPosteriors; + } /// @} private: @@ -413,7 +536,7 @@ class InputManager { // look for in that directory std::vector parseLocation(const std::string &locationString, std::string &fitter, fileTypeEnum fileType, const std::string ¶meter = "", - const std::string &sample = "") const; + const std::string &sample = "", const std::string ¶meter2 = "") const; // helper function to look for an object defined by a vector of strings [ (directory to look in), // (end of the name of the object) ] this just calls roots TDirectoryFile->Get() function so @@ -432,6 +555,12 @@ class InputManager { bool findBySampleLLH(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, const std::string &sample, bool setInputFileScan = false); + // check the input file for raw MCMC step values for a particular parameter + bool findRawChainSteps(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, bool setInputBranch = false ) const ; + + // check the input file for processed 1d posteriors for a particular parameter + bool find1dPosterior(InputFile &inputFileDef, const std::string ¶meter, std::string &fitter, bool setFileData = false) const ; + // fns tp read an input file void fillFileInfo(InputFile &inputFileDef, bool printThoughts = true); void fillFileData(InputFile &inputFileDef, bool printThoughts = true); diff --git a/plotting/plottingUtils/plottingManager.cpp b/plotting/plottingUtils/plottingManager.cpp index 9344f6e6..eb36e16c 100644 --- a/plotting/plottingUtils/plottingManager.cpp +++ b/plotting/plottingUtils/plottingManager.cpp @@ -29,6 +29,7 @@ void PlottingManager::initialise() { /// to find an option at runtime _plottingConfig = YAML::LoadFile(_configFileName); + MACH3LOG_DEBUG("Initialising PlottingManager with plotting congif {}", _configFileName); // read options from the config YAML::Node managerOptions = _plottingConfig["ManagerOptions"]; @@ -36,14 +37,20 @@ void PlottingManager::initialise() { if (translationConfig == "") { translationConfig = DEFAULT_TRANSLATION_CONFIG; + MACH3LOG_DEBUG("PlottingManager: Using default translation config file name"); } + + MACH3LOG_DEBUG("PlottingManager: Using translation config file: {}", translationConfig); std::string styleConfig = managerOptions["styleConfig"].as(); if (styleConfig == "") { styleConfig = DEFAULT_STYLE_CONFIG; + MACH3LOG_DEBUG("PlottingManager: Using default style config file name"); } + MACH3LOG_DEBUG("PlottingManager: Using style config file: {}", styleConfig); + // create the StyleManager _styleMan = std::make_unique(styleConfig); diff --git a/plotting/plottingUtils/plottingManager.h b/plotting/plottingUtils/plottingManager.h index 4cffa269..52727ef5 100644 --- a/plotting/plottingUtils/plottingManager.h +++ b/plotting/plottingUtils/plottingManager.h @@ -66,6 +66,7 @@ class PlottingManager { void initialise(); ~PlottingManager() { + MACH3LOG_DEBUG("##### Deleting PlottingManager Instance #####"); } /// @brief Parse command line arguments. diff --git a/plotting/plottingUtils/plottingUtils.cpp b/plotting/plottingUtils/plottingUtils.cpp index 74f8e27a..1ba4a151 100644 --- a/plotting/plottingUtils/plottingUtils.cpp +++ b/plotting/plottingUtils/plottingUtils.cpp @@ -80,4 +80,31 @@ std::vector> TGraphToVector(TGraph graph) { return ret; } + +std::vector> TGraphToVector(TGraph2D graph) { + + int nPoints = graph.GetN(); + std::vector> ret(3); + std::vector pointsX(nPoints); + std::vector pointsY(nPoints); + std::vector pointsZ(nPoints); + + // Get the points out + Double_t x, y, z; + + for (int pointId = 0; pointId < nPoints; pointId++) + { + graph.GetPoint(pointId, x, y, z); + pointsX[pointId] = x; + pointsY[pointId] = y; + pointsZ[pointId] = z; + } + + ret[0] = pointsX; + ret[1] = pointsY; + ret[2] = pointsZ; + + return ret; +} + } // namespace MaCh3Plotting diff --git a/plotting/plottingUtils/plottingUtils.h b/plotting/plottingUtils/plottingUtils.h index 04287029..d9808dcd 100644 --- a/plotting/plottingUtils/plottingUtils.h +++ b/plotting/plottingUtils/plottingUtils.h @@ -12,6 +12,7 @@ // ROOT #include "TCanvas.h" +#include "TGraph2D.h" #include "TColor.h" #include "TDirectory.h" #include "TFile.h" @@ -27,6 +28,7 @@ #include "TLine.h" #include "TROOT.h" #include "TStyle.h" +#include "TMultiGraph.h" namespace MaCh3Plotting { /// @defgroup Utils Plotting Utility Functions @@ -46,5 +48,12 @@ TH1D TGraphToTH1D(TGraph graph, std::string newName = "", std::string newTitle = /// @return A vector of vectors containing the data from the initial graph. The first vector is the x axis, the 2nd the y axis std::vector> TGraphToVector(TGraph graph); + +/// @brief This handy little function lets you interpret a 2d TGraph as a vector containing the same data. +/// @param graph The graph you want to convert. +/// @return A vector of vectors containing the data from the initial graph. The first vector is the x axis, the 2nd the y axis, the 3rd is the z axis +std::vector> TGraphToVector(TGraph2D graph); + + /// @} } // namespace MaCh3Plotting diff --git a/plotting/plottingUtils/pythonPlottingModule.cpp b/plotting/plottingUtils/pythonPlottingModule.cpp index 43a2a5d4..708f579b 100644 --- a/plotting/plottingUtils/pythonPlottingModule.cpp +++ b/plotting/plottingUtils/pythonPlottingModule.cpp @@ -34,8 +34,8 @@ void initPlotting(py::module &m){ .def("get_split_by_sample", &MaCh3Plotting::PlottingManager::getSplitBySample, "Get whether or not the user has set the 'split by sample' (-s) option") .def("get_plot_ratios", &MaCh3Plotting::PlottingManager::getPlotRatios, "Get whether or not the user specified the 'plot ratios' (-r) option") .def("get_draw_grid", &MaCh3Plotting::PlottingManager::getDrawGrid, "Get wheter or not the user has specified the 'draw grid' (-g) option") - .def("style", &MaCh3Plotting::PlottingManager::style, "Get the StyleManager associated with this PlottingManager") - .def("input", &MaCh3Plotting::PlottingManager::input, "Get the InputManager associated with this PlottingManager") + .def("style", &MaCh3Plotting::PlottingManager::style, py::return_value_policy::reference, "Get the StyleManager associated with this PlottingManager") + .def("input", &MaCh3Plotting::PlottingManager::input, py::return_value_policy::reference, "Get the InputManager associated with this PlottingManager") // EM: I can't figure out how to add the getOption methods as theres not really a way to deduce the return type from yaml so leaving them out for now :/ // I think one solution would be to extend the PlottingManager class inside of python (add a pyPlottingManager (or something like that) that derives @@ -58,6 +58,12 @@ void initPlotting(py::module &m){ .def("get_known_llh_parameters", &MaCh3Plotting::InputManager::getKnownLLHParameters, "Get all the parameters that a file has LLH scans for") .def("get_known_llh_samples", &MaCh3Plotting::InputManager::getKnownLLHSamples, "Get all the samples that a file has individual LLH scans for") .def("get_known_post_fit_parameters", &MaCh3Plotting::InputManager::getKnownPostFitParameters, "Get all the parameters that a file has post fit values and errors for") + .def("get_known_MCMC_parameters", &MaCh3Plotting::InputManager::getKnownMCMCParameters, "Get all the parameters that a file has MCMC chain entries for") + .def("get_known_1d_posterior_parameters", &MaCh3Plotting::InputManager::getKnown1dPosteriorParameters, "Get all the parameters that a file has processed 1d posteriors for") + .def("get_MCMC_entry", &MaCh3Plotting::InputManager::getMCMCentry, "Load up a particular step in the MCMC chain for a particular input file") + .def("get_MCMC_value", &MaCh3Plotting::InputManager::getMCMCvalue, "Get the value of a particular parameter for the current entry (set by set_MCMC_entry) in the chain for a particular file") + .def("get_n_MCMC_entries", &MaCh3Plotting::InputManager::getnMCMCentries, "Get the number of entries in the MCMC chain in a particular file") + .def("get_1d_posterior", &MaCh3Plotting::InputManager::get1dPosterior, "Get the 1d posterior for a particular parameter from a particular file") ; py::class_(m_plotting, "StyleManager") diff --git a/plotting/plottingUtils/styleManager.h b/plotting/plottingUtils/styleManager.h index 6df697a4..bccc5d28 100644 --- a/plotting/plottingUtils/styleManager.h +++ b/plotting/plottingUtils/styleManager.h @@ -16,6 +16,14 @@ class StyleManager { /// @brief Constructor /// @param configName The style config to read from StyleManager(std::string configName); + + // NO COPYING! + StyleManager( const StyleManager& ) = delete; + StyleManager( StyleManager&& ) = default; + + ~StyleManager(){ + MACH3LOG_DEBUG("##### Deleting StyleManager Instance #####"); + } /// @brief Convert hideous and vulgar internal parameter name into a beautiful presentable name /// @details The pretty parameter names should be specified in the style config file diff --git a/pyproject.toml b/pyproject.toml index 603ff958..df2c90ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,3 +5,6 @@ build-backend = "scikit_build_core.build" [project] name = "pyMaCh3" version = "0.0.1" + +[tool.scikit-build.cmake] +args = ["-DMaCh3_PYTHON_ENABLED=ON"] \ No newline at end of file