/*************************************************************************** PFindRun.h Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2026 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 _PFINDRUN_H_ #define _PFINDRUN_H_ #include "PMusr.h" //-------------------------------------------------------------------------- /** * @brief PFindRun - Locates muSR data files using template-based path resolution. * * This class searches for muSR run data files across multiple paths using * configurable templates that encode instrument naming conventions. It supports * various file formats (ROOT, NeXus, PSI-BIN, PSI-MDU, MUD, WKM) and handles * year/run number substitution in file paths. * * The template system uses placeholders: * - %yyyy% : 4-digit year (e.g., 2023) * - %yy% : 2-digit year (e.g., 23) * - %rr...r% : Run number with varying digits (%rr%, %rrr%, up to %rrrrrrrrr%) * * @par Example Usage: * @code * PStringVector paths = {"/data/gps", "/data/lem"}; * PRunNameTemplateList templates; * PRunNameTemplate gpsTemplate; * gpsTemplate.instrument = "GPS"; * gpsTemplate.runNameTemplate = "%yyyy%/%rrrrr%.root"; * templates.push_back(gpsTemplate); * * PFindRun finder(paths, templates, "GPS", 2023, 2425, "MusrRoot"); * if (finder.FoundPathName()) { * TString fullPath = finder.GetPathName(); * // fullPath = "/data/gps/2023/02425.root" * } * @endcode * * @see PRunNameTemplate * @see PRunNameTemplateList */ class PFindRun { public: //---------------------------------------------------------------------- /** * @brief Default constructor - Creates instance without search parameters. * * Initializes the finder with paths and templates but no specific run to search. * Use the full constructor to perform automatic searches. * * @param path Vector of directory paths to search * @param runNameTemplateList List of template patterns for different instruments */ PFindRun(const PStringVector path, const PRunNameTemplateList runNameTemplateList); //---------------------------------------------------------------------- /** * @brief Full constructor - Creates instance and prepares for file search. * * Initializes the finder with all parameters needed to locate a specific run file. * Call FoundPathName() after construction to perform the actual search. * * @param path Vector of directory paths to search * @param runNameTemplateList List of template patterns for different instruments * @param instrument Instrument name (must match a template entry, e.g., "GPS", "LEM") * @param year Run year (e.g., 2023) * @param run Run number (e.g., 2425) * @param file_format Optional file format filter: "MusrRoot"/"ROOT", "NeXus", * "PSI-BIN", "PSI-MDU", "MUD", "WKM". Empty string matches any format. */ PFindRun(const PStringVector path, const PRunNameTemplateList runNameTemplateList, const TString &instrument, const UInt_t year, const UInt_t run, const TString file_format=""); //---------------------------------------------------------------------- /** * @brief Searches for the run file using configured templates and paths. * * Iterates through all paths containing the instrument name, applies matching * templates, and checks filesystem for file existence. If a file format is * specified, only files with matching extensions are considered. * * @return true if file was found, false otherwise * * @par Search Algorithm: * 1. Filter paths containing instrument name * 2. For each matching path, try all templates for that instrument * 3. Substitute year/run placeholders to create full path * 4. Check if file exists on filesystem * 5. If file_format specified, verify extension matches * * @note After successful search, use GetPathName() to retrieve the full path. */ Bool_t FoundPathName(); //---------------------------------------------------------------------- /** * @brief Returns the full path to the found run file. * * @return Full filesystem path including filename and extension, or empty * string if no file was found (call FoundPathName() first). */ TString GetPathName() { return fPathName; } //---------------------------------------------------------------------- /** * @brief Debug utility - Prints current search configuration to stdout. * * Outputs instrument name, year, run number, and all available templates * with their patterns. Useful for troubleshooting path resolution issues. */ void DumpTemplateList(); private: const PStringVector fPath; ///< Search paths for data files const PRunNameTemplateList fRunNameTemplateList; ///< Template patterns per instrument TString fInstrument{""}; ///< Target instrument name (e.g., "GPS", "LEM") Int_t fYear{-1}; ///< Run year (-1 if not specified) Int_t fRun{-1}; ///< Run number (-1 if not specified) TString fFileFormat{""}; ///< Optional file format filter (empty = any) TString fPathName{""}; ///< Resolved full path (empty until found) //---------------------------------------------------------------------- /** * @brief Generates full file path by substituting template placeholders. * * Internal helper that replaces year and run number placeholders in a template * with actual values. Supports variable-length run number formatting (2-9 digits). * * @param path Base directory path * @param runNameTemplate Template string with placeholders (%yyyy%, %yy%, %rr...r%) * @return Full path with placeholders substituted (e.g., "/data/gps/2023/02425.root") * * @par Template Examples: * - "%yyyy%/%rrrrr%.root" with year=2023, run=42 → "2023/00042.root" * - "run_%yy%_%rrr%.nxs" with year=2023, run=425 → "run_23_425.nxs" */ TString CreatePathName(const TString path, const TString runNameTemplate); }; #endif // _PFINDRUN_H_