#ifndef UTSUSEMIHEADER
#define UTSUSEMIHEADER

#define UTSUSEMI_DEFINE_MULTH     "UTSUSEMI_MULTH"
#define UTSUSEMI_DEFINE_DATA_DIR  "UTSUSEMI_DATA_DIR"
#define UTSUSEMI_DEFINE_BASE_DIR  "UTSUSEMI_BASE_DIR"
#define UTSUSEMI_DEFINE_INST_CODE "UTSUSEMI_INST_CODE"
#define UTSUSEMI_DEFINE_USR_DIR   "UTSUSEMI_USR_DIR"
#define UTSUSEMI_DEFINE_WORK_DIR  "UTSUSEMI_WORK_DIR"
#define UTSUSEMI_DEFINE_DEBUGMODE "UTSUSEMI_DEBUGMODE"
#define UTSUSEMI_DEFINE_LOG_QUIET "UTSUSEMI_LOG_QUIET"
#define UTSUSEMI_DEFINE_IGNORE_EMPTYFILE "UTSUSEMI_IGNORE_EMPTYFILE"

#include "Header.hh"
#include "HeaderBase.hh"
#include "ElementContainer.hh"
#include "ElementContainerArray.hh"
#include "ElementContainerMatrix.hh"
#include "OperatorBase.hh"
#include "ManipulatorBase.hh"
#include "SearchInHeader.hh"
#include "StringTools.hh"
#include "BoostXmlParser.hh"
#include "MlfHeader.hh"

#include "UtsusemiCheckDataProcess.hh"
#include "UtsusemiUnitConverter.hh"

#include <thread>
#include <chrono>

#ifdef MULTH
    #include <omp.h>
#endif

#if PY_MAJOR_VERSION >= 3
#define IS_PY3
#endif

// removed 2025/4/17
//#ifdef _MSC_VER
//    #include "msvc/dirent.h"
//#if _MSC_VER<1900
//    template < typename T >
//    bool isnan(T val)
//    {
//        #if defined(_WIN64)
//            return _isnanf(val) !=0;
//        #else
//            return _isnan(val) !=0;
//        #endif
//    }
//#endif
//#else
//    #include <dirent.h>
//#endif

//////////////////////////////////
// UtsusemiHeader
/////////////////////////////////

//!  Header of Utsusemi
/*!  gives information about Utsusemi
 */
#ifdef UTSUSEMIMANYOREVNUMBER
static const int UTSUSEMIMANYOVERSIONREV = (int)UTSUSEMIMANYOREVNUMBER;
#else
static const int UTSUSEMIMANYOVERSIONREV = 0;
#endif
static const std::string UTSUSEMIMANYOVERSION = "4.0";
static const Double UTSUSEMIMASKVALUE64 = MLF_MASKVALUE;
static const float  UTSUSEMIMASKVALUE32 = (float)(1.0E+30);
static const UInt4  UTSUSEMIMASKVALUEUINT4 = -1; /**< the maximum value of UInt4 (unsigned long)   */
static const Double UTSUSEMIMASKERRORVALUE = -1.0e-10;
static const std::string UTSUSEMICONTACTPERSON = "Yasuhiro Inamura";
static const std::string UTSUSEMICONTACTEMAIL = "yasuhiro.inamura@j-parc.jp";
UInt4 UtsusemiGetNumOfMulTh();
UInt4 UtsusemiEnvGetNumOfMulTh();
        //!< Get the number of multi-threadings from environment variables
        /*!<    UTSUSEMI_MULTH
         *
         *   @param None
         *   @return (std::string) the number of multh-threadings
         */
std::string UtsusemiEnvGetDataDir();
        //!< Get the path to data from environment variables
        /*!<    UTSUSEMI_DATA_DIR (/data)
         *
         *   @param None
         *   @return (std::string) the path to data
         */
std::string UtsusemiEnvGetBaseDir();
        //!< Get the path to python-utusemi base directory from environment variables
        /*!<    UTSUSEMI_BASE_DIR (/opt/mlfsoft/python-utsusemi)
         *
         *   @param None
         *   @return (std::string) the path to base path
         */
