From 019a16e1aab98d84a8e271b4db75ffa649d61ffa Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Fri, 14 Nov 2025 10:05:36 +0100 Subject: [PATCH] improve doxygen documentation of PRgeHandler.* --- src/classes/PRgeHandler.cpp | 163 ++++++++++++++++++------- src/include/PRgeHandler.h | 237 ++++++++++++++++++++++++++++++++---- 2 files changed, 330 insertions(+), 70 deletions(-) diff --git a/src/classes/PRgeHandler.cpp b/src/classes/PRgeHandler.cpp index 3a121ef03..1cb37515a 100644 --- a/src/classes/PRgeHandler.cpp +++ b/src/classes/PRgeHandler.cpp @@ -45,7 +45,10 @@ ClassImpQ(PXmlRgeHandler) // OnStartDocument //-------------------------------------------------------------------------- /** - *

Called on start of the XML file reading. Initializes all necessary variables. + * \brief SAX callback invoked at the start of XML document parsing. + * + * Initializes the parsing state by resetting the key to empty. This ensures + * clean state for processing the XML content. */ void PXmlRgeHandler::OnStartDocument() { @@ -56,7 +59,14 @@ void PXmlRgeHandler::OnStartDocument() // OnEndDocument //-------------------------------------------------------------------------- /** - *

Called on end of XML file reading. + * \brief SAX callback invoked at the end of XML document parsing. + * + * Performs final validation to ensure all required fields were parsed: + * - TrimSP data path must be set + * - RGE filename prefix must be set + * - At least one implantation energy must be specified + * + * Sets fIsValid to false and calls OnError() if any validation fails. */ void PXmlRgeHandler::OnEndDocument() { @@ -85,11 +95,19 @@ void PXmlRgeHandler::OnEndDocument() // OnStartElement //-------------------------------------------------------------------------- /** - *

Called when a XML start element is found. Filters out the needed elements - * and sets a proper key. + * \brief SAX callback invoked when an XML start tag is encountered. + * + * Processes recognized elements within the section: + * - : Directory containing RGE files + * - : RGE filename prefix + * - : Single implantation energy value + * - : Energy range with start/stop/step attributes + * + * For , parses the attributes and generates the energy list. + * Performs extensive validation on attribute values and ranges. * * \param str XML element name - * \param attributes used only for energy_vect + * \param attributes Element attributes (only used for energy_vect) */ void PXmlRgeHandler::OnStartElement(const Char_t *str, const TList *attributes) { @@ -182,9 +200,12 @@ void PXmlRgeHandler::OnStartElement(const Char_t *str, const TList *attributes) // OnEndElement //-------------------------------------------------------------------------- /** - *

Called when a XML end element is found. Resets the handler key. + * \brief SAX callback invoked when an XML end tag is encountered. * - * \param str not used + * Resets the parsing state when leaving the section and + * clears the current element key for all end tags. + * + * \param str XML element name */ void PXmlRgeHandler::OnEndElement(const Char_t *str) { @@ -199,10 +220,17 @@ void PXmlRgeHandler::OnEndElement(const Char_t *str) // OnCharacters //-------------------------------------------------------------------------- /** - *

Content of a given XML element. Filters out the data and feeds them to - * the internal variables. + * \brief SAX callback invoked for text content between XML tags. * - * \param str XML element string + * Processes the content based on the current parsing state (fKey): + * - eDataPath: Stores the data directory path + * - eFlnPre: Stores the RGE filename prefix + * - eEnergy: Parses integer energy value and adds to energy list + * + * Performs validation and error handling for energy values, ensuring + * they are valid integers within range. + * + * \param str Text content from XML element */ void PXmlRgeHandler::OnCharacters(const Char_t *str) { @@ -249,9 +277,11 @@ void PXmlRgeHandler::OnCharacters(const Char_t *str) // OnComment //-------------------------------------------------------------------------- /** - *

Called when a XML comment is found. Not used. + * \brief SAX callback invoked for XML comments. * - * \param str not used. + * Currently not used - comments are ignored. + * + * \param str Comment text */ void PXmlRgeHandler::OnComment(const Char_t *str) { @@ -262,9 +292,11 @@ void PXmlRgeHandler::OnComment(const Char_t *str) // OnWarning //-------------------------------------------------------------------------- /** - *

Called when the XML parser emits a warning. + * \brief SAX callback invoked when the parser emits a warning. * - * \param str warning string + * Prints warning message to stderr. + * + * \param str Warning message from parser */ void PXmlRgeHandler::OnWarning(const Char_t *str) { @@ -276,9 +308,12 @@ void PXmlRgeHandler::OnWarning(const Char_t *str) // OnError //-------------------------------------------------------------------------- /** - *

Called when the XML parser emits an error. + * \brief SAX callback invoked when the parser encounters an error. * - * \param str error string + * Prints error message to stderr. Called both by the parser and + * by this handler's own validation code. + * + * \param str Error message */ void PXmlRgeHandler::OnError(const Char_t *str) { @@ -290,9 +325,11 @@ void PXmlRgeHandler::OnError(const Char_t *str) // OnFatalError //-------------------------------------------------------------------------- /** - *

Called when the XML parser emits a fatal error. + * \brief SAX callback invoked when the parser encounters a fatal error. * - * \param str fatal error string + * Prints fatal error message to stderr. Fatal errors typically stop parsing. + * + * \param str Fatal error message */ void PXmlRgeHandler::OnFatalError(const Char_t *str) { @@ -304,10 +341,12 @@ void PXmlRgeHandler::OnFatalError(const Char_t *str) // OnCdataBlock //-------------------------------------------------------------------------- /** - *

Not used. + * \brief SAX callback invoked for CDATA blocks. * - * \param str not used - * \param len not used + * Currently not used - CDATA blocks are ignored. + * + * \param str CDATA content + * \param len Length of CDATA content */ void PXmlRgeHandler::OnCdataBlock(const Char_t *str, Int_t len) { @@ -322,8 +361,18 @@ ClassImp(PRgeHandler) // Ctor //-------------------------------------------------------------------------- /** - * @brief PRgeHandler::PRgeHandler - * @param fln + * \brief Constructor that loads TrimSP range distribution data. + * + * Performs the following steps: + * 1. Validates that XML configuration filename is provided + * 2. Parses XML file using PXmlRgeHandler to get file paths and energies + * 3. Reads all specified .rge files from TrimSP + * 4. Calculates total particle counts for each energy + * 5. Computes normalized distributions nn(z) where ∫nn(z)dz = 1 + * + * Sets fValid to false if any errors occur during loading. + * + * \param fln Path to XML configuration file (empty triggers error) */ PRgeHandler::PRgeHandler(const std::string fln) { @@ -440,10 +489,18 @@ PRgeHandler::PRgeHandler(const std::string fln) // ReadRgeFile //-------------------------------------------------------------------------- /** - *

Read the content of a rge-file. + * \brief Reads a single TrimSP .rge file and populates a PRgeData structure. * - * @param fln file name of the rge-file - * @return true on success. + * Parses the two-column format from TrimSP output: + * - Column 1: Depth in Ångström (converted to nm by dividing by 10) + * - Column 2: Number of particles (amplitude) + * + * Skips empty lines and non-numeric lines. Performs extensive validation + * on numeric values with detailed error messages. + * + * \param fln Path to the .rge file + * \param data PRgeData structure to populate with depth and amplitude vectors + * \return True on success, false if file cannot be opened or contains invalid data */ bool PRgeHandler::ReadRgeFile(const std::string fln, PRgeData &data) { @@ -553,10 +610,13 @@ bool PRgeHandler::ReadRgeFile(const std::string fln, PRgeData &data) // GetZmax via energy //-------------------------------------------------------------------------- /** - *

Get maximal depth for a given energy. + * \brief Returns maximum penetration depth for a given implantation energy. * - * @param energy energy in (eV) - * @return zMax if energy is found, -1 otherwise. + * Searches for a data set matching the specified energy (within 0.9 keV + * tolerance) and returns its maximum depth value. + * + * \param energy Implantation energy in eV + * \return Maximum depth in nm, or -1 if energy not found */ Double_t PRgeHandler::GetZmax(const Double_t energy) { @@ -567,7 +627,7 @@ Double_t PRgeHandler::GetZmax(const Double_t energy) break; } } - + if (idx != -1) return GetZmax(idx); @@ -578,10 +638,13 @@ Double_t PRgeHandler::GetZmax(const Double_t energy) // GetZmax via index //-------------------------------------------------------------------------- /** - *

Get maximal depth for a given index. + * \brief Returns maximum penetration depth for a given data set index. * - * @param idx index for which zMax is requested. - * @return zMax if idx is in range, -1 otherwise. + * Returns the last depth value from the depth vector, which represents + * the maximum penetration depth for this energy. + * + * \param idx Data set index (0 to GetNoOfRgeDataSets()-1) + * \return Maximum depth in nm, or -1 if idx out of range */ Double_t PRgeHandler::GetZmax(const Int_t idx) { @@ -595,11 +658,14 @@ Double_t PRgeHandler::GetZmax(const Int_t idx) // Get_n via energy //-------------------------------------------------------------------------- /** - *

Get the normalized n(E,z) value. + * \brief Returns normalized particle distribution at given energy and depth. * - * @param energy (eV) - * @param z (nm) - * @return n(E,z) if energy and z are in proper range, -1.0 otherwise. + * Searches for a data set matching the specified energy (within 0.9 keV + * tolerance) and returns the normalized distribution value at depth z. + * + * \param energy Implantation energy in eV + * \param z Depth in nm + * \return Normalized distribution nn(E,z), or 0.0 if energy not found or z out of range */ Double_t PRgeHandler::Get_n(const Double_t energy, const Double_t z) { @@ -620,11 +686,17 @@ Double_t PRgeHandler::Get_n(const Double_t energy, const Double_t z) // Get_n via index //-------------------------------------------------------------------------- /** - *

Get the normalized n(idx,z) value. + * \brief Returns normalized particle distribution at given index and depth. * - * @param idx index of the rge-dataset - * @param z (nm) - * @return n(idx,z) if idx and z are in proper range, -1.0 otherwise. + * Uses linear interpolation between adjacent data points to compute the + * distribution value at the requested depth. The normalization ensures + * that ∫nn(z)dz = 1 over the entire depth range. + * + * Special handling for z near zero: extrapolates linearly from first data point. + * + * \param idx Data set index (0 to GetNoOfRgeDataSets()-1) + * \param z Depth in nm + * \return Normalized distribution nn(idx,z), or 0.0 if idx or z out of range */ Double_t PRgeHandler::Get_n(const Int_t idx, const Double_t z) { @@ -658,10 +730,13 @@ Double_t PRgeHandler::Get_n(const Int_t idx, const Double_t z) // GetEnergyIndex //-------------------------------------------------------------------------- /** - *

Get the energy index by providing an energy in (eV). + * \brief Finds the data set index corresponding to a given implantation energy. * - * @param energy in (eV). - * @return energy index if energy was found, -1 otherwise. + * Searches through loaded data sets for a matching energy value using a + * tolerance of 0.9 keV (i.e., |E_data - E_query| < 0.9 keV). + * + * \param energy Implantation energy in eV + * \return Data set index (0 to GetNoOfRgeDataSets()-1), or -1 if not found */ Int_t PRgeHandler::GetEnergyIndex(const Double_t energy) { diff --git a/src/include/PRgeHandler.h b/src/include/PRgeHandler.h index 2befda98a..a831e593d 100644 --- a/src/include/PRgeHandler.h +++ b/src/include/PRgeHandler.h @@ -41,86 +41,271 @@ //----------------------------------------------------------------------------- /** - *

Keep a single rge table from TrimSP for a given energy. + * \brief Data structure for a single TrimSP range distribution at a given energy. + * + * PRgeData stores the muon/particle implantation depth profile calculated by + * TrimSP (Transport of Ions in Matter - Stopping and Range) for a specific + * implantation energy. It contains the depth distribution n(z) and normalized + * distribution nn(z) where ∫nn(z)dz = 1. + * + * \see PRgeHandler for the class that reads and manages RGE data + * \see PRgeDataList for collections of RGE data sets */ struct PRgeData { - Double_t energy; - PDoubleVector depth; - PDoubleVector amplitude; - PDoubleVector nn; // normalized int n(z) dz = 1 amplitudes - Double_t noOfParticles; + Double_t energy; ///< Implantation energy in eV + PDoubleVector depth; ///< Depth values in nanometers (nm) + PDoubleVector amplitude; ///< Number of particles at each depth (raw counts from TrimSP) + PDoubleVector nn; ///< Normalized particle density where ∫nn(z)dz = 1 + Double_t noOfParticles; ///< Total number of particles (sum of amplitudes) }; //----------------------------------------------------------------------------- /** - *

Keep all rge tables from TrimSP. + * \brief Container for multiple TrimSP range distributions at different energies. + * + * PRgeDataList is a vector of PRgeData structures, typically containing + * implantation profiles for a range of energies (e.g., 1-30 keV). */ typedef std::vector PRgeDataList; //----------------------------------------------------------------------------- /** - *

Reads the xml-startup file in order to extract all necessary information - * about the RGE files (TrimSP) needed. + * \brief XML SAX parser handler for TrimSP configuration files. + * + * PXmlRgeHandler parses XML configuration files to extract TrimSP (Transport + * of Ions in Matter) data file locations and parameters. The XML file specifies: + * - Data path: Directory containing .rge files + * - Filename prefix: Base name for RGE files (e.g., "LCCO_E") + * - Energy list: Implantation energies (individual values or start/stop/step) + * + * This handler implements ROOT's TSAXParser callbacks for event-driven XML parsing. + * + * \par XML Format Example: + * \code{.xml} + * + * /path/to/rge/files + * Material_E + * 1000 + * 5000 + * + * + * \endcode + * + * \see PRgeHandler for the main RGE data manager + * \see TSAXParser for ROOT's SAX parser implementation */ class PXmlRgeHandler : public TObject, public TQObject { public: + /// Default constructor PXmlRgeHandler() {} + /// Destructor virtual ~PXmlRgeHandler() {} + /// Called at start of XML document parsing (SLOT) virtual void OnStartDocument(); // SLOT + /// Called at end of XML document parsing, performs validation (SLOT) virtual void OnEndDocument(); // SLOT - virtual void OnStartElement(const char*, const TList*); // SLOT - virtual void OnEndElement(const char*); // SLOT - virtual void OnCharacters(const char*); // SLOT - virtual void OnComment(const char*); // SLOT - virtual void OnWarning(const char*); // SLOT - virtual void OnError(const char*); // SLOT - virtual void OnFatalError(const char*); // SLOT - virtual void OnCdataBlock(const char*, Int_t); // SLOT + /** + * \brief Called when XML start tag is encountered (SLOT) + * \param str Element name + * \param attributes Element attributes (used for energy_vect) + */ + virtual void OnStartElement(const char* str, const TList* attributes); // SLOT + /** + * \brief Called when XML end tag is encountered (SLOT) + * \param str Element name + */ + virtual void OnEndElement(const char* str); // SLOT + /** + * \brief Called for element content between tags (SLOT) + * \param str Character data + */ + virtual void OnCharacters(const char* str); // SLOT + /** + * \brief Called for XML comments (SLOT) + * \param str Comment text + */ + virtual void OnComment(const char* str); // SLOT + /** + * \brief Called when parser emits a warning (SLOT) + * \param str Warning message + */ + virtual void OnWarning(const char* str); // SLOT + /** + * \brief Called when parser encounters an error (SLOT) + * \param str Error message + */ + virtual void OnError(const char* str); // SLOT + /** + * \brief Called when parser encounters a fatal error (SLOT) + * \param str Fatal error message + */ + virtual void OnFatalError(const char* str); // SLOT + /** + * \brief Called for CDATA blocks (SLOT) + * \param str CDATA content + * \param len Length of CDATA + */ + virtual void OnCdataBlock(const char* str, Int_t len); // SLOT + /** + * \brief Returns validity status of parsed configuration. + * \return True if XML was parsed successfully and all required fields are present + */ virtual bool IsValid() { return fIsValid; } + + /** + * \brief Returns the TrimSP data directory path. + * \return Directory path containing .rge files + */ virtual std::string GetTrimSpDataPath() { return fTrimSpDataPath; } + + /** + * \brief Returns the RGE filename prefix. + * \return Filename prefix (e.g., "LCCO_E" for files like LCCO_E1000.rge) + */ virtual std::string GetTrimSpFlnPre() { return fTrimSpFlnPre; } + + /** + * \brief Returns the list of implantation energies. + * \return Vector of energies in eV + */ virtual const PIntVector GetTrimSpDataVectorList() const { return fTrimSpDataEnergyList; } private: + /// Enum for tracking which XML element is currently being parsed enum EKeyWords {eEmpty, eDataPath, eFlnPre, eEnergy}; - EKeyWords fKey; + EKeyWords fKey; ///< Current parsing context/state - bool isTrimSp{false}; - bool fIsValid{true}; + bool isTrimSp{false}; ///< True when inside element + bool fIsValid{true}; ///< Validity flag (false if parsing errors occur) - std::string fTrimSpDataPath{""}; //< where to find the rge-files - std::string fTrimSpFlnPre{""}; //< keeps the preface of the rge file name, e.g. LCCO_E - PIntVector fTrimSpDataEnergyList; //< TrimSP implantation energy list (in eV) + std::string fTrimSpDataPath{""}; ///< Directory path to RGE files + std::string fTrimSpFlnPre{""}; ///< RGE filename prefix (e.g., "LCCO_E" for LCCO_E1000.rge) + PIntVector fTrimSpDataEnergyList; ///< List of implantation energies in eV ClassDef(PXmlRgeHandler, 1) }; //----------------------------------------------------------------------------- /** - * @brief The PRegHandler class + * \brief Manager for TrimSP range distribution data. + * + * PRgeHandler reads and manages muon/particle implantation depth profiles + * calculated by TrimSP (Transport of Ions in Matter - Stopping and Range). + * It provides access to: + * - Particle implantation depth distributions n(E,z) + * - Normalized distributions nn(E,z) where ∫nn(z)dz = 1 + * - Maximum penetration depths for different energies + * + * The class loads RGE files specified in an XML configuration file, which + * can contain data for multiple implantation energies. RGE files contain + * depth (in Ångström) vs. particle count data from TrimSP simulations. + * + * \par Typical Usage: + * \code + * PRgeHandler rge("config.xml"); + * if (rge.IsValid()) { + * Double_t zmax = rge.GetZmax(5000.0); // Max depth at 5 keV + * Double_t n = rge.Get_n(5000.0, 10.0); // Distribution at 5 keV, 10 nm depth + * } + * \endcode + * + * \see PRgeData for the data structure holding individual distributions + * \see PXmlRgeHandler for XML configuration parsing */ class PRgeHandler : public TObject { public: + /** + * \brief Constructor that loads TrimSP data from XML configuration. + * \param fln Path to XML configuration file (empty string for manual setup) + * + * Parses the XML file to get RGE file locations and energies, then loads + * all specified RGE files. Sets fValid to false if any errors occur. + */ PRgeHandler(std::string fln=""); + + /// Destructor virtual ~PRgeHandler() {} + /** + * \brief Returns validity status. + * \return True if all RGE files loaded successfully, false if errors occurred + */ virtual bool IsValid() { return fValid; } + + /** + * \brief Returns number of loaded RGE data sets. + * \return Number of energy data sets (one per energy value) + */ virtual UInt_t GetNoOfRgeDataSets() { return (UInt_t)fData.size(); } + + /** + * \brief Returns all RGE data sets. + * \return Vector of all loaded PRgeData structures + */ virtual PRgeDataList GetRgeData() { return fData; } + + /** + * \brief Returns maximum penetration depth for a given energy. + * \param energy Implantation energy in eV + * \return Maximum depth in nm, or -1 if energy not found + */ virtual Double_t GetZmax(const Double_t energy); + + /** + * \brief Returns maximum penetration depth for a data set index. + * \param idx Data set index (0 to GetNoOfRgeDataSets()-1) + * \return Maximum depth in nm, or -1 if idx out of range + */ virtual Double_t GetZmax(const Int_t idx); + + /** + * \brief Returns normalized particle distribution at given energy and depth. + * \param energy Implantation energy in eV + * \param z Depth in nm + * \return Normalized distribution nn(E,z), or 0.0 if out of range + * + * Uses linear interpolation between data points. The normalization ensures + * that ∫nn(z)dz = 1 over the entire depth range. + */ virtual Double_t Get_n(const Double_t energy, const Double_t z); + + /** + * \brief Returns normalized particle distribution at given index and depth. + * \param idx Data set index (0 to GetNoOfRgeDataSets()-1) + * \param z Depth in nm + * \return Normalized distribution nn(idx,z), or 0.0 if out of range + * + * Uses linear interpolation between data points. The normalization ensures + * that ∫nn(z)dz = 1 over the entire depth range. + */ virtual Double_t Get_n(const Int_t idx, const Double_t z); + + /** + * \brief Finds the data set index for a given energy. + * \param energy Implantation energy in eV + * \return Data set index, or -1 if energy not found + * + * Uses tolerance of 0.9 keV for matching energies. + */ virtual Int_t GetEnergyIndex(const Double_t energy); private: - bool fValid{false}; - PRgeDataList fData; + bool fValid{false}; ///< Validity flag (true if all RGE files loaded successfully) + PRgeDataList fData; ///< Collection of RGE data sets (one per energy) + /** + * \brief Reads a single RGE file and populates a PRgeData structure. + * \param fln Path to the .rge file + * \param data PRgeData structure to populate + * \return True on success, false on error + * + * Parses the two-column format (depth amplitude) from TrimSP output. + * Converts depth from Ångström to nanometers. + */ virtual bool ReadRgeFile(const std::string fln, PRgeData &data); ClassDef(PRgeHandler, 1)