358 lines
16 KiB
C++
358 lines
16 KiB
C++
/***************************************************************************
|
|
|
|
PStartupHandler.h
|
|
|
|
Author: Andreas Suter
|
|
e-mail: andreas.suter@psi.ch
|
|
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* Copyright (C) 2007-2025 by Andreas Suter *
|
|
* andreas.suter@psi.ch *
|
|
* *
|
|
* This program 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 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program 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 this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#ifndef _PSTARTUPHANDLER_H_
|
|
#define _PSTARTUPHANDLER_H_
|
|
|
|
#include <TObject.h>
|
|
#include <TQObject.h>
|
|
#include <TList.h>
|
|
#include <TString.h>
|
|
#include <TSAXParser.h>
|
|
|
|
#include "PMusr.h"
|
|
|
|
//--------------------------------------------------------------------------
|
|
// This function is a replacement for the ParseFile method of TSAXParser.
|
|
//--------------------------------------------------------------------------
|
|
/**
|
|
* \brief Replacement function for TSAXParser::ParseFile().
|
|
*
|
|
* This standalone function provides a workaround for environments where
|
|
* TSAXParser::ParseFile() does not work correctly but ParseBuffer() does.
|
|
* It reads the entire XML file into memory and then parses it as a buffer.
|
|
*
|
|
* \param saxParser Pointer to an initialized TSAXParser object with connected slots
|
|
* \param startup_path_name Full path to the XML file to be parsed
|
|
*
|
|
* \return Parse status:
|
|
* - 0: Success
|
|
* - 1: File could not be read
|
|
* - Other: XML parse error code from TSAXParser::ParseBuffer()
|
|
*
|
|
* \see PStartupHandler
|
|
*/
|
|
int parseXmlFile(TSAXParser*, const char*);
|
|
|
|
/**
|
|
* \brief Handles the musrfit XML startup configuration file (musrfit_startup.xml).
|
|
*
|
|
* PStartupHandler is responsible for locating, parsing, and providing access to
|
|
* the musrfit startup configuration file. This XML file contains default settings
|
|
* that customize musrfit behavior across different installations and user preferences.
|
|
*
|
|
* \section startup_contents Configuration File Contents
|
|
*
|
|
* The musrfit_startup.xml file stores:
|
|
* - <b>Data search paths:</b> Directories to search for μSR data files
|
|
* - <b>Run name templates:</b> Instrument-specific patterns for constructing data file paths
|
|
* - <b>Fourier transform defaults:</b> Units, apodization, plot type, phase settings
|
|
* - <b>ROOT marker list:</b> Marker styles for data point display
|
|
* - <b>ROOT color list:</b> RGB colors for multi-run plotting
|
|
*
|
|
* \section startup_search File Search Order
|
|
*
|
|
* The startup file is searched in the following locations (first found wins):
|
|
* -# Current working directory: \c ./musrfit_startup.xml
|
|
* -# User config directory: \c $HOME/.musrfit/musrfit_startup.xml
|
|
* -# MUSRFITPATH environment: \c $MUSRFITPATH/musrfit_startup.xml
|
|
* -# ROOT installation: \c $ROOTSYS/bin/musrfit_startup.xml (with warning)
|
|
*
|
|
* If no file is found, a default configuration is automatically created in
|
|
* \c $HOME/.musrfit/musrfit_startup.xml.
|
|
*
|
|
* \section startup_xml XML File Structure
|
|
*
|
|
* \code{.xml}
|
|
* <?xml version="1.0" encoding="UTF-8"?>
|
|
* <musrfit xmlns="http://lmu.web.psi.ch/musrfit/user/MUSR/WebHome.html">
|
|
* <comment>Configuration description</comment>
|
|
* <data_path>/path/to/data/directory</data_path>
|
|
* <run_name_template inst="gps">d%yyyy%/tdc/root/deltat_tdc_gps_%yyyy%_%rrrr%.root</run_name_template>
|
|
* <fourier_settings>
|
|
* <units>Gauss</units>
|
|
* <fourier_power>0</fourier_power>
|
|
* <apodization>none</apodization>
|
|
* <plot>real_and_imag</plot>
|
|
* <phase>0.0</phase>
|
|
* <phase_increment>1.0</phase_increment>
|
|
* </fourier_settings>
|
|
* <root_settings>
|
|
* <marker_list>
|
|
* <marker>24</marker>
|
|
* </marker_list>
|
|
* <color_list>
|
|
* <color>255,0,0</color>
|
|
* </color_list>
|
|
* </root_settings>
|
|
* </musrfit>
|
|
* \endcode
|
|
*
|
|
* \section startup_templates Run Name Templates
|
|
*
|
|
* Run name templates use placeholders for automatic file path construction:
|
|
* - \c %yyyy% : 4-digit year (e.g., 2024)
|
|
* - \c %yy% : 2-digit year (e.g., 24)
|
|
* - \c %rrrr% : 4-digit run number with leading zeros
|
|
* - \c %rrrrr% : 5-digit run number with leading zeros
|
|
*
|
|
* Example: \c d%yyyy%/tdc/root/deltat_tdc_gps_%yyyy%_%rrrr%.root
|
|
* → \c d2024/tdc/root/deltat_tdc_gps_2024_1234.root
|
|
*
|
|
* \section startup_sax SAX Parser Implementation
|
|
*
|
|
* This class implements the TQObject signal/slot mechanism to handle SAX parser
|
|
* callbacks. The parser events trigger the following methods:
|
|
* - OnStartDocument(): Initialize default values
|
|
* - OnStartElement(): Identify XML element type, set parsing state
|
|
* - OnCharacters(): Extract element content
|
|
* - OnEndElement(): Reset parsing state
|
|
* - OnEndDocument(): Validate and fill missing defaults
|
|
* - OnWarning/OnError/OnFatalError(): Error handling
|
|
*
|
|
* \section startup_usage Usage Example
|
|
*
|
|
* \code{.cpp}
|
|
* // Create handler (searches for and parses startup file)
|
|
* PStartupHandler startupHandler;
|
|
*
|
|
* // Check if configuration was loaded successfully
|
|
* if (startupHandler.StartupFileFound()) {
|
|
* // Get data search paths
|
|
* PStringVector paths = startupHandler.GetDataPathList();
|
|
*
|
|
* // Get Fourier transform defaults
|
|
* PMsrFourierStructure fourier = startupHandler.GetFourierDefaults();
|
|
*
|
|
* // Get plotting colors and markers
|
|
* PIntVector colors = startupHandler.GetColorList();
|
|
* PIntVector markers = startupHandler.GetMarkerList();
|
|
* }
|
|
* \endcode
|
|
*
|
|
* \see PMsrHandler for MSR file parsing
|
|
* \see PRunDataHandler for data file loading with path resolution
|
|
*/
|
|
class PStartupHandler : public TObject, public TQObject
|
|
{
|
|
public:
|
|
/**
|
|
* \brief Constructor that locates and parses the musrfit startup configuration file.
|
|
*
|
|
* Searches for musrfit_startup.xml in standard locations and parses it if found.
|
|
* If no file is found, creates a default configuration in $HOME/.musrfit/.
|
|
*
|
|
* <b>Search order:</b>
|
|
* -# ./musrfit_startup.xml (current directory)
|
|
* -# $HOME/.musrfit/musrfit_startup.xml
|
|
* -# $MUSRFITPATH/musrfit_startup.xml
|
|
* -# $ROOTSYS/bin/musrfit_startup.xml (with warning)
|
|
*
|
|
* \param reset_startup_file If true and file is found, rewrites it with default content.
|
|
* Useful for restoring corrupted or outdated configurations.
|
|
*
|
|
* \note The actual XML parsing is performed by connecting this handler to a TSAXParser
|
|
* and calling parseXmlFile() externally.
|
|
*
|
|
* \see StartupFileFound(), GetStartupFilePath()
|
|
*/
|
|
PStartupHandler(bool reset_startup_file=false);
|
|
|
|
/**
|
|
* \brief Destructor releasing allocated resources.
|
|
*
|
|
* Clears all configuration vectors:
|
|
* - fDataPathList
|
|
* - fMarkerList
|
|
* - fColorList
|
|
* - fRunNameTemplate
|
|
*/
|
|
virtual ~PStartupHandler();
|
|
|
|
/** \brief SAX callback: Called when XML document parsing begins.
|
|
* Initializes all configuration variables to default values. */
|
|
virtual void OnStartDocument(); // SLOT
|
|
|
|
/** \brief SAX callback: Called when XML document parsing ends.
|
|
* Triggers CheckLists() to ensure all required settings have values. */
|
|
virtual void OnEndDocument(); // SLOT
|
|
|
|
/** \brief SAX callback: Called when an XML start element is encountered.
|
|
* \param str Element name (e.g., "data_path", "marker", "units")
|
|
* \param attributes XML attributes (used for inst attribute in run_name_template) */
|
|
virtual void OnStartElement(const Char_t*, const TList*); // SLOT
|
|
|
|
/** \brief SAX callback: Called when an XML end element is encountered.
|
|
* \param str Element name (unused, resets parsing state) */
|
|
virtual void OnEndElement(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called with element text content.
|
|
* \param str Text content between XML tags (the actual configuration values) */
|
|
virtual void OnCharacters(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called when XML comment is found (unused).
|
|
* \param str Comment text */
|
|
virtual void OnComment(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called when XML parser issues a warning.
|
|
* \param str Warning message (output to stderr) */
|
|
virtual void OnWarning(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called when XML parser encounters an error.
|
|
* \param str Error message (output to stderr) */
|
|
virtual void OnError(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called when XML parser encounters a fatal error.
|
|
* \param str Fatal error message (output to stderr) */
|
|
virtual void OnFatalError(const Char_t*); // SLOT
|
|
|
|
/** \brief SAX callback: Called for CDATA blocks (unused).
|
|
* \param str CDATA content
|
|
* \param len Length of CDATA content */
|
|
virtual void OnCdataBlock(const Char_t*, Int_t); // SLOT
|
|
|
|
/**
|
|
* \brief Checks if the startup configuration file was successfully located.
|
|
* \return true if musrfit_startup.xml was found (in any search location), false otherwise
|
|
*/
|
|
virtual Bool_t StartupFileFound() { return fStartupFileFound; }
|
|
|
|
/**
|
|
* \brief Returns the full path to the located startup configuration file.
|
|
* \return Full path including filename (e.g., "/home/user/.musrfit/musrfit_startup.xml"),
|
|
* or empty string if not found
|
|
*/
|
|
virtual TString GetStartupFilePath() { return fStartupFilePath; }
|
|
|
|
/**
|
|
* \brief Validates configuration lists and fills missing entries with defaults.
|
|
*
|
|
* Called at end of XML parsing to ensure all required lists have values.
|
|
* If a list is empty, populates it with sensible defaults:
|
|
* - Data paths: PSI facility standard locations
|
|
* - Markers: ROOT marker codes (circles, squares, triangles, etc.)
|
|
* - Colors: Standard plotting colors (black, red, green, blue, etc.)
|
|
*/
|
|
virtual void CheckLists();
|
|
|
|
/**
|
|
* \brief Returns Fourier transform default settings.
|
|
* \return PMsrFourierStructure containing units, apodization, plot type, phase settings
|
|
*/
|
|
virtual PMsrFourierStructure GetFourierDefaults() { return fFourierDefaults; }
|
|
|
|
/**
|
|
* \brief Returns the list of instrument-specific run name templates.
|
|
* \return Vector of PRunNameTemplate structures (instrument name + path pattern)
|
|
*/
|
|
virtual const PRunNameTemplateList GetRunNameTemplateList() { return fRunNameTemplate; }
|
|
|
|
/**
|
|
* \brief Returns the list of data file search paths.
|
|
* \return Vector of directory paths to search for μSR data files
|
|
*/
|
|
virtual const PStringVector GetDataPathList() const { return fDataPathList; }
|
|
|
|
/**
|
|
* \brief Returns the list of ROOT marker codes for plotting.
|
|
* \return Vector of ROOT TMarker style codes (e.g., 24=open circle, 25=open square)
|
|
*/
|
|
virtual const PIntVector GetMarkerList() const { return fMarkerList; }
|
|
|
|
/**
|
|
* \brief Returns the list of ROOT color codes for plotting.
|
|
* \return Vector of ROOT TColor codes (generated from RGB values)
|
|
*/
|
|
virtual const PIntVector GetColorList() const { return fColorList; }
|
|
|
|
private:
|
|
/**
|
|
* \brief Enumeration of XML element types for SAX parser state machine.
|
|
*
|
|
* Used by OnStartElement() to set parsing context and by OnCharacters()
|
|
* to determine how to interpret element content.
|
|
*/
|
|
enum EKeyWords {
|
|
eEmpty, ///< No active element (between elements or unknown)
|
|
eComment, ///< Inside \<comment\> element
|
|
eDataPath, ///< Inside \<data_path\> element
|
|
eRunNameTemplate, ///< Inside \<run_name_template\> element
|
|
eOptions, ///< Inside \<options\> element (reserved)
|
|
eFourierSettings, ///< Inside \<fourier_settings\> container
|
|
eUnits, ///< Inside \<units\> element (Gauss/Tesla/MHz/Mc/s)
|
|
eFourierPower, ///< Inside \<fourier_power\> element (0-20)
|
|
eApodization, ///< Inside \<apodization\> element (none/weak/medium/strong)
|
|
ePlot, ///< Inside \<plot\> element (real/imag/real_and_imag/power/phase)
|
|
ePhase, ///< Inside \<phase\> element (degrees)
|
|
ePhaseIncrement, ///< Inside \<phase_increment\> element (degrees per step)
|
|
eRootSettings, ///< Inside \<root_settings\> container
|
|
eMarkerList, ///< Inside \<marker_list\> container
|
|
eMarker, ///< Inside \<marker\> element (ROOT marker code)
|
|
eColorList, ///< Inside \<color_list\> container
|
|
eColor ///< Inside \<color\> element (RGB comma-separated)
|
|
};
|
|
|
|
EKeyWords fKey; ///< Current XML element type (SAX parser state)
|
|
Bool_t fStartupFileFound; ///< True if musrfit_startup.xml was located
|
|
TString fStartupFilePath; ///< Full path to located startup file (empty if not found)
|
|
TString fCurrentInstrumentName; ///< Instrument name from run_name_template inst attribute
|
|
PMsrFourierStructure fFourierDefaults; ///< Fourier transform default settings structure
|
|
PStringVector fDataPathList; ///< List of directories to search for data files
|
|
PRunNameTemplateList fRunNameTemplate; ///< List of instrument-specific run name patterns
|
|
PIntVector fMarkerList; ///< List of ROOT TMarker style codes for plotting
|
|
PIntVector fColorList; ///< List of ROOT TColor codes (from RGB) for plotting
|
|
|
|
/**
|
|
* \brief Checks if a file exists at the specified path.
|
|
* \param fln Full path to check
|
|
* \return true if file exists and is readable, false otherwise
|
|
*/
|
|
Bool_t StartupFileExists(Char_t *fln);
|
|
|
|
/**
|
|
* \brief Creates or overwrites a startup file with default configuration.
|
|
*
|
|
* Writes a complete musrfit_startup.xml with:
|
|
* - Standard PSI data paths
|
|
* - Run name templates for all PSI instruments
|
|
* - Default Fourier settings
|
|
* - Standard marker and color lists
|
|
*
|
|
* \param reset_startup_file If true, overwrites existing file at fStartupFilePath.
|
|
* If false, creates new file at $HOME/.musrfit/musrfit_startup.xml.
|
|
* \return true on success, false on write failure
|
|
*/
|
|
Bool_t WriteDefaultStartupFile(bool reset_startup_file=false);
|
|
|
|
ClassDef(PStartupHandler, 1)
|
|
};
|
|
|
|
#endif // _PSTARTUPHANDLER_H_
|
|
|