std::string UtsusemiEnvGetInstCode();
        //!< Get the instrument code from environment variables
        /*!<    UTSUSEMI_INST_CODE ("SIK","AMR",...)
         *
         *   @param None
         *   @return (std::string) the instrument code
         */
std::string UtsusemiEnvGetInstDataDir();
        //!< Get the path to data for the instrumennt from environment variables
        /*!<    UTSUSEMI_DATA_DIR/UTSUSEMI_INST_CODE (/data/XXX)
         *
         *   @param None
         *   @return (std::string) the path to data
         */
std::string UtsusemiEnvGetInstDir();
        //!< Get the path for instrument on python-utusemi from environment variables
        /*!<    UTSUSEMI_BASE_DIR/UTSUSEMI_INST_CODE (/opt/mlfsoft/python-utusemi/XXX)
         *
         *   @param None
         *   @return (std::string) the path
         */
std::string UtsusemiEnvGetUserDir();
        //!< Get the path for users on python-utsusemi from environment variables
        /*!<    UTSUSEMI_USR_DIR (~/)
         *
         *   @param None
         *   @return (std::string) the path
         */
std::string UtsusemiEnvGetWorkDir();
        //!< Get the current path for users from environment variables
        /*!<    UTSUSEMI_WORK_DIR is used only on executing software as an application instead of current directory
         *   If software executed in a shell, UTSUSEMI_WORK_DIR must be unset and then current directory is working dir.
         *   If UTSUSEMI_WORK_DIR is empty, return ""
         *
         *   @param None
         *   @return (std::string) the path
         */
bool UtsusemiEnvGetDebugMode();
        //!< Get the flag of debug mode on python-utsusemi from environment variables
        /*!<    UTSUSEMI_DEBUGMODE
         *
         *   @param None
         *   @return (bool) true: debug Mode, false: normal mode
         */
bool UtsusemiEnvGetIsQuiet();
        //!< Get the flag of QuietMode on UtsusemiMessage, Warning and Error from environment variables
        /*!<    UTSUSEMI_LOG_QUIET
         *
         *   @param None
         *   @return (bool) true returns when UTSUSEMI_LOG_QUIET is Y or y
         */
bool UtsusemiEnvGetIgnoreEmptyFile();
        //!< Get the flag to ignore the error when given edb file size is empty
        /*!<    UTSUSEMI_IGNORE_EMPTYFILE
         *
         *   @param None
         *   @return (bool) true returns when UTSUSEMI_IGNORE_EMPTYFILE is Y or y
         */


static const std::string UTSUSEMIUSERPRIVTEMPORALFILEPATH = "ana/tmp";
static const std::string UTSUSEMIUSERPRIVXMLFILEPATH = "ana/xml";
static const std::string UTSUSEMIUSERPRIVTEMPWIRINGINFOBASE = "wiringinfo_tmp_%s_%s.xml";
static const std::string UTSUSEMIUSERPRIVTEMPDETECTORINFOBASE = "detectorinfo_tmp_%s_%s.xml";
static const std::string UTSUSEMIDEFAULTANAENVIRONFILE = "environ_ana.xml";
static const std::string UTSUSEMIENVIRONPATHINRUNFOLDER = "params/Utsusemi";

static const std::string UTSUSEMI_KEY_INTENSITY = "Intensity";
static const std::string UTSUSEMI_KEY_COUNTS_UNIT = "counts";
static const std::string UTSUSEMI_KEY_ARB_UNIT = "arb. unit";
static const std::string UTSUSEMI_KEY_ERROR = "Error";
static const std::string UTSUSEMI_KEY_TOF = "TOF";
static const std::string UTSUSEMI_KEY_TOF_UNIT = "micro-sec";
static const std::string UTSUSEMI_KEY_ENERGY = "Energy";
static const std::string UTSUSEMI_KEY_ENERGYTRANSFER = "EnergyTransfer";
static const std::string UTSUSEMI_KEY_ENERGY_UNIT = "meV";
static const std::string UTSUSEMI_KEY_LAMBDA = "Lambda";
static const std::string UTSUSEMI_KEY_LAMBDA_UNIT = "Ang";
static const std::string UTSUSEMI_KEY_MOMENTTRANSFER = "MomentumTransfer";
static const std::string UTSUSEMI_KEY_MOMENTTRANSFER_UNIT = "1/Ang";
static const std::string UTSUSEMI_KEY_DVALUE = "d";
static const std::string UTSUSEMI_KEY_HW = "hw";
static const std::string UTSUSEMI_KEY_HW_DNA = "HW";
static const std::string UTSUSEMI_KEY_UNKNOWN = "Unknown";
static const std::string UTSUSEMI_KEY_UNKNOWN_UNIT = "unknown";
static const std::string UTSUSEMI_KEY_QX = "Qx";
static const std::string UTSUSEMI_KEY_QY = "Qy";
static const std::string UTSUSEMI_KEY_QZ = "Qz";
static const std::string UTSUSEMI_KEY_VIEWX = "Vx";
static const std::string UTSUSEMI_KEY_VIEWY = "Vy";
static const std::string UTSUSEMI_KEY_VIEWZ = "Vz";
static const std::string UTSUSEMI_KEY_VIEWW = "Vw";


static const std::string UTSUSEMI_KEY_HEAD_RUNNUMBER = "RUNNUMBER";
static const std::string UTSUSEMI_KEY_HEAD_MONITORCOUNT = "MONITORCOUNT";
static const std::string UTSUSEMI_KEY_HEAD_INSTRUMENT = "INSTRUMENT";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLETYPE = "SAMPLETYPE";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLETYPE_POWDER = "Powder";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLETYPE_UNKNOWN = "unknown";
static const std::string UTSUSEMI_KEY_HEAD_MEASPERIOD = "MEASPERIOD";
static const std::string UTSUSEMI_KEY_HEAD_KICKERCOUNT = "KICKERCOUNT";
static const std::string UTSUSEMI_KEY_HEAD_CASEID = "CASEID";
static const std::string UTSUSEMI_KEY_HEAD_L1 = "L1";
static const std::string UTSUSEMI_KEY_HEAD_TYPICALL2 = "TypicalL2";
static const std::string UTSUSEMI_KEY_HEAD_TYPICALDS = "TypicalDS";
static const std::string UTSUSEMI_KEY_HEAD_TYPICALPIXELSIZE = "TypicalPixelSize";
static const std::string UTSUSEMI_KEY_HEAD_MASKED = "MASKED";
static const std::string UTSUSEMI_KEY_HEAD_DETID = "DETID";
static const std::string UTSUSEMI_KEY_HEAD_BANKID = "BANKID";
static const std::string UTSUSEMI_KEY_HEAD_INDEXINBANK = "INDEXINBANK";
static const std::string UTSUSEMI_KEY_HEAD_BANKIDLIST = "BANKIDLIST";
static const std::string UTSUSEMI_KEY_HEAD_BANKNAMELIST = "BANKNAMELIST";
static const std::string UTSUSEMI_KEY_HEAD_BANKSIZELIST = "BANKSIZELIST";
static const std::string UTSUSEMI_KEY_HEAD_MASKDEC = "MASKEDElementContainer";
static const std::string UTSUSEMI_KEY_HEAD_DETPOSINFO = "DETPOSINFO";
static const std::string UTSUSEMI_KEY_HEAD_PIXELPOSITION = "PixelPosition";
static const std::string UTSUSEMI_KEY_HEAD_PIXELCOVERAGE = "PixelCoverage";
static const std::string UTSUSEMI_KEY_HEAD_PIXELSOLIDANGLE = "PixelSolidAngle";
static const std::string UTSUSEMI_KEY_HEAD_PIXELPOLARANGLES = "PixelPolarAngle";
static const std::string UTSUSEMI_KEY_HEAD_PIXELAZIMANGLES = "PixelAzimAngle";
static const std::string UTSUSEMI_KEY_HEAD_POLARANGLE = "PolarAngle";
static const std::string UTSUSEMI_KEY_HEAD_AZIMANGLE = "AzimAngle";
static const std::string UTSUSEMI_KEY_HEAD_TOTALCOUNTS = "TotalCounts";
static const std::string UTSUSEMI_KEY_HEAD_EI = "Ei";
static const std::string UTSUSEMI_KEY_HEAD_EF = "Ef";
static const std::string UTSUSEMI_KEY_HEAD_PIXELID = "PIXELID";
static const std::string UTSUSEMI_KEY_HEAD_XRANGE = "XRANGE";
static const std::string UTSUSEMI_KEY_HEAD_LABEL = "Label";
static const std::string UTSUSEMI_KEY_HEAD_XPOS = "XPOS";
static const std::string UTSUSEMI_KEY_HEAD_YPOS = "YPOS";
static const std::string UTSUSEMI_KEY_HEAD_DATAPROCESSED = "DATAPROCESSED";
static const std::string UTSUSEMI_KEY_HEAD_ISHISTOGRAM = "isHistogram";

static const std::string UTSUSEMI_KEY_HEAD_DETTYPE = "TYPE";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_PSD = "PSD";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_UPSD = "UPSD";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_MON = "MON";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_MONITOR = "MONITOR";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_SCIN1D = "SCIN1D";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_RPMT = "RPMT";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_MWPC = "MWPC";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_WLSF32 = "WLSF32";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_MUNID = "MUNID";
static const std::string UTSUSEMI_KEY_HEAD_DETTYPE_TRIGNET = "TRIGNET";

static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS = "SampleLatticeConsts";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_UVECT = "SampleUvec";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_VVECT = "SampleVvec";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX = "SampleUBMatrix";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_UBPRIORITY = "SampleUBMpriority";
static const std::string UTSUSEMI_KEY_HEAD_SAMPLE_ROTATESTEPS = "SampleRotateSteps";

std::string FindParamFilePath(std::string target="", std::string additionalPath="" );
        //!< Returns full file path using Utsusemi environment variables
        /*!< if target!="", this searches target in directory as below order:
         *   1. additionalPath/<target>
         *   2. ${CurrentDir}/<target>
         *   3. ${UTSUSEMI_BASE_DIR}/${UTSUSEMI_INST_CODE}/ana/xml/<target>
         *   4. ${UTSUSEMI_USR_DIR}/ana/xml/<target>
         *   5. /tmp/<target>
         *
         *   if target=="", this returns first existed dir in order above.
         *
         *   @param target          file name
         *   @param additionalPath  Additional search path
         *   @retval "" : fails to find.
         *   @retval std::string : found full path
         */
std::string FindTempFilePath(std::string target="", std::string additionalPath="" );
        //!< Returns full file path using Utsusemi environment variables
        /*!< if target!="", this searches target in directory as below order:
         *   1. additionalPath/<target>
         *   2. ${CurrentDir}/<target>
         *   3. ${UTSUSEMI_USR_DIR}/ana/tmp/<target>
         *   4. /tmp/<target>
         *
         *   if target=="", this returns first existed directory in order above.
         *
         *   @param target          file name
         *   @param additionalPath  Additional search path
         *   @retval "" : fails to find.
         *   @retval std::string : found full path
         */
std::string _FindFilePath( std::string target, std::string interPath, std::string additionalPath, bool isParam=true );
std::string FindRootDataFolder(std::string _dataDir="");
        //!< Checks given path (_dataDir) and returns full path using Utsusemi environment variables
        /*!< if _dataDir!="", _dataDir = environment value "UTSUSEMI_DATA_DIR"
         *   and check whether _dataDir path exists or not.
         *   Usually, returns _dataDir=/data
         *
         *   @param _dataDir  : root data folder like '/data'
         *   @retval "" : fails to find.
         *   @retval std::string : found full path
         */
std::vector<std::string> FindInstDataFolders(std::string _instCode, std::string _rootDir="");
        //!< Returns data folder for each instrument.
        /*!<
         *   Usually, returns /data/XXX, /data/XXX00, /data/XXX01,...
         *
         *   @param _instCode   : SIK, AMR, DNA, ...
         *   @param _rootDir    : /data
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
std::vector<std::string> FindRunDataFolders( UInt4 _runNo );
        //!< Returns Run (raw) data folder
        /*!<
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD, /data/XXX00/XXXnnnnnn_YYYYMMDD, ...
         *
         *   @param _runNo              : run number
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
std::vector<std::string> FindRunDataFolders( std::string _instCode, UInt4 _runNo );
        //!< Returns Run (raw) data folder
        /*!<
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD, /data/XXX00/XXXnnnnnn_YYYYMMDD, ...
         *
         *   @param _runNo              : run number
         *   @param _instCode           : SIK, AMR, DNA, ...
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
std::vector<std::string> FindRunDataFolders( std::string _instCode, UInt4 _runNo, std::vector<std::string> _instDataFolders );
        //!< Returns Run (raw) data folder
        /*!<
         *   Only runNo is given : other arguments are used by Utsusemi environment values.
         *   Only instCode and runNo are given : other argument is FindInstDataFolders results.
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD, /data/XXX00/XXXnnnnnn_YYYYMMDD, ...
         *
         *   @param _runNo              : run number
         *   @param _instCode           : SIK, AMR, DNA, ...
         *   @param _instDataFolders    : returned from FindInstDataFolders
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
UInt4 PutLatestRunNoFromDataFolder( std::string _instCode="", UInt4 _runNoUpperLimit=900000 );
        //!< Returns the latest Run Number in data folder
        /*!<
         *
         *   @param _instCode       : SIK, AMR, DNA, ...
         *   @param _runNoUpperLimit: The upper limit for run number
         *   @retval 0              : fails to find.
         *   @retval 1 to 999999    : the latest run number in data folder
         */
std::string FindEnvironFolderInRunData( UInt4 _runNo );
        //!< Returns params/Utsusemi folder in Run (raw) data
        /*!<
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD/params/Utsusemi,...
         *
         *   @param _runNo              : run number
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
std::string FindEnvironFolderInRunData( std::string _instCode, UInt4 _runNo );
        //!< Returns params/Utsusemi folder in Run (raw) data
        /*!<
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD/params/Utsusemi,...
         *
         *   @param _instCode           : SIK, AMR, DNA, ...
         *   @param _runNo              : run number
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
std::string FindEnvironFolderInRunData( std::string _instCode, UInt4 _runNo, std::vector<std::string> _instDataFolders );
        //!< Returns params/Utsusemi folder in Run (raw) data
        /*!<
         *   Usually, returns /data/XXX/XXXnnnnnn_YYYYMMDD/params/Utsusemi,...
         *
         *   @param _runNo              : run number
         *   @param _instCode           : SIK, AMR, DNA, ...
         *   @param _instDataFolders    : returned from FindInstDataFolders
         *   @retval empty std::vector   : fails to find.
         *   @retval std::vector<std::string> : found full path
         */
void _addPath( std::string *orgPath, std::string *addPath );

/////////////////////////////////////
// UtsusemiLogger
/////////////////////////////////////

//! Logger of Ustusemi
/*! stores any messages
 *  This executes as Singlton.
 */
class UtsusemiLogger
{
private:
    UtsusemiLogger(){};
    UtsusemiLogger(const UtsusemiLogger &other){};
    UtsusemiLogger &operator=(const UtsusemiLogger &other);
    ~UtsusemiLogger(){};
    std::vector<std::string> _Messages; // Messages
    std::vector<Int4>  _Levels;    // level=0 : normal, level=1 : worning, level=2 : error
    std::vector<std::string> _Timer;    // Time stamp in clocks
    bool _isQuiet;
    bool _isLogging;
    std::vector<std::string> _Label;
    void Initialize();
public:
    static UtsusemiLogger &getInstance();
    std::string _convT( const time_t *timer );
    void Add( const Int4 level, const std::string msg, const bool isForce=false );
        //!< Adds message
        /*!<
         *   @param level (Int4) 0:normal message, 1:worning message, 2:error message
         *   @param msg   (std::string) message
         *   @param isForce (bool) shows message in spite of _isQuiet flag
         *   @retval None
         */
    void Add( const std::vector<Int4> levels, const std::vector<std::string> msgs );
        //!< Adds many messages in a time
        /*!<
         *   @param levels (std::vector<Int4>) 0:normal message, 1:warning message, 2:error message
         *   @param msgs   (std::vector<std::string>) messages
         *   @retval None
         */
    void Add( const std::vector<Int4> levels, const std::vector<std::string> msgs, const std::vector<std::string> timer );
        //!< Adds many messages in a time
        /*!<
         *   @param levels (std::vector<Int4>) 0:normal message, 1:warning message, 2:error message
         *   @param msgs   (std::vector<std::string>) messages
         *   @param timer  (std::vector<std::string>) timers std::string
         *   @retval None
         */
    void Clear();
        //!< Clear stored messages
        /*!<
         *   @param None
         *   @retval None
         */
    void CheckLogQuiet();
        //!< Update the flag from the current UTSUSEMI_LOG_QUIET environment value
        /*!<
         *   @param None
         *   @retval None
         */
    void SetLoggingOn(){ _isLogging=true; }
        //!< Set the logging on
        /*!<
         *   @param None
         *   @retval None
         */
    void SetLoggingOff(){ _isLogging=false; }
        //!< Set the logging off
        /*!<
         *   @param None
         *   @retval None
         */
    bool LoggingStatus(){ return _isLogging; }
        //!< Return the logging status
        /*!<
         *   @param None
         *   @retval true
         *   @retval false
         */
    std::vector<Int4> PutLevels(){ return _Levels; }
        //!< Puts Levels
        /*!<
         *   @retval _Levels (std::vector<Int4>)
         */
    std::vector<std::string> PutMessages( const Int4 level=-1 );
        //!< Puts Messages
        /*!<
         *   @param level (Int4) -1: all messages, 0:normal, 1:warning, 2:error
         *   @retval _Messages (std::vector<std::string>)
         */
    void Dump( const std::string filename="" );
        //!< Dumps to file
        /*!<
         *   @param filename (std::string) filename including path
         *   @retval None
         */

};
std::vector<std::string> UtsusemiPutErrorMessages();
void UtsusemiError( const std::string msg, const bool isForce=false );
std::vector<std::string> UtsusemiPutWarningMessages();
void UtsusemiWarning( const std::string msg, const bool isForce=false );
std::vector<std::string> UtsusemiPutMessages();
void UtsusemiMessage( const std::string msg, const bool isForce=false );
void UtsusemiCheckLogQuiet();
void UtsusemiLoggerDump(const std::string filename="");
void UtsusemiLoggerOn();
void UtsusemiLoggerOff();
bool UtsusemiLoggerStatus();
void UtsusemiLoggerClear();

/////////////////////////////////////
// UtsusemiRunDataPathDict
/////////////////////////////////////

//! Dictionary for Run data path
/*! stores the found run data folders
 *  This is executed as a Singlton.
 */
class UtsusemiRunDataPathDict
{
private:
    UtsusemiRunDataPathDict(){};
    UtsusemiRunDataPathDict(const UtsusemiRunDataPathDict &other){};
    UtsusemiRunDataPathDict &operator=(const UtsusemiRunDataPathDict &other);
    ~UtsusemiRunDataPathDict(){};
    Map< std::vector<std::string> > _DictRunDataFolder;
    void Initialize();

public:
    static UtsusemiRunDataPathDict &getInstance();
    void Add( const std::string runNo, const std::vector<std::string> runFolders);
        //!< Adds path informations
        /*!<
         *   @param runNo (std::string) XXXnnnnnn like SIK012345
         *   @param runFolders (std::vector<std::string>) /data/SIK/SIK012345_20181218
         *   @retval None
         */
    std::vector<std::string> Put( const std::string runNo );
        //!< Puts path informations
        /*!<
         *   @param runNo (std::string) XXXnnnnnn like SIK012345
         *   @return std::vector<std::string> folders for runNo
         */
    void Dump();
        //!< Dumps of dictionary
        /*!<
         *   @param None
         *   @retval None
         */
    void Clear();
        //!< Clears dictionary
        /*!<
         *   @param None
         *   @retval None
         */
};
std::vector<std::string> UtsusemiPutRunDataPathFromDict(const std::string runNo);
void UtsusemiAddRunDataPathToDict(const std::string runNo, const std::vector<std::string> runFolders);
void UtsusemiDumpRunDataPathDict();
void UtsusemiClearRunDataPathDict();
#endif


// for VC++ only
#ifdef _MSC_VER
    // required for UtsusemiDetectorInfoEditroBase, UtsusemiWiringInfoEditorTemplate
    #include <process.h>
    #define  getpid  _getpid

#if _MSC_VER<1900
    // required for D4Matrix
    double round(double x);
#endif

    // required for D4Matrix, D4MatrixCalc, UtsusemiD4MatOnMem
    //void usleep(int usec);
#endif

