diff --git a/.gitignore b/.gitignore index cdbb78d8e..8cec4c3be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ #Build files *.o -build/ #Backup files *~ @@ -16,6 +15,8 @@ latex/ tmp/ doc/classdiagramRawEvent.svg ValgrindOut.xml +doc/ +doxywarning.txt #Compressed Files *.bz2 @@ -24,8 +25,9 @@ ValgrindOut.xml #Ignore the build and exec directory build/ +*build-*/ install/ -doc/ + #Ignore IDE files *.cbp @@ -44,4 +46,4 @@ HIS LDF HIS/* LDF/* -data +data \ No newline at end of file diff --git a/Acquisition/CMakeLists.txt b/Acquisition/CMakeLists.txt new file mode 100644 index 000000000..c5907ed8a --- /dev/null +++ b/Acquisition/CMakeLists.txt @@ -0,0 +1,21 @@ +#Adds the install prefix for referencing in the source code +add_definitions(-D INSTALL_PREFIX="\\"${CMAKE_INSTALL_PREFIX}\\"") + +#Build the pixie interface +include_directories(Interface/include) +add_subdirectory(Interface/source) + +#Build the MCA objects +include_directories(MCA/include) +add_subdirectory(MCA) + +#Build PxiDump +add_subdirectory(PxiDump) + +#Build poll +add_subdirectory(Poll) + +#Build the setup tools +if (BUILD_SETUP) + add_subdirectory(Setup) +endif() \ No newline at end of file diff --git a/Interface/include/Lock.h b/Acquisition/Interface/include/Lock.h similarity index 100% rename from Interface/include/Lock.h rename to Acquisition/Interface/include/Lock.h diff --git a/Interface/include/PixieInterface.h b/Acquisition/Interface/include/PixieInterface.h similarity index 92% rename from Interface/include/PixieInterface.h rename to Acquisition/Interface/include/PixieInterface.h index 18637f491..860d7c4b0 100644 --- a/Interface/include/PixieInterface.h +++ b/Acquisition/Interface/include/PixieInterface.h @@ -91,6 +91,8 @@ class PixieInterface bool ReadConfigurationFile(const char *fn); + /// @brief Parses the input from configuration file for the ModuleType tag. + std::string ParseModuleTypeTag(std::string value); bool GetSlots(const char *slotF = NULL); // wrappers to the pixie-16 app functions bool Init(bool offlineMode = false); @@ -119,7 +121,7 @@ class PixieInterface double GetLiveTime(int mod, int chan); double GetRealTime(int mod); double GetProcessedEvents(int mod); - bool GetModuleInfo(unsigned short mod, unsigned short *rev, unsigned int *serNum, unsigned short *adcBits, unsigned short *adcMsps); + bool GetModuleInfo(const unsigned short &mod, unsigned short *rev, unsigned int *serNum, unsigned short *adcBits, unsigned short *adcMsps); // # # bool StartHistogramRun(unsigned short mode = NEW_RUN); bool StartHistogramRun(unsigned short mod, unsigned short mode); @@ -180,19 +182,17 @@ class PixieInterface #endif static std::set validConfigKeys; - std::map configStrings; + std::map> configStrings; bool doneInit; - // convert a configuration string to be relative to pixieBaseDir unless it begins with a . - std::string ConfigFileName(const std::string &str); + /// @brief Convert a configuration string to be relative to PixieBaseDir unless it begins with a . + std::string ConfigFileName(const std::string &type, const std::string &str); // checks retval and outputs default OK/ERROR message bool CheckError(bool exitOnError = false) const; unsigned short numberCards; unsigned short slotMap[MAX_MODULES]; - unsigned short firmwareConfig[MAX_MODULES]; - bool hasAlternativeConfig; stats_t statistics; diff --git a/Interface/include/PixieSupport.h b/Acquisition/Interface/include/PixieSupport.h similarity index 100% rename from Interface/include/PixieSupport.h rename to Acquisition/Interface/include/PixieSupport.h diff --git a/Interface/include/Utility.h b/Acquisition/Interface/include/Utility.h similarity index 100% rename from Interface/include/Utility.h rename to Acquisition/Interface/include/Utility.h diff --git a/Interface/source/CMakeLists.txt b/Acquisition/Interface/source/CMakeLists.txt similarity index 74% rename from Interface/source/CMakeLists.txt rename to Acquisition/Interface/source/CMakeLists.txt index afbf41bac..c571fff15 100644 --- a/Interface/source/CMakeLists.txt +++ b/Acquisition/Interface/source/CMakeLists.txt @@ -3,7 +3,8 @@ set(Interface_SOURCES PixieInterface.cpp Lock.cpp) add_library(PixieInterface STATIC ${Interface_SOURCES}) #Order is important, PXI before PLX -target_link_libraries(PixieInterface PixieCoreStatic ${PXI_LIBRARIES} ${PLX_LIBRARIES}) +target_link_libraries(PixieInterface PaassCoreStatic ${PXI_LIBRARIES} + ${PLX_LIBRARIES}) set(Support_SOURCES PixieSupport.cpp) add_library(PixieSupport STATIC ${Support_SOURCES}) diff --git a/Interface/source/Lock.cpp b/Acquisition/Interface/source/Lock.cpp similarity index 100% rename from Interface/source/Lock.cpp rename to Acquisition/Interface/source/Lock.cpp diff --git a/Interface/source/PixieInterface.cpp b/Acquisition/Interface/source/PixieInterface.cpp similarity index 69% rename from Interface/source/PixieInterface.cpp rename to Acquisition/Interface/source/PixieInterface.cpp index b81bba3b5..a14e1858d 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Acquisition/Interface/source/PixieInterface.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -96,39 +97,37 @@ bool PixieInterface::Histogram::Write(ofstream &out) return true; } -PixieInterface::PixieInterface(const char *fn) : hasAlternativeConfig(false), lock("PixieInterface") +PixieInterface::PixieInterface(const char *fn) : lock("PixieInterface") { SetColorTerm(); // Set-up valid configuration keys if they don't exist yet if (validConfigKeys.empty()) { - //? perhaps these should allow more than just one alternate firmware configuration - validConfigKeys.insert("AltComFpgaFile"); - validConfigKeys.insert("AltDspConfFile"); - validConfigKeys.insert("AltDspVarFile"); - validConfigKeys.insert("AltSpFpgaFile"); - validConfigKeys.insert("AltTrigFpgaFile"); - // standard files + // module files + validConfigKeys.insert("ModuleType"); + validConfigKeys.insert("ModuleBaseDir"); + validConfigKeys.insert("SpFpgaFile"); + validConfigKeys.insert("TrigFpgaFile"); validConfigKeys.insert("ComFpgaFile"); validConfigKeys.insert("DspConfFile"); validConfigKeys.insert("DspVarFile"); + // global files + validConfigKeys.insert("PixieBaseDir"); validConfigKeys.insert("DspSetFile"); validConfigKeys.insert("DspWorkingSetFile"); validConfigKeys.insert("ListModeFile"); - validConfigKeys.insert("PixieBaseDir"); validConfigKeys.insert("SlotFile"); - validConfigKeys.insert("SpFpgaFile"); - validConfigKeys.insert("TrigFpgaFile"); validConfigKeys.insert("CrateConfig"); } if (!ReadConfigurationFile(fn)) { - std::cout << Display::ErrorStr() << " Unable to read configuration file: '" << fn << "\n"; - std::cout << Display::InfoStr() << " Did you forget to copy default " - "configuration files from '" << INSTALL_PREFIX - << "/share/config' to the running directory?\n"; + std::cout << Display::ErrorStr() << " Unable to read configuration file: '" << fn << "'\n"; + if (configStrings.find("global") == configStrings.end()) { + std::cout << Display::InfoStr() << " Are the configuration files in the running directory?\n"; + std::cout << "Autoconfigured files are avaialable in " << INSTALL_PREFIX << "\n"; + } exit(EXIT_FAILURE); } //Overwrite the default path 'pxisys.ini' with the one specified in the scan file. - PCISysIniFile = configStrings["CrateConfig"].c_str(); + PCISysIniFile = configStrings["global"]["CrateConfig"].c_str(); } @@ -145,6 +144,68 @@ PixieInterface::~PixieInterface() retval = Pixie16ExitSystem(numberCards); CheckError(); } +std::string PixieInterface::ParseModuleTypeTag(std::string value) { + std::string moduleType = "invalid"; + int adcRes = -1, msps = -1; + string revision = ""; + + string adcResStr = ""; + size_t adcResLocEnd = value.find('b'); + if (adcResLocEnd != string::npos) { + size_t adcResLocBegin = value.find_last_not_of("0123456789", adcResLocEnd - 1); + if (adcResLocBegin == string::npos) adcResLocBegin = 0; + else adcResLocBegin++; + adcResStr = value.substr(adcResLocBegin, adcResLocEnd - adcResLocBegin); + } + + if (adcResStr.empty()) { + std::cout << ErrorStr() << " Invalid ModuleType, ADC resolution not specified: '" << InfoStr(value) << "'.\n"; + } + else { + try { adcRes = std::stoi(adcResStr); } + catch (const std::invalid_argument& ia) { + std::cout << ErrorStr() << " Invalid ADC resolution: '" << value << "' (" << adcResStr << ")\n"; + } + } + + string mspsStr = ""; + size_t mspsLocEnd = value.find('m'); + if (mspsLocEnd != string::npos) { + size_t mspsLocBegin = value.find_last_not_of("0123456789", mspsLocEnd - 1); + if (mspsLocBegin == string::npos) mspsLocBegin = 0; + else mspsLocBegin++; + mspsStr = value.substr(mspsLocBegin, mspsLocEnd - mspsLocBegin); + } + + if (mspsStr.empty()) { + std::cout << ErrorStr() << " Invalid ModuleType, sample rate not specified: '" << InfoStr(value) << "'.\n"; + } + else { + try { msps = std::stoi(mspsStr); } + catch (const std::invalid_argument& ia) { + std::cout << ErrorStr() << " Invalid sample rate: '" << value << "' (" << mspsStr << ")\n"; + } + } + + size_t revLoc = value.find("rev"); + string revStr = "not specified"; + if (revLoc != string::npos) revStr = value.substr(revLoc+3, 1); + if (revStr.length() == 1) { + revision = revStr; + } + else { + std::cout << ErrorStr() << " Invalid Revision: '" << value << "' (" << revStr << ")\n"; + } + + if (adcRes > 0 && msps > 0 && revision != "") { + stringstream moduleTypeStream; + moduleTypeStream << adcRes << "b" << msps << "m-rev" << revision; + moduleType = moduleTypeStream.str(); + } + + return moduleType; + +} bool PixieInterface::ReadConfigurationFile(const char *fn) { @@ -155,8 +216,13 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) stringbuf tag, value; string line; + std::cout << "Reading Pixie Configuration\n"; + //Loop over lines in config file - while (std::getline(in,line)) { + bool error = false; + bool newModule = false; + string moduleType = ""; + while (std::getline(in,line)) { //Get a string stream of current line std::istringstream lineStream(line); //If the line leads with a '#' we ignore it. @@ -169,13 +235,63 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) if (validConfigKeys.find(tag) == validConfigKeys.end()) { cout << "Unrecognized tag " << WarningStr(tag) << " in PixieInterface configuration file." << endl; } + + //Parse the ModuleType tag. + //Moule type is expected as with the following three items ##b, ###m, rev# + if (tag == "ModuleType") { + + moduleType = ParseModuleTypeTag(value); + + std::cout << "Module Type: "; + + //If we have multiple entires for one type we throw and error. + if (configStrings.find(moduleType) != configStrings.end()) { + error = true; + + std::cout << ErrorStr(moduleType) << "\n"; + + std::cout << ErrorStr() << " Duplicate module type information found for " << moduleType << "!\n"; + std::cout << " Remove or comment out tags to be ignored.\n"; + + moduleType = "ignored_" + moduleType; + } + else {std::cout << InfoStr(moduleType) << "\n";} + + newModule = true; + } //Store configuration - configStrings[tag] = ConfigFileName(value); + else if (tag == "SpFpgaFile" || tag == "ComFpgaFile" || tag == "DspConfFile" || tag == "DspVarFile" || tag == "TrigFpgaFile" || tag == "ModuleBaseDir") { + if (moduleType == "") { + moduleType = "default"; + std::cout << "Module Type: " << InfoStr(moduleType) << "\n"; + } + if (newModule && tag != "ModuleBaseDir") { + std::cout << " PixieBaseDir\t" << configStrings["global"]["PixieBaseDir"] << "\n"; + } + newModule = false; + if (configStrings[moduleType][tag] != "") { + error = true; + + std::cout << " " << ErrorStr(tag) << "\t" << value << endl; + + std::cout << ErrorStr() << " Duplicate " << tag << " specified for " << moduleType << "!\n"; + std::cout << " Remove or comment out tags to be ignored.\n"; + + tag = "ignored_" + tag; + } + else { + std::cout << " " << tag << "\t" << value << endl; + } + configStrings[moduleType][tag] = ConfigFileName(moduleType,value); + } + else { + std::cout << " " << tag << "\t" << value << endl; + configStrings["global"][tag] = ConfigFileName("global",value); + } //Check if BaseDir is defined differently then in the environment if (tag == "PixieBaseDir") { - cout << "Pixie base directory is " << InfoStr(value) << endl; // check if this matches the environment PXI_ROOT if it is set if (getenv("PXI_ROOT") != NULL) { if ( value != string(getenv("PXI_ROOT")) ) { @@ -186,6 +302,8 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) } } + if (error) return false; + return true; } @@ -194,7 +312,7 @@ bool PixieInterface::GetSlots(const char *slotF) char restOfLine[CONFIG_LINE_LENGTH]; if (slotF == NULL) - slotF = configStrings["SlotFile"].c_str(); + slotF = configStrings["global"]["SlotFile"].c_str(); ifstream in(slotF); @@ -213,13 +331,6 @@ bool PixieInterface::GetSlots(const char *slotF) } for (int i = 0; i < numberCards; i++) { - // check if this is a module with an alternative firmware configuration (tagged with '*') - if (in.peek() == '*') { - in.ignore(); - hasAlternativeConfig = true; - firmwareConfig[i] = 1; // alternative config - } else firmwareConfig[i] = 0; // standard config - in >> slotMap[i]; in.getline(restOfLine, CONFIG_LINE_LENGTH, '\n'); if (!in.good()) { @@ -259,51 +370,86 @@ bool PixieInterface::Init(bool offlineMode) bool PixieInterface::Boot(int mode, bool useWorkingSetFile) { string &setFile = useWorkingSetFile ? - configStrings["DspWorkingSetFile"] : configStrings["DspSetFile"]; + configStrings["global"]["DspWorkingSetFile"] : configStrings["global"]["DspSetFile"]; - LeaderPrint("Booting Pixie"); + LeaderPrint("Boot Configuration"); - //Break the leader print for the Boot status. - if (mode == BootAll) std::cout << std::endl; + //Loop through each module and determine its type. + //We also check if the modules are all the same. If not we set multiConf to true. + bool multiConf = false; + std::vector< std::string > moduleTypes; + for (int mod = 0; mod < numberCards; mod++) { + unsigned short rev, adcBits, adcMsps; + unsigned int serNum; + GetModuleInfo(mod, &rev, &serNum, &adcBits, &adcMsps); + + stringstream moduleType; + moduleType << adcBits << "b" << adcMsps << "m"; + moduleType << "-rev" << (char)(97 + rev - 10 ); + + if (mod > 0 && moduleType.str() != moduleTypes.back()) multiConf = true; + moduleTypes.push_back(moduleType.str()); + } bool goodBoot = true; - if (hasAlternativeConfig) { + if (multiConf) { // must proceed through boot module by module - cout << InfoStr("[MULTICONFIG]") << "\n"; - for (int i=0; i < numberCards; i++) { - if (firmwareConfig[i] == 1) { - // use the Alt... files - retval = Pixie16BootModule(&configStrings["AltComFpgaFile"][0], - &configStrings["AltSpFpgaFile"][0], - &configStrings["AltTrigFpgaFile"][0], - &configStrings["AltDspConfFile"][0], - &setFile[0], - &configStrings["AltDspVarFile"][0], - i, mode); - } else { - // use the standard files - retval = Pixie16BootModule(&configStrings["ComFpgaFile"][0], - &configStrings["SpFpgaFile"][0], - &configStrings["TrigFpgaFile"][0], - &configStrings["DspConfFile"][0], - &setFile[0], - &configStrings["DspVarFile"][0], - i, mode); + + //Break the leader print for the boot configuration status. + cout << InfoStr("[MULTI]") << "\n"; + + //Check that all module types are valid. + bool error = false; + for (int mod = 0; mod < numberCards; mod++) { + if (configStrings.find(moduleTypes.at(mod)) == configStrings.end()) { + std::cout << ErrorStr() << " Configuration not defined for type " << moduleTypes.at(mod) << " (mod " << mod << ")\n"; + error = true; } - LeaderPrint("Booting Pixie Module "); + } + if (error) return false; + + for (int i=0; i < numberCards; i++) { + retval = Pixie16BootModule(&configStrings[moduleTypes.at(i)]["ComFpgaFile"][0], + &configStrings[moduleTypes.at(i)]["SpFpgaFile"][0], + &configStrings[moduleTypes.at(i)]["TrigFpgaFile"][0], + &configStrings[moduleTypes.at(i)]["DspConfFile"][0], + &setFile[0], + &configStrings[moduleTypes.at(i)]["DspVarFile"][0], + i, mode); + + stringstream leader; + leader << "Booting Pixie (" << moduleTypes.at(i) << ") Module " << i; + LeaderPrint(leader.str()); goodBoot = (goodBoot && !CheckError(true)); } } else { + //Break the leader print for the boot configuration status. + cout << InfoStr("[SINGLE]") << "\n"; + + //Determine if we need to use "default" type. + string moduleType = moduleTypes.front(); + if (configStrings.find(moduleType) == configStrings.end()) { + moduleType = "default"; + if (configStrings.find(moduleType) == configStrings.end()) { + std::cout << ErrorStr() << " Config not defined for type " << moduleTypes.back() << "\n"; + return false; + } + } + //std::cout << "Booting all modules as type " << InfoStr(moduleType) << "\n"; + // boot all at once - retval = Pixie16BootModule(&configStrings["ComFpgaFile"][0], - &configStrings["SpFpgaFile"][0], - &configStrings["TrigFpgaFile"][0], - &configStrings["DspConfFile"][0], + retval = Pixie16BootModule(&configStrings[moduleType]["ComFpgaFile"][0], + &configStrings[moduleType]["SpFpgaFile"][0], + &configStrings[moduleType]["TrigFpgaFile"][0], + &configStrings[moduleType]["DspConfFile"][0], &setFile[0], - &configStrings["DspVarFile"][0], + &configStrings[moduleType]["DspVarFile"][0], numberCards, mode); - if (mode == BootAll) LeaderPrint("Booting Pixie"); + + stringstream leader; + leader << "Booting Pixie (" << moduleType << ")"; + LeaderPrint(leader.str()); goodBoot = !CheckError(true); } @@ -325,6 +471,7 @@ bool PixieInterface::Boot(int mode, bool useWorkingSetFile) hadError = true; } } + if (hadError) cout << ErrorStr() << endl; else if (updated) @@ -446,7 +593,7 @@ void PixieInterface::PrintSglChanPar(const char *name, int mod, int chan, double bool PixieInterface::SaveDSPParameters(const char *fn) { if (fn == NULL) - fn = &configStrings["DspWorkingSetFile"][0]; + fn = &configStrings["global"]["DspWorkingSetFile"][0]; strncpy(tmpName, fn, nameSize); LeaderPrint("Writing DSP parameters"); @@ -824,12 +971,25 @@ bool PixieInterface::ToggleChannelBit(int mod, int chan, const char *parameter, return WriteSglChanPar(parameter, dval, mod, chan); } -string PixieInterface::ConfigFileName(const string &str) +string PixieInterface::ConfigFileName(const string &type, const string &str) { - if (str[0] == '.' || str[0] == '/') - return str; - else - return configStrings["PixieBaseDir"] + '/' + str; + //If the file name starts with a '.' or a '/' then we assume the BaseDir should be ignored. + if (str[0] == '.' || str[0] == '/') return str; + + //Try to determine correct BaseDir. + string baseDir; + //If the file is a global type we use PixieBaseDir + if (type == "global") baseDir = configStrings["global"]["PixieBaseDir"]; + //Otherwise we try the ModuleBaseDir for the specified type and then the PixieBaseDir + else { + baseDir = configStrings[type]["ModuleBaseDir"]; + if (baseDir.empty()) baseDir = configStrings["global"]["PixieBaseDir"]; + } + //No success so we assume they want the local directory. + if (baseDir.empty()) baseDir = "."; + + //Return the appended string. + return baseDir + '/' + str; } bool PixieInterface::CheckError(bool exitOnError) const @@ -841,7 +1001,7 @@ bool PixieInterface::CheckError(bool exitOnError) const return (retval < 0); } -bool PixieInterface::GetModuleInfo(unsigned short mod, unsigned short *rev, unsigned int *serNum, unsigned short *adcBits, unsigned short *adcMsps) { +bool PixieInterface::GetModuleInfo(const unsigned short &mod, unsigned short *rev, unsigned int *serNum, unsigned short *adcBits, unsigned short *adcMsps) { //Return false if error code provided. return (Pixie16ReadModuleInfo(mod,rev,serNum,adcBits,adcMsps) == 0); } diff --git a/Interface/source/PixieSupport.cpp b/Acquisition/Interface/source/PixieSupport.cpp similarity index 100% rename from Interface/source/PixieSupport.cpp rename to Acquisition/Interface/source/PixieSupport.cpp diff --git a/Interface/source/Utility.cpp b/Acquisition/Interface/source/Utility.cpp similarity index 100% rename from Interface/source/Utility.cpp rename to Acquisition/Interface/source/Utility.cpp diff --git a/Interface/source/test.cpp b/Acquisition/Interface/source/test.cpp similarity index 100% rename from Interface/source/test.cpp rename to Acquisition/Interface/source/test.cpp diff --git a/MCA/CMakeLists.txt b/Acquisition/MCA/CMakeLists.txt similarity index 100% rename from MCA/CMakeLists.txt rename to Acquisition/MCA/CMakeLists.txt diff --git a/MCA/include/DrrBlock.h b/Acquisition/MCA/include/DrrBlock.h similarity index 100% rename from MCA/include/DrrBlock.h rename to Acquisition/MCA/include/DrrBlock.h diff --git a/MCA/include/Exceptions.h b/Acquisition/MCA/include/Exceptions.h similarity index 100% rename from MCA/include/Exceptions.h rename to Acquisition/MCA/include/Exceptions.h diff --git a/MCA/include/HisDrr.h b/Acquisition/MCA/include/HisDrr.h similarity index 100% rename from MCA/include/HisDrr.h rename to Acquisition/MCA/include/HisDrr.h diff --git a/MCA/include/MCA.h b/Acquisition/MCA/include/MCA.h similarity index 100% rename from MCA/include/MCA.h rename to Acquisition/MCA/include/MCA.h diff --git a/MCA/include/MCA_DAMM.h b/Acquisition/MCA/include/MCA_DAMM.h similarity index 100% rename from MCA/include/MCA_DAMM.h rename to Acquisition/MCA/include/MCA_DAMM.h diff --git a/MCA/include/MCA_ROOT.h b/Acquisition/MCA/include/MCA_ROOT.h similarity index 100% rename from MCA/include/MCA_ROOT.h rename to Acquisition/MCA/include/MCA_ROOT.h diff --git a/MCA/share/mca_input.txt b/Acquisition/MCA/share/mca_input.txt similarity index 100% rename from MCA/share/mca_input.txt rename to Acquisition/MCA/share/mca_input.txt diff --git a/MCA/source/CMakeLists.txt b/Acquisition/MCA/source/CMakeLists.txt similarity index 100% rename from MCA/source/CMakeLists.txt rename to Acquisition/MCA/source/CMakeLists.txt diff --git a/MCA/source/HisDrr.cpp b/Acquisition/MCA/source/HisDrr.cpp similarity index 99% rename from MCA/source/HisDrr.cpp rename to Acquisition/MCA/source/HisDrr.cpp index 56ffec8be..bb33bb4e7 100644 --- a/MCA/source/HisDrr.cpp +++ b/Acquisition/MCA/source/HisDrr.cpp @@ -150,7 +150,7 @@ HisDrr::HisDrr(const string &drr, const string &his, const string &input) { // Using information from drrData drr header is created DrrHeader head; - int totLength; + int totLength = 0; for (unsigned int i = 0; i < drrData.size(); ++i) totLength += (drrData[i].scaled[0]+drrData[i].scaled[1])*drrData[i].halfWords; // Magic words (whatever they do...) diff --git a/MCA/source/MCA.cpp b/Acquisition/MCA/source/MCA.cpp similarity index 100% rename from MCA/source/MCA.cpp rename to Acquisition/MCA/source/MCA.cpp diff --git a/MCA/source/MCA_DAMM.cpp b/Acquisition/MCA/source/MCA_DAMM.cpp similarity index 100% rename from MCA/source/MCA_DAMM.cpp rename to Acquisition/MCA/source/MCA_DAMM.cpp diff --git a/MCA/source/MCA_ROOT.cpp b/Acquisition/MCA/source/MCA_ROOT.cpp similarity index 100% rename from MCA/source/MCA_ROOT.cpp rename to Acquisition/MCA/source/MCA_ROOT.cpp diff --git a/MCA/source/MCA_exec.cpp b/Acquisition/MCA/source/MCA_exec.cpp similarity index 100% rename from MCA/source/MCA_exec.cpp rename to Acquisition/MCA/source/MCA_exec.cpp diff --git a/Poll/CMakeLists.txt b/Acquisition/Poll/CMakeLists.txt similarity index 98% rename from Poll/CMakeLists.txt rename to Acquisition/Poll/CMakeLists.txt index 240248e61..673ea3c38 100644 --- a/Poll/CMakeLists.txt +++ b/Acquisition/Poll/CMakeLists.txt @@ -1,4 +1,3 @@ - include_directories(include) add_subdirectory(source) diff --git a/Poll/include/poll2_core.h b/Acquisition/Poll/include/poll2_core.h similarity index 95% rename from Poll/include/poll2_core.h rename to Acquisition/Poll/include/poll2_core.h index c8457c17b..3db778315 100644 --- a/Poll/include/poll2_core.h +++ b/Acquisition/Poll/include/poll2_core.h @@ -235,6 +235,13 @@ class Poll{ /// Broadcast a data spill onto the network in the classic pacman format. void broadcast_pac_data(); + /// @brief Splits the arguments to pread and pwrite on a colon delimeter. + /// @param[in] arg The argument to be split. + /// @param[out] start The first value in the string indicating the first mod / ch. + /// @param[out] start The second value in the string indicating the last mod / ch. + /// @return Whether the attempt was succesful. + bool SplitParameterArgs(const std::string &arg, int &start, int &stop); + public: /// Default constructor. Poll(); diff --git a/Poll/include/poll2_stats.h b/Acquisition/Poll/include/poll2_stats.h similarity index 100% rename from Poll/include/poll2_stats.h rename to Acquisition/Poll/include/poll2_stats.h diff --git a/Poll/monitor.bash b/Acquisition/Poll/monitor.bash similarity index 100% rename from Poll/monitor.bash rename to Acquisition/Poll/monitor.bash diff --git a/Poll/send_alarm b/Acquisition/Poll/send_alarm similarity index 100% rename from Poll/send_alarm rename to Acquisition/Poll/send_alarm diff --git a/Poll/source/CMakeLists.txt b/Acquisition/Poll/source/CMakeLists.txt similarity index 85% rename from Poll/source/CMakeLists.txt rename to Acquisition/Poll/source/CMakeLists.txt index 86f4a8672..3d6cab51c 100644 --- a/Poll/source/CMakeLists.txt +++ b/Acquisition/Poll/source/CMakeLists.txt @@ -9,10 +9,10 @@ endif() set(LISTENER_SOURCES listener.cpp) add_executable(listener ${LISTENER_SOURCES}) -target_link_libraries(listener PixieCoreStatic) +target_link_libraries(listener PaassCoreStatic) set(MONITOR_SOURCES monitor.cpp) add_executable(monitor ${MONITOR_SOURCES}) -target_link_libraries(monitor PixieCoreStatic) +target_link_libraries(monitor PaassCoreStatic) install(TARGETS listener monitor DESTINATION bin) diff --git a/Poll/source/listener.cpp b/Acquisition/Poll/source/listener.cpp similarity index 100% rename from Poll/source/listener.cpp rename to Acquisition/Poll/source/listener.cpp diff --git a/Poll/source/monitor.cpp b/Acquisition/Poll/source/monitor.cpp similarity index 100% rename from Poll/source/monitor.cpp rename to Acquisition/Poll/source/monitor.cpp diff --git a/Poll/source/poll2.cpp b/Acquisition/Poll/source/poll2.cpp similarity index 100% rename from Poll/source/poll2.cpp rename to Acquisition/Poll/source/poll2.cpp diff --git a/Poll/source/poll2_core.cpp b/Acquisition/Poll/source/poll2_core.cpp similarity index 87% rename from Poll/source/poll2_core.cpp rename to Acquisition/Poll/source/poll2_core.cpp index 58b7d2434..208a444ea 100644 --- a/Poll/source/poll2_core.cpp +++ b/Acquisition/Poll/source/poll2_core.cpp @@ -19,7 +19,9 @@ #include #include #include +#include #include + #include #include #include @@ -233,8 +235,8 @@ void Poll::PrintModuleInfo() { unsigned short revision, adcBits, adcMsps; unsigned int serialNumber; if (pif->GetModuleInfo(mod, &revision, &serialNumber, &adcBits, &adcMsps)) { - std::cout << "Module " << mod << ": " << - "Serial Number " << serialNumber << ", " << + std::cout << "Module " << std::right << std::setw(2) << mod << ": " << + "Serial Number " << std::right << std::setw(4) << serialNumber << ", " << "Rev " << std::hex << std::uppercase << revision << std::dec << " " << "(" << revision << "), " << adcBits << "-bit " << adcMsps << " MS/s " << @@ -829,6 +831,31 @@ void Poll::get_traces(int mod_, int chan_, int thresh_/*=0*/){ delete[] module_data; } +/// This method splits the arguments for pread and pwrite on a colon delimeter. +/// This allows the user to proivde a range for the function for example, +/// \code pread 0 0:4 TRIGGER_THRESHOLD \code +/// will only read the TRIGGER_THRESHOLD for module 0, channels 0 to 4. +/// If the argument has no colons start and stop will be equal. +/// If the attmept is unsuccesful the mehtod returns false. +bool Poll::SplitParameterArgs(const std::string &arg, int &start, int &stop) { + //If a character is found that is nonnumeric or is not the delimeter we stop. + if (arg.find_first_not_of("-0123456789:") != std::string::npos) return false; + + size_t delimeterPos = arg.find(':'); + try { + start = std::stoi(arg.substr(0, delimeterPos)); + //If the delimeter was found we can seperate the stop otherwise set start = stop. + if (delimeterPos != std::string::npos) { + stop = std::stoi(arg.substr(delimeterPos + 1)); + if (start < 0 || stop < 0 || start > stop) return false; + } + else stop = start; + } + catch (const std::invalid_argument &ia) { + return false; + } + return true; +} /////////////////////////////////////////////////////////////////////////////// // Poll::CommandControl /////////////////////////////////////////////////////////////////////////////// @@ -846,10 +873,10 @@ void Poll::CommandControl(){ int select_dummy; if(server->Select(select_dummy)){ UDP_Packet pacman_command; - + // We have a pacman command. Retrieve the command server->RecvMessage((char *)&pacman_command, sizeof(UDP_Packet)); - + /* Valid poll commands 0x11 - INIT_ACQ 0x22 - START_ACQ @@ -1037,15 +1064,43 @@ void Poll::CommandControl(){ if(cmd == "pwrite"){ // Syntax "pwrite " if(p_args > 0 && arguments.at(0) == "help"){ pchan_help(); } else if(p_args >= 4){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - else if(!IsNumeric(arguments.at(1), sys_message_head, "Invalid channel specification")) continue; - else if(!IsNumeric(arguments.at(3), sys_message_head, "Invalid parameter value specification")) continue; - int mod = atoi(arguments.at(0).c_str()); - int ch = atoi(arguments.at(1).c_str()); - double value = std::strtod(arguments.at(3).c_str(), NULL); + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } + int chStart, chStop; + if (!SplitParameterArgs(arguments.at(1), chStart, chStop)) { + std::cout << "ERROR: Invalid channel argument: '" << arguments.at(1) << "'\n"; + continue; + } + + //Check that there are no characters in the string unless it is hex. + std::string &valueStr = arguments.at(3); + if (valueStr.find_last_not_of("+-eE0123456789.") != std::string::npos && + !((valueStr.find("0x") == 0 || valueStr.find("0X") == 0) && + valueStr.find_first_not_of("0123456789abcdefABCDEF", 2) == std::string::npos) ) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } + + double value; + try { value = std::stod(valueStr); } + catch (const std::invalid_argument &ia) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } ParameterChannelWriter writer; - if(forChannel(pif, mod, ch, writer, make_pair(arguments.at(2), value))){ pif->SaveDSPParameters(); } + bool error = false; + for (int mod = modStart; mod <= modStop; mod++) { + for (int ch = chStart; ch <= chStop; ch++) { + if(forChannel(pif, mod, ch, writer, make_pair(arguments.at(2), value))){ + error = true; + } + } + } + if (!error) pif->SaveDSPParameters(); } else{ std::cout << sys_message_head << "Invalid number of parameters to pwrite\n"; @@ -1055,13 +1110,38 @@ void Poll::CommandControl(){ else if(cmd == "pmwrite"){ // Syntax "pmwrite " if(p_args > 0 && arguments.at(0) == "help"){ pmod_help(); } else if(p_args >= 3){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - else if(!IsNumeric(arguments.at(2), sys_message_head, "Invalid parameter value specification")) continue; - int mod = atoi(arguments.at(0).c_str()); - unsigned int value = (unsigned int)std::strtoul(arguments.at(2).c_str(), NULL, 0); - + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } + + //Check that there are no characters in the string unless it is hex. + std::string &valueStr = arguments.at(2); + if (valueStr.find_last_not_of("0123456789") != std::string::npos && + !((valueStr.find("0x") == 0 || valueStr.find("0X") == 0) && + valueStr.find_first_not_of("0123456789abcdefABCDEF", 2) == std::string::npos) ) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } + + unsigned int value; + //Use stod to add hex capability. The decimal and negative values are + // caught above and rejected. + try { value = (unsigned int) std::stod(valueStr); } + catch (const std::invalid_argument &ia) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } + ParameterModuleWriter writer; - if(forModule(pif, mod, writer, make_pair(arguments.at(1), value))){ pif->SaveDSPParameters(); } + bool error = false; + for (int mod = modStart; mod <= modStop; mod++) { + if(!forModule(pif, mod, writer, make_pair(arguments.at(1), value))){ + error = true; + } + } + if (!error) pif->SaveDSPParameters(); } else{ std::cout << sys_message_head << "Invalid number of parameters to pmwrite\n"; @@ -1074,17 +1154,27 @@ void Poll::CommandControl(){ std::cout << sys_message_head << "Warning! Cannot view pixie parameters while acquisition is running\n\n"; continue; } - + if(cmd == "pread"){ // Syntax "pread " if(p_args > 0 && arguments.at(0) == "help"){ pchan_help(); } else if(p_args >= 3){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - else if(!IsNumeric(arguments.at(1), sys_message_head, "Invalid channel specification")) continue; - int mod = atoi(arguments.at(0).c_str()); - int ch = atoi(arguments.at(1).c_str()); - + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } + int chStart, chStop; + if (!SplitParameterArgs(arguments.at(1), chStart, chStop)) { + std::cout << "ERROR: Invalid channel argument: '" << arguments.at(1) << "'\n"; + continue; + } + ParameterChannelReader reader; - forChannel(pif, mod, ch, reader, arguments.at(2)); + for (int mod = modStart; mod <= modStop; mod++) { + for (int ch = chStart; ch <= chStop; ch++) { + forChannel(pif, mod, ch, reader, arguments.at(2)); + } + } } else{ std::cout << sys_message_head << "Invalid number of parameters to pread\n"; @@ -1094,11 +1184,16 @@ void Poll::CommandControl(){ else if(cmd == "pmread"){ // Syntax "pmread " if(p_args > 0 && arguments.at(0) == "help"){ pmod_help(); } else if(p_args >= 2){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - int mod = atoi(arguments.at(0).c_str()); + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } ParameterModuleReader reader; - forModule(pif, mod, reader, arguments.at(1)); + for (int mod = modStart; mod <= modStop; mod++) { + forModule(pif, mod, reader, arguments.at(1)); + } } else{ std::cout << sys_message_head << "Invalid number of parameters to pmread\n"; @@ -1113,11 +1208,18 @@ void Poll::CommandControl(){ } if(p_args >= 1){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - int mod = atoi(arguments.at(0).c_str()); - + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } + OffsetAdjuster adjuster; - if(forModule(pif, mod, adjuster, 0)){ pif->SaveDSPParameters(); } + bool error = false; + for (int mod = modStart; mod <= modStop; mod++) { + if(!forModule(pif, mod, adjuster, 0)){ error = true; } + } + if (!error) pif->SaveDSPParameters(); } else{ std::cout << sys_message_head << "Invalid number of parameters to adjust_offsets\n"; @@ -1153,14 +1255,28 @@ void Poll::CommandControl(){ BitFlipper flipper; if(p_args >= 3){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid module specification")) continue; - else if(!IsNumeric(arguments.at(1), sys_message_head, "Invalid channel specification")) continue; + int modStart, modStop; + if (!SplitParameterArgs(arguments.at(0), modStart, modStop)) { + std::cout << "ERROR: Invalid module argument: '" << arguments.at(0) << "'\n"; + continue; + } + int chStart, chStop; + if (!SplitParameterArgs(arguments.at(1), chStart, chStop)) { + std::cout << "ERROR: Invalid channel argument: '" << arguments.at(1) << "'\n"; + continue; + } flipper.SetCSRAbit(arguments.at(2)); std::string dum_str = "CHANNEL_CSRA"; - if(forChannel(pif, atoi(arguments.at(0).c_str()), atoi(arguments.at(1).c_str()), flipper, dum_str)){ - pif->SaveDSPParameters(); + bool error = false; + for (int mod = modStart; mod <= modStop; mod++) { + for (int ch = chStart; ch <= chStop; ch++) { + if(!forChannel(pif, mod, ch, flipper, dum_str)){ + error = true; + } + } } + if (!error) pif->SaveDSPParameters(); } else{ std::cout << sys_message_head << "Invalid number of parameters to toggle\n"; @@ -1194,8 +1310,24 @@ void Poll::CommandControl(){ else if(cmd == "csr_test"){ // Run CSRAtest method BitFlipper flipper; if(p_args >= 1){ - if(!IsNumeric(arguments.at(0), sys_message_head, "Invalid CSRA value specification")) continue; - flipper.CSRAtest((unsigned int)atoi(arguments.at(0).c_str())); + //Check that there are no characters in the string unless it is hex. + std::string &valueStr = arguments.at(0); + if (valueStr.find_last_not_of("0123456789") != std::string::npos && + !((valueStr.find("0x") == 0 || valueStr.find("0X") == 0) && + valueStr.find_first_not_of("0123456789abcdefABCDEF", 2) == std::string::npos) ) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } + unsigned int value; + //Use stod to add hex capability. The decimal and negative values are + // caught above and rejected. + try { value = (unsigned int) std::stod(valueStr); } + catch (const std::invalid_argument &ia) { + std::cout << "ERROR: Invalid parameter value: '" << valueStr << "'\n"; + continue; + } + + flipper.CSRAtest(value); } else{ std::cout << sys_message_head << "Invalid number of parameters to csr_test\n"; @@ -1485,7 +1617,7 @@ void Poll::RunControl(){ else{ std::cout << sys_message_head << "Attempting PIXIE crate reboot\n"; pif->Boot(PixieInterface::BootAll); - printf("Press any key to continue..."); + printf("Press Enter key to continue..."); std::cin.get(); do_reboot = false; } @@ -1580,7 +1712,7 @@ void Poll::RunControl(){ //Handle a stop signal if(do_stop_acq){ // Read data from the modules. - ReadFIFO(); + if (!had_error) ReadFIFO(); // Instruct all modules to end the current run. pif->EndRun(); @@ -1596,7 +1728,7 @@ void Poll::RunControl(){ //We sleep to allow the module to finish. sleep(1); //We read the FIFO out. - ReadFIFO(); + if (!had_error) ReadFIFO(); } //Print the module status. @@ -1778,15 +1910,15 @@ bool Poll::ReadFIFO() { std::cout << " to buffer position " << dataWords << std::endl; } - //After reading the FIFO and printing a sttus message we can update the number of words to include the partial event. + //After reading the FIFO and printing a status message we can update the number of words to include the partial event. nWords[mod] += partialEvents[mod].size(); //Clear the partial event partialEvents[mod].clear(); - //We now ned to parse the event to determine if there is a hanging event. Also, allows a check for corrupted data. - size_t parseWords = dataWords; + //We now need to parse the event to determine if there is a hanging event. Also, allows a check for corrupted data. + size_t parseWords = dataWords; //We declare the eventSize outside the loop in case there is a partial event. - word_t eventSize = 0; + word_t eventSize = 0, prevEventSize = 0; word_t slotExpected = pif->GetSlotNumber(mod); while (parseWords < dataWords + nWords[mod]) { //Check first word to see if data makes sense. @@ -1797,19 +1929,20 @@ bool Poll::ReadFIFO() { bool virtualChannel = ((fifoData[parseWords] & 0x20000000) != 0); if( slotRead != slotExpected ){ - std::cout << Display::ErrorStr() << " Slot read (" << slotRead - << ") not the same as" << " slot expected (" - << slotExpected << ")" << std::endl; - break; + std::cout << Display::ErrorStr() << " Slot read " << slotRead + << " not the same as slot expected " + << slotExpected << std::endl; + had_error = true; } - else if (chanRead < 0 || chanRead > 15) { + if (chanRead < 0 || chanRead > 15) { std::cout << Display::ErrorStr() << " Channel read (" << chanRead << ") not valid!\n"; - break; + had_error = true; } - else if(eventSize == 0){ - std::cout << Display::ErrorStr() << "ZERO EVENT SIZE in mod " << mod << "!\n"; - break; + if(eventSize == 0){ + std::cout << Display::ErrorStr() << " ZERO EVENT SIZE in mod " << mod << "!\n"; + had_error = true; } + if (had_error) break; // Update the statsHandler with the event (for monitor.bash) if(!virtualChannel && statsHandler){ @@ -1818,6 +1951,7 @@ bool Poll::ReadFIFO() { //Iterate to the next event and continue parsing parseWords += eventSize; + prevEventSize = eventSize; } //We now check the outcome of the data parsing. @@ -1833,26 +1967,62 @@ bool Poll::ReadFIFO() { //Update the number of words to indicate removal or partial event. nWords[mod] -= partialSize; - } //If parseWords is small then the parse failed for some reason else if (parseWords < dataWords + nWords[mod]) { - std::cout << Display::ErrorStr() << " Parsing indicated corrupted data at " << parseWords - dataWords << " words into FIFO.\n"; + //Determine the fifo position from successfully parsed words plus the last event length. + std::cout << Display::ErrorStr() << " Parsing indicated corrupted data for module " << mod << ".\n"; + std::cout << "| Parsing failed at " << parseWords - dataWords << "/" << nWords[mod] + << " (" << parseWords << "/" << dataWords + nWords[mod] << ") words into FIFO." << std::endl; + + //Print the previous event + std::cout << "|\n| Event prior to parsing error (" << prevEventSize << " words):"; + std::cout << std::hex << std::setfill('1'); + for(size_t i=0;i< prevEventSize;i++) { + if (i%5 == 0) std::cout << std::endl << "| "; + std::cout << "0x" << std::right << std::setw(8) << std::setfill('0'); + std::cout << fifoData[parseWords - prevEventSize + i] << " "; + } + std::cout << std::dec << std::setfill(' ') << std::endl; + + //Print the parsed event + std::cout << "|\n| Event at parsing error (" << eventSize << " words):"; + size_t outputSize = eventSize; + if (eventSize > 50) { + outputSize = 50; + std::cout << "\n| (Truncated at " << outputSize << " words.)"; + } + std::cout << std::hex << std::setfill('0'); + for(size_t i=0;i< outputSize;i++) { + if (i%5 == 0) std::cout << std::endl << "| "; + std::cout << "0x" << std::right << std::setw(8) << std::setfill('0'); + std::cout << fifoData[parseWords + i] << " "; + } + std::cout << std::dec << std::setfill(' ') << std::endl; - std::cout << std::hex; - //Print the previous words - std::cout << "Words prior to parsing error:\n"; - for(int i=0;i< 100;i++) { - if (i%10 == 0) std::cout << std::endl << "\t"; - std::cout << fifoData[dataWords + parseWords - 100 + i] << " "; + //Print the following event + //Determine size of following event. + word_t nextEventSize = 0; + if (parseWords + eventSize < dataWords + nWords[mod]) { + nextEventSize = ((fifoData[parseWords + eventSize] & 0x7FFE2000) >> 17); } - //Print the following words - std::cout << "Words following parsing error:\n"; - for(int i=0;i< 100;i++) { - if (i%10 == 0) std::cout << std::endl << "\t"; - std::cout << fifoData[dataWords + parseWords + i] << " "; + std::cout << "|\n| Event after parsing error (" << nextEventSize << " words):"; + + //Determine output size for event. + outputSize = nextEventSize; + if (eventSize > 50) outputSize = 50; + if (parseWords + eventSize + outputSize >= dataWords + nWords[mod]) + outputSize = dataWords + nWords[mod] - (parseWords + eventSize); + if (outputSize != nextEventSize) + std::cout << "\n| (Truncated at " << outputSize << " words.)"; + + std::cout << std::hex << std::setfill('0'); + for(size_t i=0;i< outputSize;i++) { + if (i%5 == 0) std::cout << std::endl << "| "; + std::cout << "0x" << std::right << std::setw(8); + std::cout << fifoData[parseWords + eventSize + i] << " "; } - std::cout << std::dec << std::endl; + std::cout << std::dec << std::setfill(' ') << std::endl << "|\n"; do_stop_acq = true; had_error = true; @@ -1916,3 +2086,4 @@ std::string yesno(bool value_){ if(value_){ return "Yes"; } return "No"; } + diff --git a/Poll/source/poll2_stats.cpp b/Acquisition/Poll/source/poll2_stats.cpp similarity index 100% rename from Poll/source/poll2_stats.cpp rename to Acquisition/Poll/source/poll2_stats.cpp diff --git a/PxiDump/CMakeLists.txt b/Acquisition/PxiDump/CMakeLists.txt similarity index 100% rename from PxiDump/CMakeLists.txt rename to Acquisition/PxiDump/CMakeLists.txt diff --git a/PxiDump/include/set2root.hpp b/Acquisition/PxiDump/include/set2root.hpp similarity index 100% rename from PxiDump/include/set2root.hpp rename to Acquisition/PxiDump/include/set2root.hpp diff --git a/PxiDump/source/CMakeLists.txt b/Acquisition/PxiDump/source/CMakeLists.txt similarity index 100% rename from PxiDump/source/CMakeLists.txt rename to Acquisition/PxiDump/source/CMakeLists.txt diff --git a/PxiDump/source/set2root.cpp b/Acquisition/PxiDump/source/set2root.cpp similarity index 97% rename from PxiDump/source/set2root.cpp rename to Acquisition/PxiDump/source/set2root.cpp index ce5246a16..27e99d676 100644 --- a/PxiDump/source/set2root.cpp +++ b/Acquisition/PxiDump/source/set2root.cpp @@ -17,6 +17,7 @@ #include "TFile.h" #endif +#include "HelperFunctions.hpp" #include "set2root.hpp" #define FILTER_CLOCK 8E-3 // Filter clock (in us) @@ -68,7 +69,12 @@ std::string parameter::print(){ stream << name << "["; if(count < 10) stream << "0"; - stream << count << "]" << "\t" << (*iter) << "\n"; + stream << count << "]" << "\t"; + if(name != "PreampTau") + stream << (*iter); + else + stream << IeeeStandards::IeeeFloatingToDecimal((*iter)); + stream << "\n"; count++; } } diff --git a/Setup/CMakeLists.txt b/Acquisition/Setup/CMakeLists.txt similarity index 63% rename from Setup/CMakeLists.txt rename to Acquisition/Setup/CMakeLists.txt index a2d332d4e..7f7855c04 100644 --- a/Setup/CMakeLists.txt +++ b/Acquisition/Setup/CMakeLists.txt @@ -1,3 +1,3 @@ +include_directories(include) add_subdirectory(source) - add_subdirectory(Traces) diff --git a/Setup/Traces/CMakeLists.txt b/Acquisition/Setup/Traces/CMakeLists.txt similarity index 100% rename from Setup/Traces/CMakeLists.txt rename to Acquisition/Setup/Traces/CMakeLists.txt diff --git a/Setup/Traces/share/traces/plotTraces_ch b/Acquisition/Setup/Traces/share/traces/plotTraces_ch similarity index 100% rename from Setup/Traces/share/traces/plotTraces_ch rename to Acquisition/Setup/Traces/share/traces/plotTraces_ch diff --git a/Setup/Traces/share/traces/plotTraces_mod b/Acquisition/Setup/Traces/share/traces/plotTraces_mod similarity index 100% rename from Setup/Traces/share/traces/plotTraces_mod rename to Acquisition/Setup/Traces/share/traces/plotTraces_mod diff --git a/Setup/Traces/share/traces/tra b/Acquisition/Setup/Traces/share/traces/tra similarity index 100% rename from Setup/Traces/share/traces/tra rename to Acquisition/Setup/Traces/share/traces/tra diff --git a/Setup/Traces/source/viewBaseline.sh b/Acquisition/Setup/Traces/source/viewBaseline.sh similarity index 100% rename from Setup/Traces/source/viewBaseline.sh rename to Acquisition/Setup/Traces/source/viewBaseline.sh diff --git a/Setup/include/utilities.h b/Acquisition/Setup/include/utilities.h similarity index 100% rename from Setup/include/utilities.h rename to Acquisition/Setup/include/utilities.h diff --git a/Setup/source/CMakeLists.txt b/Acquisition/Setup/source/CMakeLists.txt similarity index 100% rename from Setup/source/CMakeLists.txt rename to Acquisition/Setup/source/CMakeLists.txt diff --git a/Setup/source/adjust_offsets.cpp b/Acquisition/Setup/source/adjust_offsets.cpp similarity index 100% rename from Setup/source/adjust_offsets.cpp rename to Acquisition/Setup/source/adjust_offsets.cpp diff --git a/Setup/source/boot.cpp b/Acquisition/Setup/source/boot.cpp similarity index 100% rename from Setup/source/boot.cpp rename to Acquisition/Setup/source/boot.cpp diff --git a/Setup/source/copy_params.cpp b/Acquisition/Setup/source/copy_params.cpp similarity index 100% rename from Setup/source/copy_params.cpp rename to Acquisition/Setup/source/copy_params.cpp diff --git a/Setup/source/csr_test.cpp b/Acquisition/Setup/source/csr_test.cpp similarity index 100% rename from Setup/source/csr_test.cpp rename to Acquisition/Setup/source/csr_test.cpp diff --git a/Setup/source/find_tau.cpp b/Acquisition/Setup/source/find_tau.cpp similarity index 100% rename from Setup/source/find_tau.cpp rename to Acquisition/Setup/source/find_tau.cpp diff --git a/Setup/source/get_traces.cpp b/Acquisition/Setup/source/get_traces.cpp similarity index 100% rename from Setup/source/get_traces.cpp rename to Acquisition/Setup/source/get_traces.cpp diff --git a/Setup/source/input_whole_crate.txt b/Acquisition/Setup/source/input_whole_crate.txt similarity index 100% rename from Setup/source/input_whole_crate.txt rename to Acquisition/Setup/source/input_whole_crate.txt diff --git a/Setup/source/mca_paw.cpp b/Acquisition/Setup/source/mca_paw.cpp similarity index 100% rename from Setup/source/mca_paw.cpp rename to Acquisition/Setup/source/mca_paw.cpp diff --git a/Setup/source/paramScan.cpp b/Acquisition/Setup/source/paramScan.cpp similarity index 100% rename from Setup/source/paramScan.cpp rename to Acquisition/Setup/source/paramScan.cpp diff --git a/Setup/source/pmread.cpp b/Acquisition/Setup/source/pmread.cpp similarity index 100% rename from Setup/source/pmread.cpp rename to Acquisition/Setup/source/pmread.cpp diff --git a/Setup/source/pmwrite.cpp b/Acquisition/Setup/source/pmwrite.cpp similarity index 100% rename from Setup/source/pmwrite.cpp rename to Acquisition/Setup/source/pmwrite.cpp diff --git a/Setup/source/pread.cpp b/Acquisition/Setup/source/pread.cpp similarity index 100% rename from Setup/source/pread.cpp rename to Acquisition/Setup/source/pread.cpp diff --git a/Setup/source/pwrite.cpp b/Acquisition/Setup/source/pwrite.cpp similarity index 100% rename from Setup/source/pwrite.cpp rename to Acquisition/Setup/source/pwrite.cpp diff --git a/Setup/source/rate.cpp b/Acquisition/Setup/source/rate.cpp similarity index 100% rename from Setup/source/rate.cpp rename to Acquisition/Setup/source/rate.cpp diff --git a/Setup/source/set_hybrid.cpp b/Acquisition/Setup/source/set_hybrid.cpp similarity index 100% rename from Setup/source/set_hybrid.cpp rename to Acquisition/Setup/source/set_hybrid.cpp diff --git a/Setup/source/set_pileups_only.cpp b/Acquisition/Setup/source/set_pileups_only.cpp similarity index 100% rename from Setup/source/set_pileups_only.cpp rename to Acquisition/Setup/source/set_pileups_only.cpp diff --git a/Setup/source/set_pileups_reject.cpp b/Acquisition/Setup/source/set_pileups_reject.cpp similarity index 100% rename from Setup/source/set_pileups_reject.cpp rename to Acquisition/Setup/source/set_pileups_reject.cpp diff --git a/Setup/source/set_standard.cpp b/Acquisition/Setup/source/set_standard.cpp similarity index 100% rename from Setup/source/set_standard.cpp rename to Acquisition/Setup/source/set_standard.cpp diff --git a/Setup/source/toggle.cpp b/Acquisition/Setup/source/toggle.cpp similarity index 100% rename from Setup/source/toggle.cpp rename to Acquisition/Setup/source/toggle.cpp diff --git a/Setup/source/toggle_catcher.cpp b/Acquisition/Setup/source/toggle_catcher.cpp similarity index 100% rename from Setup/source/toggle_catcher.cpp rename to Acquisition/Setup/source/toggle_catcher.cpp diff --git a/Setup/source/toggle_gain.cpp b/Acquisition/Setup/source/toggle_gain.cpp similarity index 100% rename from Setup/source/toggle_gain.cpp rename to Acquisition/Setup/source/toggle_gain.cpp diff --git a/Setup/source/toggle_good.cpp b/Acquisition/Setup/source/toggle_good.cpp similarity index 100% rename from Setup/source/toggle_good.cpp rename to Acquisition/Setup/source/toggle_good.cpp diff --git a/Setup/source/toggle_pileup.cpp b/Acquisition/Setup/source/toggle_pileup.cpp similarity index 100% rename from Setup/source/toggle_pileup.cpp rename to Acquisition/Setup/source/toggle_pileup.cpp diff --git a/Setup/source/toggle_polarity.cpp b/Acquisition/Setup/source/toggle_polarity.cpp similarity index 100% rename from Setup/source/toggle_polarity.cpp rename to Acquisition/Setup/source/toggle_polarity.cpp diff --git a/Setup/source/toggle_trace.cpp b/Acquisition/Setup/source/toggle_trace.cpp similarity index 100% rename from Setup/source/toggle_trace.cpp rename to Acquisition/Setup/source/toggle_trace.cpp diff --git a/Setup/source/trace.cpp b/Acquisition/Setup/source/trace.cpp similarity index 100% rename from Setup/source/trace.cpp rename to Acquisition/Setup/source/trace.cpp diff --git a/Setup/source/trace_paw.cpp b/Acquisition/Setup/source/trace_paw.cpp similarity index 100% rename from Setup/source/trace_paw.cpp rename to Acquisition/Setup/source/trace_paw.cpp diff --git a/Analysis/CMakeLists.txt b/Analysis/CMakeLists.txt new file mode 100644 index 000000000..ad99e74d9 --- /dev/null +++ b/Analysis/CMakeLists.txt @@ -0,0 +1,35 @@ +option(USE_HRIBF "Use HRIBF library for scan base." OFF) +option(USE_GSL "Use GSL for Pulse Fitting" OFF) + +#Check if GSL is installed +if(USE_GSL) + find_package(GSL REQUIRED) + add_definitions("-D usegsl") +endif(USE_GSL) + +#Everything below is dependent on these two sets of libaries so we include the +#headers. +include_directories(Resources/include) +include_directories(ScanLibraries/include) + +if(USE_HRIBF) + #Find HRIBF Libraries + find_package(HRIBF REQUIRED) + add_definitions("-D USE_HRIBF") + + #If we are using HRIBF interface we need to include the ScanorInterface header + # for the following code. + include_directories(Scanor/include) + add_subdirectory(Scanor) +endif(USE_HRIBF) + +#We will always build these two since they include static lib for the rest +add_subdirectory(ScanLibraries) +add_subdirectory(Resources) + +#Build utilities. +add_subdirectory(Utilities) + +if(BUILD_UTKSCAN) + add_subdirectory(Utkscan) +endif(BUILD_UTKSCAN) \ No newline at end of file diff --git a/Analysis/Resources/CMakeLists.txt b/Analysis/Resources/CMakeLists.txt new file mode 100644 index 000000000..d2031f51f --- /dev/null +++ b/Analysis/Resources/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(source) + +if(BUILD_TESTS OR BUILD_UNITTESTS) + add_subdirectory(tests) +endif(BUILD_TESTS OR BUILD_UNITTESTS) \ No newline at end of file diff --git a/Analysis/Resources/include/GslFitter.hpp b/Analysis/Resources/include/GslFitter.hpp new file mode 100644 index 000000000..48a43c4f8 --- /dev/null +++ b/Analysis/Resources/include/GslFitter.hpp @@ -0,0 +1,67 @@ +/// @file GslFitter.hpp +/// @brief Implementation of the GSL fitting routine for GSL v2+ +/// @author S. V. Paulauskas +/// @date August 8, 2016 +#ifndef PIXIESUITE_GSLFITTER_HPP +#define PIXIESUITE_GSLFITTER_HPP + +#include + +#include + +#include +#include +#include + +#include "TimingDriver.hpp" + +class GslFitter : public TimingDriver { +public: + ///Default Constructor + GslFitter() : TimingDriver() { isFastSiPm_ = false; } + + ///Default Destructor + ~GslFitter() {} + + /// @return the amplitude from the GSL fit + double GetAmplitude(void) { return amp_; } + + /// @return the chi^2 from the GSL fit + double GetChiSq(void) { return chi_ * chi_; } + + /// @return the chi^2dof from the GSL fit + double GetChiSqPerDof(void) { return GetChiSq() / dof_; } + + ///The ever important phase calculation + /// @param[in] data The baseline subtracted data for the fitting + /// @param[in] pars The parameters for the fit + /// @param[in] max : Information about the maximum position and value + /// @param[in] baseline : The average and standard deviation of the baseline + double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline); + + ///Sets the isFastSiPm_ flag + ///@param[in] a : The value that we are going to set + void SetIsFastSiPm(const bool &a) { isFastSiPm_ = a; } + + /// @brief Structure necessary for the GSL fitting routines + struct FitData { + size_t n;//!< size of the fitting parameters + double *y;//!< ydata to fit + double *sigma;//!< weights used for the fit + double beta; //!< the beta parameter for the fit + double gamma; //!< the gamma parameter for the fit + double qdc;//!< the QDC for the fit + }; +private: + bool isFastSiPm_; + + double amp_; + double chi_; + double dof_; +}; + + +#endif //PIXIESUITE_GSLFITTER_HPP diff --git a/Analysis/Resources/include/PolynomialCfd.hpp b/Analysis/Resources/include/PolynomialCfd.hpp new file mode 100644 index 000000000..661b799ab --- /dev/null +++ b/Analysis/Resources/include/PolynomialCfd.hpp @@ -0,0 +1,23 @@ +/// @file PolynomialCfd.hpp +/// @brief A method that uses the +/// @author C. R. Thornsberry and S. V. Paulauskas +/// @date December 6, 2016 +#ifndef PIXIESUITE_POLYNOMIALCFD_HPP +#define PIXIESUITE_POLYNOMIALCFD_HPP + +#include "TimingDriver.hpp" + +class PolynomialCfd : public TimingDriver { +public: + PolynomialCfd() {}; + + ~PolynomialCfd() {}; + + /// Perform CFD analysis on the waveform using the pol2 algorithm. + double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline); +}; + +#endif //PIXIESUITE_POLYNOMIALCFD_HPP diff --git a/Analysis/Resources/include/RootFitter.hpp b/Analysis/Resources/include/RootFitter.hpp new file mode 100644 index 000000000..6dd2d767a --- /dev/null +++ b/Analysis/Resources/include/RootFitter.hpp @@ -0,0 +1,24 @@ +/// @file RootFitter.hpp +/// @brief Class to handle fitting traces using ROOT +/// @author S. V. Paulauskas +/// @date December 18, 2016 +#ifndef PIXIESUITE_ROOTFITTER_HPP +#define PIXIESUITE_ROOTFITTER_HPP + +#include "TimingDriver.hpp" + +class RootFitter : public TimingDriver { +public: + RootFitter() {}; + + ~RootFitter() {}; + + /// Perform CFD analysis on the waveform using the pol2 algorithm. + double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &maxInfo, + std::pair baseline); +}; + + +#endif //PIXIESUITE_ROOTFITTER_HPP diff --git a/Analysis/Resources/include/TimingDriver.hpp b/Analysis/Resources/include/TimingDriver.hpp new file mode 100644 index 000000000..2d5396776 --- /dev/null +++ b/Analysis/Resources/include/TimingDriver.hpp @@ -0,0 +1,69 @@ +/// \file TimingDriver.hpp +/// \brief An abstract class that will provide the base for fitting +/// \author S. V. Paulauskas +/// \date August 8, 2016 + +#ifndef PIXIESUITE_TIMINGDRIVER_HPP +#define PIXIESUITE_TIMINGDRIVER_HPP + +#include +#include + +/// An abstract class that will be used to handle timing. +class TimingDriver { +public: + ///Default Constructor + TimingDriver() {}; + + ///Default destructor + virtual ~TimingDriver() {}; + + ///This virtual function provides results other than the phase to the + /// user. Please look at the documentation of the children to see exactly + /// what is returned with this vector. + ///@TODO Not sure this is the best way to do things, but it cut the + /// number of methods necessary by a factor of 5 or 6. + ///@return A vector containing useful information calculated in addition + /// to the phase. + virtual std::vector GetResults(void) { return results_; } + + ///This is a virtual function that actually deifnes how we are going to + /// determine the phase. We have several different implementations of how + /// we can do this but we'll overload this method in the children to + /// provide specific implementation. + ///@param[in] data : The vector of data that we are going to work with. + /// This usually means a trace or waveform. + ///@param[in] pars : The pair of parameters that we want to use for the + /// algorithm. For Fitters this will be beta and gamma, for CFDs this + /// will be the fraction and the delay. + /// @param[in] maxInfo : The information about the maximum in a pair + /// of NOTE : The value of the maximum for CFD based + /// calculations should be the extrapolated maximum. + /// @param[in] a : The baseline information in a pair + ///@return The phase calculated by the algorithm. + virtual double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { + return 0.0; + } + + ///@Brief Overload of the Calculate phase method to allow for data + /// vectors of type double. We do this since we cannot template a virtual + /// method. + virtual double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { + return 0.0; + } + + /// Sets the QDC that we want to set + /// \param[in] a the qdc of the waveform for the fit + void SetQdc(const double &a) { qdc_ = a; } +protected: + std::vector results_; //!< Vector containing results + double qdc_;//!< qdc of the waveform being fitted +}; + +#endif //PIXIESUITE_TIMINGDRIVER_HPP diff --git a/Analysis/Resources/include/TraditionalCfd.hpp b/Analysis/Resources/include/TraditionalCfd.hpp new file mode 100644 index 000000000..d266c3241 --- /dev/null +++ b/Analysis/Resources/include/TraditionalCfd.hpp @@ -0,0 +1,24 @@ +///@file TraditionalCfd.hpp +///@brief Traditional CFD implemented digitally +///@author S. V. Paulauskas +///@date July 22, 2011 + +#ifndef PIXIESUITE_TRADITIONALCFD_HPP +#define PIXIESUITE_TRADITIONALCFD_HPP + +#include "TimingDriver.hpp" + +class TraditionalCfd : public TimingDriver { +public: + /// Default constructor + TraditionalCfd() {}; + + /// Default destructor + ~TraditionalCfd() {}; + + double CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline); +}; +#endif //PIXIESUITE_TRADITIONALCFD_HPP diff --git a/Analysis/Resources/include/VandleTimingFunction.hpp b/Analysis/Resources/include/VandleTimingFunction.hpp new file mode 100644 index 000000000..7d7f68984 --- /dev/null +++ b/Analysis/Resources/include/VandleTimingFunction.hpp @@ -0,0 +1,17 @@ +/// @file VandleTimingFunction.hpp +/// @brief A class to handle the processing of traces +/// @author S. V. Paulauskas +/// @date October 3, 2014 +#ifndef __VANDLETIMINGFUNCITON__HPP__ +#define __VANDLETIMINGFUNCITON__HPP__ + +class VandleTimingFunction { +public: + VandleTimingFunction() {}; + + virtual ~VandleTimingFunction() {}; + + double operator()(double *x, double *p); +}; + +#endif diff --git a/Analysis/Resources/include/XiaCfd.hpp b/Analysis/Resources/include/XiaCfd.hpp new file mode 100644 index 000000000..7473a143f --- /dev/null +++ b/Analysis/Resources/include/XiaCfd.hpp @@ -0,0 +1,21 @@ +// +// Created by vincent on 12/6/16. +// + +#ifndef PIXIESUITE_XIACFD_HPP +#define PIXIESUITE_XIACFD_HPP + + +class XiaCfd : public TimingDriver { +public: + XiaCfd() {}; + + ~XiaCfd() {}; + + /// Perform CFD analysis on the waveform using the XIA algorithm. + double CalculatePhase(const double &F_ = 0.5, const size_t &D_ = 1, + const size_t &L_ = 1); +}; + + +#endif //PIXIESUITE_XIACFD_HPP diff --git a/Analysis/Resources/source/CMakeLists.txt b/Analysis/Resources/source/CMakeLists.txt new file mode 100644 index 000000000..7e55755ab --- /dev/null +++ b/Analysis/Resources/source/CMakeLists.txt @@ -0,0 +1,33 @@ +#Set the utility sources that we will make a lib out of +set(ResourceSources PolynomialCfd.cpp TraditionalCfd.cpp) + +if (USE_GSL) + if (${GSL_VERSION} GREATER 1.9) + list(APPEND ResourceSources Gsl2Fitter.cpp) + else (${GSL_VERSION} LESS 2.0) + list(APPEND ResourceSources Gsl1Fitter.cpp) + endif (${GSL_VERSION} GREATER 1.9) +endif (USE_GSL) + +if (USE_ROOT) + list(APPEND ResourceSources RootFitter.cpp VandleTimingFunction.cpp) +endif (USE_ROOT) + +#Add the sources to the library +add_library(ResourceObjects OBJECT ${ResourceSources}) + +if (BUILD_SHARED_LIBS) + message(STATUS "Building Utility Shared Objects") + add_library(UtilityLibrary SHARED $) + target_link_libraries(UtilityLibrary PaassCoreStatic) + if (USE_ROOT) + target_link_libraries(UtilityLibrary ${ROOT_LIBRARIES}) + endif (USE_ROOT) + install(TARGETS UtilityLibrary DESTINATION lib) +endif (BUILD_SHARED_LIBS) + +#Create Utility static library and add ncurses if we have it +add_library(ResourceStatic STATIC $) +if (USE_ROOT) + target_link_libraries(ResourceStatic ${ROOT_LIBRARIES}) +endif (USE_ROOT) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp b/Analysis/Resources/source/Gsl1Fitter.cpp similarity index 75% rename from Scan/utkscan/analyzers/source/Gsl1Fitter.cpp rename to Analysis/Resources/source/Gsl1Fitter.cpp index 30798b964..039aa5ba9 100644 --- a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp +++ b/Analysis/Resources/source/Gsl1Fitter.cpp @@ -2,14 +2,6 @@ /// \brief Implementation of the GSL fitting routine for GSL v2+ /// \author S. V. Paulauskas /// \date August 8, 2016 -#include - -#include - -#include -#include -#include - #include "GslFitter.hpp" /** Defines the GSL fitting function for standard PMTs @@ -55,29 +47,30 @@ int SiPmtFunctionDerivative(const gsl_vector *x, void *FitData, gsl_vector *f, using namespace std; -void GslFitter::PerformFit(const std::vector &data, - const std::pair &pars, - const double &weight/* = 1.*/, - const double &area/* = 1.*/) { +double GslFitter::CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { gsl_multifit_function_fdf f; int status; const size_t sizeFit = data.size(); size_t numParams; double xInit[3]; - double y[sizeFit], sigma[sizeFit]; + double *y = new double[sizeFit]; + double *sigma = new double[sizeFit]; for(unsigned int i = 0; i < sizeFit; i++) { y[i] = data.at(i); - sigma[i] = weight; + sigma[i] = baseline.second; } - struct FitDriver::FitData fitData = - {sizeFit, y, sigma, pars.first, pars.second, area}; + struct GslFitter::FitData fitData = + {sizeFit, y, sigma, pars.first, pars.second, qdc_}; f.n = sizeFit; f.params = &fitData; - if(!isFastSipm_) { + if(!isFastSiPm_) { numParams = 2; xInit[0] = 0.0; xInit[1] = 2.5; @@ -100,11 +93,14 @@ void GslFitter::PerformFit(const std::vector &data, f.p = numParams; gsl_multifit_fdfsolver_set (s, &f, &x.vector); - for(unsigned int iter = 0; iter < 1e8; iter++) { + static const double maxIter = 1e8; + static const double tolerance = 1e-4; + + for(unsigned int iter = 0; iter < maxIter; iter++) { status = gsl_multifit_fdfsolver_iterate(s); if(status) break; - status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4); + status = gsl_multifit_test_delta (s->dx, s->x, tolerance, tolerance); if(status != GSL_CONTINUE) break; } @@ -112,25 +108,24 @@ void GslFitter::PerformFit(const std::vector &data, gsl_multifit_covar (s->J, 0.0, covar); chi_ = gsl_blas_dnrm2(s->f); - if(!isFastSipm_) { - phase_ = gsl_vector_get(s->x,0); + if(!isFastSiPm_) amp_ = gsl_vector_get(s->x,1); - } else { - phase_ = gsl_vector_get(s->x,0); + else amp_ = 0.0; - } gsl_multifit_fdfsolver_free (s); gsl_matrix_free (covar); + + return gsl_vector_get(s->x,0); } int PmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *y = ((struct FitDriver::FitData *)FitData)->y; - double *sigma = ((struct FitDriver::FitData *)FitData)->sigma; - double beta = ((struct FitDriver::FitData *)FitData)->beta; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct GslFitter::FitData *)FitData)->n; + double *y = ((struct GslFitter::FitData *)FitData)->y; + double *sigma = ((struct GslFitter::FitData *)FitData)->sigma; + double beta = ((struct GslFitter::FitData *)FitData)->beta; + double gamma = ((struct GslFitter::FitData *)FitData)->gamma; + double qdc = ((struct GslFitter::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double alpha = gsl_vector_get (x, 1); @@ -151,11 +146,11 @@ int PmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { } int CalcPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *sigma = ((struct FitDriver::FitData *) FitData)->sigma; - double beta = ((struct FitDriver::FitData *)FitData)->beta; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct GslFitter::FitData *)FitData)->n; + double *sigma = ((struct GslFitter::FitData *) FitData)->sigma; + double beta = ((struct GslFitter::FitData *)FitData)->beta; + double gamma = ((struct GslFitter::FitData *)FitData)->gamma; + double qdc = ((struct GslFitter::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double alpha = gsl_vector_get (x, 1); @@ -189,11 +184,11 @@ int PmtFunctionDerivative (const gsl_vector * x, void *FitData, gsl_vector * f, } int SiPmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *y = ((struct FitDriver::FitData *)FitData)->y; - double *sigma = ((struct FitDriver::FitData *)FitData)->sigma; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct GslFitter::FitData *)FitData)->n; + double *y = ((struct GslFitter::FitData *)FitData)->y; + double *sigma = ((struct GslFitter::FitData *)FitData)->sigma; + double gamma = ((struct GslFitter::FitData *)FitData)->gamma; + double qdc = ((struct GslFitter::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); @@ -207,10 +202,10 @@ int SiPmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { } int CalcSiPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *sigma = ((struct FitDriver::FitData *)FitData)->sigma; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct GslFitter::FitData *)FitData)->n; + double *sigma = ((struct GslFitter::FitData *)FitData)->sigma; + double gamma = ((struct GslFitter::FitData *)FitData)->gamma; + double qdc = ((struct GslFitter::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double dphi; diff --git a/Analysis/Resources/source/Gsl2Fitter.cpp b/Analysis/Resources/source/Gsl2Fitter.cpp new file mode 100644 index 000000000..bf40176c5 --- /dev/null +++ b/Analysis/Resources/source/Gsl2Fitter.cpp @@ -0,0 +1,208 @@ +/// \file Gsl2Fitter.cpp +/// \brief Implementation of the GSL fitting routine for GSL v2+ +/// \author S. V. Paulauskas +/// \date August 8, 2016 +#include "GslFitter.hpp" + +/** Defines the GSL fitting function for standard PMTs + * \param [in] x : the vector of gsl starting parameters + * \param [in] FitData : The data to use for the fit + * \param [in] f : pointer to the function + * \return an integer that GSL does something magical with */ +int PmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f); + +/** Defines the GSL fitting function for standard PMTs + * \param [in] x : the vector of gsl starting parameters + * \param [in] FitData : The data to use for the fit + * \param [in] J : pointer to the Jacobian of the function + * \return an integer that GSL does something magical with */ +int CalcPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J); + +/** Defines the GSL fitting function for the fast output of SiPMTs + * \param [in] x : the vector of gsl starting parameters + * \param [in] FitData : The data to use for the fit + * \param [in] f : pointer to the function + * \return an integer that GSL does something magical with */ +int SiPmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f); + +/** Defines the GSL fitting function for the fast output SiPMTs + * \param [in] x : the vector of gsl starting parameters + * \param [in] FitData : The data to use for the fit + * \param [in] J : pointer to the Jacobian of the function + * \return an integer that GSL does something magical with */ +int CalcSiPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J); + +using namespace std; + +double GslFitter::CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { + gsl_multifit_function_fdf f; + int info; + const size_t n = data.size(); + size_t p; + double xInit[3]; + + if (!isFastSiPm_) { + p = 2; + xInit[0] = 0.0; + xInit[1] = 2.5; + + f.f = &PmtFunction; + f.df = &CalcPmtJacobian; + } else { + p = 1; + xInit[0] = (double) data.size() * 0.5; + + f.f = &SiPmtFunction; + f.df = &CalcSiPmtJacobian; + } + + dof_ = n - p; + + const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; + gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, p); + gsl_matrix *jac = gsl_matrix_alloc(n, p); + gsl_matrix *covar = gsl_matrix_alloc(p, p); + double *y = new double[n]; + double *weights = new double[n]; + struct FitData fitData = {n, y, weights, pars.first, + pars.second, qdc_}; + gsl_vector_view x = gsl_vector_view_array(xInit, p); + gsl_vector_view w = gsl_vector_view_array(weights, n); + + static const unsigned int maxIter = 100; + static const double xtol = 1e-4; + static const double gtol = 1e-4; + static const double ftol = 0.0; + + f.n = n; + f.p = p; + f.params = &fitData; + + for (unsigned int i = 0; i < n; i++) { + weights[i] = baseline.second; + y[i] = data[i]; + } + + gsl_multifit_fdfsolver_wset(s, &f, &x.vector, &w.vector); + gsl_multifit_fdfsolver_driver(s, maxIter, xtol, gtol, ftol, &info); + gsl_multifit_fdfsolver_jac(s, jac); + gsl_multifit_covar(jac, 0.0, covar); + + gsl_vector *res_f = gsl_multifit_fdfsolver_residual(s); + chi_ = gsl_blas_dnrm2(res_f); + + double phase = 0.0; + if (!isFastSiPm_) { + phase = gsl_vector_get(s->x, 0); + amp_ = gsl_vector_get(s->x, 1); + } else { + phase = gsl_vector_get(s->x, 0); + amp_ = 0.0; + } + + gsl_multifit_fdfsolver_free(s); + gsl_matrix_free(covar); + gsl_matrix_free(jac); + delete y; + delete weights; + + return phase; +} + +int PmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f) { + size_t n = ((struct GslFitter::FitData *) FitData)->n; + double *y = ((struct GslFitter::FitData *) FitData)->y; + double beta = ((struct GslFitter::FitData *) FitData)->beta; + double gamma = ((struct GslFitter::FitData *) FitData)->gamma; + double qdc = ((struct GslFitter::FitData *) FitData)->qdc; + + double phi = gsl_vector_get(x, 0); + double alpha = gsl_vector_get(x, 1); + + for (size_t i = 0; i < n; i++) { + double t = i; + double diff = t - phi; + double Yi = 0; + + if (t < phi) + Yi = 0; + else + Yi = qdc * alpha * exp(-beta * diff) * + (1 - exp(-pow(gamma * diff, 4.))); + + gsl_vector_set(f, i, Yi - y[i]); + } + return (GSL_SUCCESS); +} + +int CalcPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J) { + size_t n = ((struct GslFitter::FitData *) FitData)->n; + double beta = ((struct GslFitter::FitData *) FitData)->beta; + double gamma = ((struct GslFitter::FitData *) FitData)->gamma; + double qdc = ((struct GslFitter::FitData *) FitData)->qdc; + + double phi = gsl_vector_get(x, 0); + double alpha = gsl_vector_get(x, 1); + + double dphi, dalpha; + + for (size_t i = 0; i < n; i++) { + double t = i; + double diff = t - phi; + double gaussSq = exp(-pow(gamma * diff, 4.)); + if (t < phi) { + dphi = 0; + dalpha = 0; + } else { + dphi = alpha * beta * qdc * exp(-beta * diff) * (1 - gaussSq) - + 4 * alpha * qdc * pow(diff, 3.) * exp(-beta * diff) * + pow(gamma, 4.) * gaussSq; + dalpha = qdc * exp(-beta * diff) * (1 - gaussSq); + } + gsl_matrix_set(J, i, 0, dphi); + gsl_matrix_set(J, i, 1, dalpha); + } + return (GSL_SUCCESS); +} + +int SiPmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f) { + size_t n = ((struct GslFitter::FitData *) FitData)->n; + double *y = ((struct GslFitter::FitData *) FitData)->y; + double gamma = ((struct GslFitter::FitData *) FitData)->gamma; + double qdc = ((struct GslFitter::FitData *) FitData)->qdc; + + double phi = gsl_vector_get(x, 0); + + for (size_t i = 0; i < n; i++) { + double t = i; + double diff = t - phi; + double Yi = (qdc / (gamma * sqrt(2 * M_PI))) * + exp(-diff * diff / (2 * gamma * gamma)); + gsl_vector_set(f, i, Yi - y[i]); + } + return (GSL_SUCCESS); +} + +int CalcSiPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J) { + size_t n = ((struct GslFitter::FitData *) FitData)->n; + double gamma = ((struct GslFitter::FitData *) FitData)->gamma; + double qdc = ((struct GslFitter::FitData *) FitData)->qdc; + + double phi = gsl_vector_get(x, 0); + double dphi; + + for (size_t i = 0; i < n; i++) { + double t = i; + double diff = t - phi; + + dphi = (qdc * diff / (pow(gamma, 3) * sqrt(2 * M_PI))) * + exp(-diff * diff / (2 * gamma * gamma)); + + gsl_matrix_set(J, i, 0, dphi); + } + return (GSL_SUCCESS); +} + diff --git a/Analysis/Resources/source/PolynomialCfd.cpp b/Analysis/Resources/source/PolynomialCfd.cpp new file mode 100644 index 000000000..957652095 --- /dev/null +++ b/Analysis/Resources/source/PolynomialCfd.cpp @@ -0,0 +1,50 @@ +/// @file PolynomialCfd.cpp +/// @brief Timing method that calculates the timing using a Polynomial based +/// CFD. +/// @author C. R. Thornsberry and S. V. Paulauskas +/// @date December 6, 2016 +#include + +#include "HelperFunctions.hpp" +#include "PolynomialCfd.hpp" + +using namespace std; + +/// Perform CFD analysis on the waveform. +double PolynomialCfd::CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { + if (data.size() == 0) + throw range_error("PolynomialCfd::CalculatePhase - The data vector " + "was empty!"); + if (data.size() < max.first) + throw range_error("PolynomialCfd::CalculatePhase - The maximum " + "position is larger than the size of the " + "data vector."); + + double threshold = pars.first * max.second; + double phase = -9999; + float multiplier = 1.; + + vector result; + for (unsigned int cfdIndex = max.first; cfdIndex > 0; cfdIndex--) { + if (data[cfdIndex - 1] < threshold && data[cfdIndex] >= threshold) { + // Fit the rise of the trace to a 2nd order polynomial. + result = Polynomial::CalculatePoly2(data, cfdIndex - 1).second; + + // Calculate the phase of the trace. + if(result[2] > 1) + multiplier = -1.; + + phase = (-result[1] + multiplier * + sqrt(result[1] * result[1] - + 4 * result[2] * + (result[0] - threshold))) / + (2 * result[2]); + + break; + } + } + return phase; +} \ No newline at end of file diff --git a/Analysis/Resources/source/RootFitter.cpp b/Analysis/Resources/source/RootFitter.cpp new file mode 100644 index 000000000..da13d2882 --- /dev/null +++ b/Analysis/Resources/source/RootFitter.cpp @@ -0,0 +1,53 @@ +/// @file RootFitter.cpp +/// @brief Class to handle fitting traces using ROOT +/// @author S. V. Paulauskas +/// @date December 18, 2016 +#include + +#include +#include +#include + +#include "RootFitter.hpp" +#include "VandleTimingFunction.hpp" + +using namespace std; + +double RootFitter::CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &maxInfo, + std::pair baseline) { + if (data.size() == 0) + throw range_error("RootFitter::CalculatePhase - The data was sized " + "zero."); + + vector xvals, yvals; + for (unsigned int i = 0; i < data.size(); i++) { + xvals.push_back(double(i)); + yvals.push_back(double(data[i])); + } + + TGraphErrors *graph = + new TGraphErrors(data.size(), &(xvals[0]), &(yvals[0])); + for (unsigned int i = 0; i < xvals.size(); i++) + graph->SetPointError(i, 0.0, baseline.second); + + VandleTimingFunction vandleTimingFunction; + TF1 func("func", vandleTimingFunction, 0., 1.e6, 5); + func.SetParameters(0, qdc_ * 0.5, 0.5, 0.5, baseline.first); + + ///@TODO We need to get this working, it's suffering from some strange + /// issues with ROOT and linked libraries. + //TFitResultPtr fitResults = graph->Fit(&func, "MENRS", "", 0, data.size()); + //int fitStatus = fitResults; + +// cout << "Fit Status : " << fitStatus << endl; +// cout << "QDC : " << qdc_ << endl; +// cout << "Phase : " << func->GetParameter(0) << endl; +// cout << "Amplitude : " << func->GetParameter(1) << endl; +// cout << "Beta : " << func->GetParameter(2) << endl; +// cout << "Gamma : " << func->GetParameter(3) << endl; +// cout << "Baseline : " << func->GetParameter(4) << endl; + //delete func; + return 0.0; +} \ No newline at end of file diff --git a/Analysis/Resources/source/TraditionalCfd.cpp b/Analysis/Resources/source/TraditionalCfd.cpp new file mode 100644 index 000000000..f36388141 --- /dev/null +++ b/Analysis/Resources/source/TraditionalCfd.cpp @@ -0,0 +1,58 @@ +///@file TraditionalCfd.cpp +///@brief Traditional CFD implemented digitally, similar behavior to a NIM +/// Module. +///@author S. V. Paulauskas +///@date July 22, 2011 + +#include "HelperFunctions.hpp" +#include "TraditionalCfd.hpp" + +using namespace std; + +double TraditionalCfd::CalculatePhase(const std::vector &data, + const std::pair &pars, + const std::pair &max, + const std::pair baseline) { + if (data.size() == 0) + throw range_error("PolynomialCfd::CalculatePhase - The data vector " + "was empty!"); + if (data.size() < max.first) + throw range_error("PolynomialCfd::CalculatePhase - The maximum " + "position is larger than the size of the " + "data vector."); + + unsigned int delay = (unsigned int) pars.second; + double fraction = pars.first; + vector cfd; + + //We are going to calculate the CFD here. + for (unsigned int i = 0; i < data.size() - delay; i++) + cfd.push_back(fraction * (data[i] - data[i + delay])); + + //Now we find the maximum and minimum position to locate the zero crossing. + vector::iterator cfdMin = min_element(cfd.begin(), cfd.end()); + vector::iterator cfdMax = max_element(cfd.begin(), cfd.end()); + + vector fitY(cfdMin, cfdMax); + vector fitX; + + for (int i = int(cfdMin - cfd.begin()); i < int(cfdMax - cfd.begin()); i++) + fitX.push_back((double) i); + + double num = fitY.size(); + + double sumXSq = 0, sumX = 0, sumXY = 0, sumY = 0; + + for (unsigned int i = 0; i < num; i++) { + sumXSq += fitX.at(i) * fitX.at(i); + sumX += fitX.at(i); + sumY += fitY.at(i); + sumXY += fitX.at(i) * fitY.at(i); + } + + double deltaPrime = num * sumXSq - sumX * sumX; + + //Rerun the negative of the intercept / slope + return -((1 / deltaPrime) * (sumXSq * sumY - sumX * sumXY)) / + ((1 / deltaPrime) * (num * sumXY - sumX * sumY)); +} \ No newline at end of file diff --git a/Analysis/Resources/source/VandleTimingFunction.cpp b/Analysis/Resources/source/VandleTimingFunction.cpp new file mode 100644 index 000000000..7f3bd51e0 --- /dev/null +++ b/Analysis/Resources/source/VandleTimingFunction.cpp @@ -0,0 +1,23 @@ +/// @file VandleTimingFunction.hpp +/// @brief A class to handle the processing of traces +/// @author S. V. Paulauskas +/// @date October 3, 2014 +#include + +#include "VandleTimingFunction.hpp" + +double VandleTimingFunction::operator()(double *x, double *p) { + double phase = p[0]; + double amplitude = p[1]; + double beta = p[2]; + double gamma = p[3]; + double baseline = p[4]; + + double diff = x[0] - phase; + + if (x[0] < phase) + return baseline; + + return amplitude * std::exp(-beta * diff) * + (1 - std::exp(-std::pow(gamma * diff, 4.))) + baseline; +} diff --git a/Analysis/Resources/source/XiaCfd.cpp b/Analysis/Resources/source/XiaCfd.cpp new file mode 100644 index 000000000..a68e26d46 --- /dev/null +++ b/Analysis/Resources/source/XiaCfd.cpp @@ -0,0 +1,49 @@ +///@file TraditionalCfd.cpp +///@brief Same CFD algorithm implemented by Xia LLC but offline. +///@author S. V. Paulauskas +///@date July 22, 2011 + +#include "XiaCfd.hpp" + +/// Perform CFD analysis on the waveform +double XiaCfd::CalculatePhase(const double &F_/*=0.5*/, + const size_t &D_/*=1*/, + const size_t &L_/*=1*/) { + if (size == 0 || baseline < 0) { return -9999; } + if (!cfdvals) + cfdvals = new double[size]; + + double cfdMinimum = 9999; + size_t cfdMinIndex = 0; + + phase = -9999; + + // Compute the cfd waveform. + for (size_t cfdIndex = 0; cfdIndex < size; ++cfdIndex) { + cfdvals[cfdIndex] = 0.0; + if (cfdIndex >= L_ + D_ - 1) { + for (size_t i = 0; i < L_; i++) + cfdvals[cfdIndex] += + F_ * (event->adcTrace[cfdIndex - i] - baseline) - + (event->adcTrace[cfdIndex - i - D_] - baseline); + } + if (cfdvals[cfdIndex] < cfdMinimum) { + cfdMinimum = cfdvals[cfdIndex]; + cfdMinIndex = cfdIndex; + } + } + + // Find the zero-crossing. + if (cfdMinIndex > 0) { + // Find the zero-crossing. + for (size_t cfdIndex = cfdMinIndex - 1; cfdIndex >= 0; cfdIndex--) { + if (cfdvals[cfdIndex] >= 0.0 && cfdvals[cfdIndex + 1] < 0.0) { + phase = cfdIndex - cfdvals[cfdIndex] / + (cfdvals[cfdIndex + 1] - cfdvals[cfdIndex]); + break; + } + } + } + + return phase; +} \ No newline at end of file diff --git a/Analysis/Resources/tests/CMakeLists.txt b/Analysis/Resources/tests/CMakeLists.txt new file mode 100644 index 000000000..da282c994 --- /dev/null +++ b/Analysis/Resources/tests/CMakeLists.txt @@ -0,0 +1,31 @@ +if (USE_GSL) + if (${GSL_VERSION} GREATER 1.9) + set(GSL_FITTER_SOURCES ../source/Gsl2Fitter.cpp) + else (${GSL_VERSION} LESS 2.0) + set(GSL_FITTER_SOURCES ../source/Gsl1Fitter.cpp) + endif (${GSL_VERSION} GREATER 1.9) + + #Build the test to see if the GSL fitting algorithm is behaving. + set(GSL_FITTER_SOURCES ${GSL_FITTER_SOURCES} unittest-GslFitter.cpp) + add_executable(unittest-GslFitter ${GSL_FITTER_SOURCES}) + target_link_libraries(unittest-GslFitter ${GSL_LIBRARIES} UnitTest++) + install(TARGETS unittest-GslFitter DESTINATION bin/unittests) +endif (USE_GSL) + +add_executable(unittest-PolynomialCfd unittest-PolynomialCfd.cpp + ../source/PolynomialCfd.cpp) +target_link_libraries(unittest-PolynomialCfd UnitTest++) +install(TARGETS unittest-PolynomialCfd DESTINATION bin/unittests) + +add_executable(unittest-TraditionalCfd unittest-TraditionalCfd.cpp + ../source/TraditionalCfd.cpp) +target_link_libraries(unittest-TraditionalCfd UnitTest++) +install(TARGETS unittest-TraditionalCfd DESTINATION bin/unittests) + +if (USE_ROOT) + add_executable(unittest-RootFitter unittest-RootFitter.cpp + ../source/RootFitter.cpp ../source/VandleTimingFunction.cpp) + target_link_libraries(unittest-RootFitter + ${ROOT_LIBRARIES}) + install(TARGETS unittest-RootFitter DESTINATION bin/unittests) +endif (USE_ROOT) diff --git a/Analysis/Resources/tests/unittest-GslFitter.cpp b/Analysis/Resources/tests/unittest-GslFitter.cpp new file mode 100644 index 000000000..0474503c2 --- /dev/null +++ b/Analysis/Resources/tests/unittest-GslFitter.cpp @@ -0,0 +1,31 @@ +///\file unittest-GslFitter.cpp +///\brief A small code to test the functionality of the FitDriver +///\author S. V. Paulauskas +///\date August 8, 2016 +#include +#include + +#include + +#include "GslFitter.hpp" +#include "UnitTestSampleData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_fit_variables; + +TEST_FIXTURE(GslFitter, TestGslFitter) { + //We need to set the QDC before the fit + SetQdc(21329.85714285); + + //Actually perform the fitting + double phase = CalculatePhase(waveform, fitting_parameters, + max_pair, baseline_pair); + + CHECK_CLOSE(0.8565802, GetAmplitude(), 0.1); + CHECK_CLOSE(-0.0826487, phase, 1.); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/Resources/tests/unittest-PolynomialCfd.cpp b/Analysis/Resources/tests/unittest-PolynomialCfd.cpp new file mode 100644 index 000000000..11efe5f5e --- /dev/null +++ b/Analysis/Resources/tests/unittest-PolynomialCfd.cpp @@ -0,0 +1,42 @@ +///@file unittest-PolynomialCfd.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include +#include +#include +#include + +#include + +#include "PolynomialCfd.hpp" +#include "UnitTestSampleData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_cfd_variables; + + +TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { + //Checking that we throw a range_error when the data vector is zero + CHECK_THROW(CalculatePhase(empty_vector_double, cfd_test_pars, max_pair, + baseline_pair), range_error); + + //Check that we throw a range error when the max position is larger than + // the data we provided. + CHECK_THROW(CalculatePhase(trace_sans_baseline, cfd_test_pars, + make_pair(trace_sans_baseline.size()+3, 100), + baseline_pair), range_error); + + //The expected value in this case is the value that I obtained after + // debugging the algorithm using other means. This check is here simply + // to tell us whether or not the algorithm has changed drastically from + // the "acceptable" value. + CHECK_CLOSE(73.9898, + CalculatePhase(trace_sans_baseline, cfd_test_pars, + extrapolated_maximum_pair,baseline_pair), + 5); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/Resources/tests/unittest-RootFitter.cpp b/Analysis/Resources/tests/unittest-RootFitter.cpp new file mode 100644 index 000000000..a0763fb5b --- /dev/null +++ b/Analysis/Resources/tests/unittest-RootFitter.cpp @@ -0,0 +1,31 @@ +/// @file unittest-RootFitter.cpp +/// @brief Unit tests for the RootFitter class +/// @author S. V. Paulauskas +/// @date December 18, 2016 +//#include + +#include "RootFitter.hpp" +#include "UnitTestSampleData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_fit_variables; + + +//TEST_FIXTURE(RootFitter, TestRootFitter) { +// CHECK_THROW(CalculatePhase(empty_data, expected_trace_pars, +// expected_max_info, expected_baseline_pair), +// range_error); +// +// CalculatePhase(waveform, expected_trace_pars, expected_max_info, +// expected_baseline_pair); +// +// //CHECK( != 0.0); +//} + +int main(int argv, char *argc[]) { + RootFitter fitter; + fitter.CalculatePhase(waveform, fitting_parameters, max_pair, + baseline_pair); + //return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/Resources/tests/unittest-TraditionalCfd.cpp b/Analysis/Resources/tests/unittest-TraditionalCfd.cpp new file mode 100644 index 000000000..3616edd0b --- /dev/null +++ b/Analysis/Resources/tests/unittest-TraditionalCfd.cpp @@ -0,0 +1,39 @@ +///@file unittest-TraditionalCfd.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include +#include + +#include + +#include "TraditionalCfd.hpp" +#include "UnitTestSampleData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_cfd_variables; + +TEST_FIXTURE(TraditionalCfd, TestTraditionalCfd) { + //Checking that we throw a range_error when the data vector is zero + CHECK_THROW(CalculatePhase(empty_vector_double, cfd_test_pars, max_pair, + baseline_pair), range_error); + + //Check that we throw a range error when the max position is larger than + // the data we provided. + CHECK_THROW(CalculatePhase(trace_sans_baseline, cfd_test_pars, + make_pair(trace_sans_baseline.size()+3, 100), + baseline_pair), range_error); + + //The expected value in this case is the value that I obtained after + // debugging the algorithm using other means. This check is here simply + // to tell us whether or not the algorithm has changed drastically from + // the "acceptable" value. + CHECK_CLOSE(75.1408, + CalculatePhase(trace_sans_baseline, cfd_test_pars, + extrapolated_maximum_pair,baseline_pair), + 5); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/scanor/CMakeLists.txt b/Analysis/ScanLibraries/CMakeLists.txt similarity index 73% rename from Scan/scanor/CMakeLists.txt rename to Analysis/ScanLibraries/CMakeLists.txt index 33d664731..a82afe023 100644 --- a/Scan/scanor/CMakeLists.txt +++ b/Analysis/ScanLibraries/CMakeLists.txt @@ -3,4 +3,8 @@ if(BUILD_SHARED_LIBS) install(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(BUILD_SHARED_LIBS) +if(BUILD_UNITTESTS) + add_subdirectory(tests) +endif(BUILD_UNITTESTS) + add_subdirectory(source) diff --git a/Scan/ScanLib/include/ChannelData.hpp b/Analysis/ScanLibraries/include/ChannelData.hpp similarity index 100% rename from Scan/ScanLib/include/ChannelData.hpp rename to Analysis/ScanLibraries/include/ChannelData.hpp diff --git a/Analysis/ScanLibraries/include/ChannelEvent.hpp b/Analysis/ScanLibraries/include/ChannelEvent.hpp new file mode 100644 index 000000000..74c24b65b --- /dev/null +++ b/Analysis/ScanLibraries/include/ChannelEvent.hpp @@ -0,0 +1,65 @@ +///@file ChannelEvent.hpp +///@author S. V. Paulauskas (from C. R. Thornsberry's work) +///@date December 2, 2016 + +#ifndef PIXIESUITE_CHANNELEVENT_HPP +#define PIXIESUITE_CHANNELEVENT_HPP + +#include + +#include "XiaData.hpp" + +class ChannelEvent{ +public: + bool valid_chan; /// True if the high resolution energy and time are valid. + + double hires_energy; /// High resolution energy from the integration of pulse fits. + double hires_time; /// High resolution time taken from pulse fits (in ns). + + float *xvals; /// x values used for fitting. + float *yvals; /// y values used for fitting (baseline corrected trace). + float *cfdvals; /// y values for the cfd analyzed waveform. + size_t size; /// Size of xvals and yvals arrays and of trace vector. + + float phase; /// Phase (leading edge) of trace (in ADC clock ticks (4E-9 Hz for 250 MHz digitizer)). + float baseline; /// The baseline of the trace. + float stddev; /// Standard deviation of the baseline. + float maximum; /// The baseline corrected maximum value of the trace. + float qdc; /// The calculated (baseline corrected) qdc. + float cfdCrossing; /// The zero-crossing point of the cfd waveform. + size_t max_index; /// The index of the maximum trace bin (in ADC clock ticks). + + bool baseline_corrected; /// True if the trace has been baseline corrected. + bool ignore; /// Ignore this event. + + XiaData *event; /// The low level pixie event. + + /// Default constructor. + ChannelEvent(); + + /// Constructor from a XiaData. ChannelEvent will take ownership of the XiaData. + ChannelEvent(XiaData *event_); + + /// Destructor. + ~ChannelEvent(); + + ///@TODO These methods need to be removed. At a later date. + /// Correct the trace baseline, baseline standard deviation, and find the pulse maximum. + float CorrectBaseline(); + + /// Find the leading edge of the pulse at a given percentage of pulse maximum. + float FindLeadingEdge(const float &thresh_=0.05); + + /// Integrate the baseline corrected trace in the range [start_, stop_] and return the result. + float IntegratePulse(const size_t &start_=0, const size_t &stop_=0); + + /// Integrate the baseline corrected trace in the range [start_, stop_] and return the result. + float FindQDC(const size_t &start_=0, const size_t &stop_=0); + + /// Perform CFD analysis on the waveform. + float AnalyzeCFD(const float &F_=0.5, const size_t &D_=1, const size_t &L_=1); + + /// Clear all variables and clear the trace vector and arrays. + void Clear(); +}; +#endif //PIXIESUITE_CHANNELEVENT_HPP diff --git a/Analysis/ScanLibraries/include/RootScanner.hpp b/Analysis/ScanLibraries/include/RootScanner.hpp new file mode 100644 index 000000000..63b5cf544 --- /dev/null +++ b/Analysis/ScanLibraries/include/RootScanner.hpp @@ -0,0 +1,35 @@ +#ifndef ROOTSCANNER_H +#define ROOTSCANNER_H + +#include + +#include "TCanvas.h" +#include "TApplication.h" + +#include "ScanInterface.hpp" + +class RootScanner : public ScanInterface { + public: + RootScanner(); + ~RootScanner(); + TCanvas *GetCanvas() {return canvas_;}; + void IdleTask(); + void UpdateZoom(TVirtualPad* pad = gPad); + void ResetZoom(TVirtualPad *pad = gPad); + + private: + TCanvas *canvas_; + + static const int numAxes_ = 3; + struct AxisInfo { + double rangeUserMin[numAxes_]; + double rangeUserMax[numAxes_]; + double limitMin[numAxes_]; + double limitMax[numAxes_]; + bool reset; + }; + std::map< TVirtualPad*, AxisInfo > zoomInfo_; + +}; + +#endif //ROOTSCANNER_H diff --git a/Scan/ScanLib/include/ScanInterface.hpp b/Analysis/ScanLibraries/include/ScanInterface.hpp similarity index 100% rename from Scan/ScanLib/include/ScanInterface.hpp rename to Analysis/ScanLibraries/include/ScanInterface.hpp diff --git a/Scan/ScanLib/include/Unpacker.hpp b/Analysis/ScanLibraries/include/Unpacker.hpp similarity index 93% rename from Scan/ScanLib/include/Unpacker.hpp rename to Analysis/ScanLibraries/include/Unpacker.hpp index 0714809e0..82103ea6d 100644 --- a/Scan/ScanLib/include/Unpacker.hpp +++ b/Analysis/ScanLibraries/include/Unpacker.hpp @@ -17,6 +17,8 @@ #include #include +#include "XiaListModeDataMask.hpp" + #ifndef MAX_PIXIE_MOD #define MAX_PIXIE_MOD 12 #endif @@ -68,6 +70,12 @@ class Unpacker{ /// Set the width of events in pixie16 clock ticks. double SetEventWidth(double width_){ return (eventWidth = width_); } + + void InitializeDataMask(const std::string &firmware, + const unsigned int& frequency) { + mask_.SetFrequency(frequency); + mask_.SetFirmware(firmware); + } /// Set the address of the scan interface used for file operations. ScanInterface *SetInterface(ScanInterface *interface_){ return (interface = interface_); } @@ -98,6 +106,9 @@ class Unpacker{ void Run(){ running = true; } protected: + XiaListModeDataMask mask_; //Object providing the masks necessary to + // decode the data. + double eventWidth; /// The width of the raw event in pixie clock ticks (8 ns). bool debug_mode; /// True if debug mode is set. @@ -129,9 +140,12 @@ class Unpacker{ * \param[out] bufLen The number of words in the buffer. * \return The number of XiaDatas read from the buffer. */ - int ReadBuffer(unsigned int *buf, unsigned long &bufLen); + int ReadBuffer(unsigned int *buf); private: + ///Vector containing the list of channels decoded from + std::vector decodedList_; + unsigned int TOTALREAD; /// Maximum number of data words to read. unsigned int maxWords; /// Maximum number of data words for revision D. unsigned int numRawEvt; /// The total count of raw events read from file. diff --git a/Analysis/ScanLibraries/include/XiaData.hpp b/Analysis/ScanLibraries/include/XiaData.hpp new file mode 100644 index 000000000..cb6383786 --- /dev/null +++ b/Analysis/ScanLibraries/include/XiaData.hpp @@ -0,0 +1,262 @@ +///@file XiaData.cpp +///@brief A class that holds information from the XIA LLC. Pixie-16 List +/// Mode Data +///@authors C. R. Thornsberry and S. V. Paulauskas +#ifndef XIADATA_HPP +#define XIADATA_HPP + +#include + +/*! \brief A pixie16 channel event + * + * All data is grouped together into channels. For each pixie16 channel that + * fires the energy, time (both trigger time and event time), and trace (if + * applicable) are obtained. Additional information includes the channels + * identifier, calibrated energies, trace analysis information. + * Note that this currently stores raw values internally through pixie word types + * but returns data values through native C types. This is potentially non-portable. + */ +class XiaData { +public: + /// Default constructor. + XiaData() { Clear(); } + + ///Default Destructor. + ~XiaData() {}; + + ///@brief Equality operator that compares checks if we have the same + /// channel (i.e. the ID and Time are identical) + ///@param[in] rhs : The right hand side of the comparison + ///@return True if the two XiaData classes are equal. + bool operator==(const XiaData &rhs) const { + return GetId() == rhs.GetId() && GetTime() == rhs.GetTime(); + } + + ///@brief The conjugate of the equality operator + ///@param[in] rhs : The right hand side for the comparison + ///@return True if the two are not equal. + bool operator!=(const XiaData &rhs) const { + return !operator==(rhs); + } + + ///@brief The less than operator that compares if the time of the current + /// class is less than the time of the comparison class. + ///@param[in] rhs : The right hand side for the comparison + ///@return True if this instance arrived earlier than the right hand side. + bool operator<(const XiaData &rhs) const { + return GetTime() < rhs.GetTime(); + } + + ///@brief The conjugate of the less than operator + ///@param[in] rhs : The right hand side for the comparison + ///@return True if the right hand side arrived ealier than the left hand + /// side. + bool operator>(const XiaData &rhs) const { + return !operator<(rhs); + } + + ///@brief A method that will compare the times of two XiaData classes + /// this method can be used in conjunction with sorting methods + ///@param[in] lhs : A pointer to the left hand side of the comparison + ///@param[in] rhs : A pointer to the right hand side of the comparison + ///@return True if the time of arrival for right hand side is later than + /// that of the left hand side. + static bool CompareTime(const XiaData *lhs, const XiaData *rhs) { + return lhs->GetTime() < rhs->GetTime(); + } + + ///@brief A method that will compare the unique ID of two XiaData classes + ///@param[in] lhs : A pointer to the left hand side of the comparison + ///@param[in] rhs : A pointer to the right hand side of the comparison + ///@return Return true if left hand side has a lower ID than the right + /// hand side. + static bool CompareId(const XiaData *lhs, const XiaData *rhs) { + return (lhs->GetId() < rhs->GetId()); + } + + ///@return The status of the CFD Forced Trigger Bit + bool GetCfdForcedTriggerBit() const { return cfdForceTrig_; } + + ///@return The status of the CFD Trigger bit. + bool GetCfdTriggerSourceBit() const { return cfdTrigSource_; } + + ///@return True if we had a pileup detected on the module + bool IsPileup() const { return isPileup_; } + + ///@return True if the trace was flagged as a pileup + bool IsSaturated() const { return isSaturated_; } + + ///@return True if this channel was generated on the module + bool IsVirtualChannel() const { return isVirtualChannel_; } + + ///@return The baseline as it was calculated on the module + double GetBaseline() const { return baseline_; } + + ///@return The energy that was calculated on the module + double GetEnergy() const { return energy_; } + + ///@brief Method that will return the time for the channel. The actual + /// time is a 48-bit number. We multiply 2^32 by the eventTimeHigh_ so + /// that we account for the missing upper 16 bits of the number. The + /// cfdTime_ contains all of the fractional time information, and so we + /// divide by 2^16 here. + ///@TODO Verify that this method works properly for all of the different + /// module types and firmwares. It doesn't and this value simply needs to + /// be set explicitly by the Decoder + ///@return The time for the channel. + double GetTime() const { return time_; } + + ///@return The CFD fractional time in clockticks + unsigned int GetCfdFractionalTime() const { return cfdTime_; } + + ///@return The Channel number that recorded these data + unsigned int GetChannelNumber() const { return chanNum_; } + + ///@return The crate number that had the module + unsigned int GetCrateNumber() const { return crateNum_; } + + ///@return The upper 16 bits of the event time + unsigned int GetEventTimeHigh() const { return eventTimeHigh_; } + + ///@return The lower 32 bits of the event time + unsigned int GetEventTimeLow() const { return eventTimeLow_; } + + ///@return The upper 16 bits of the external time stamp provided to the + /// module via the front panel + unsigned int GetExternalTimeHigh() const { return externalTimeHigh_; } + + ///@return The lower 32 bits of the external time stamp provided to the + /// module via the front panel + unsigned int GetExternalTimeLow() const { return externalTimeLow_; } + + ///@return The unique ID of the channel. + ///We can have a maximum of 208 channels in a crate, the first module + /// (#0) is always in the second slot of the crate, and we always have 16 + /// channels + unsigned int GetId() const { + return crateNum_ * 208 + GetModuleNumber() * 16 + chanNum_; + } + + ///@return the module number + unsigned int GetModuleNumber() const { + return slotNum_ - 2; + } + + ///@return The slot that the module was in + unsigned int GetSlotNumber() const { return slotNum_; } + + ///@return The energy sums recorded on the module + std::vector GetEnergySums() const { return eSums_; } + + ///@return the QDC recorded on the module + std::vector GetQdc() const { return qdc_; } + + ///@return The trace that was sampled on the module + std::vector GetTrace() const { return trace_; } + + ///@brief Sets the baseline recorded on the module if the energy sums + /// were recorded in the data stream + ///@param[in] a : The value to set + void SetBaseline(const double &a) { baseline_ = a; } + + ///@brief This value is set to true if the CFD was forced to trigger + ///@param[in] a : The value to set + void SetCfdForcedTriggerBit(const bool &a) { cfdForceTrig_ = a; } + + ///@brief Sets the CFD fractional time calculated on-board + ///@param[in] a : The value to set + void SetCfdFractionalTime(const unsigned int &a) { cfdTime_ = a; } + + ///@brief Sets the CFD trigger source + ///@param[in] a : The value to set + void SetCfdTriggerSourceBit(const bool &a) { cfdTrigSource_ = a; } + + ///@brief Sets the channel number + ///@param[in] a : The value to set + void SetChannelNumber(const unsigned int &a) { chanNum_ = a; } + + ///@brief Sets the crate number + ///@param[in] a : The value to set + void SetCrateNumber(const unsigned int &a) { crateNum_ = a; } + + ///@brief Sets the energy calculated on-board + ///@param[in] a : The value to set + void SetEnergy(const double &a) { energy_ = a; } + + ///@brief Sets the energy sums calculated on-board + ///@param[in] a : The value to set + void SetEnergySums(const std::vector &a) { eSums_ = a; } + + ///@brief Sets the upper 16 bits of the event time + ///@param[in] a : The value to set + void SetEventTimeHigh(const unsigned int &a) { eventTimeHigh_ = a; } + + ///@brief Sets the lower 32 bits of the event time + ///@param[in] a : The value to set + void SetEventTimeLow(const unsigned int &a) { eventTimeLow_ = a; } + + ///@brief Sets the upper 16 bits of the external event time + ///@param[in] a : The value to set + void SetExternalTimeHigh(const unsigned int &a) { externalTimeHigh_ = a; } + + ///@brief Sets the lower 32 bits of the external event time + ///@param[in] a : The value to set + void SetExternalTimeLow(const unsigned int &a) { externalTimeLow_ = a; } + + ///@brief Sets if we had a pileup found on-board + ///@param[in] a : The value to set + void SetPileup(const bool &a) { isPileup_ = a; } + + ///@brief Sets the QDCs that were calculated on-board + ///@param[in] a : The value to set + void SetQdc(const std::vector &a) { qdc_ = a; } + + ///@brief Sets the saturation flag + ///@param[in] a : True if we found a saturation on board + void SetSaturation(const bool &a) { isSaturated_ = a; } + + ///@brief Sets the slot number + ///@param[in] a : The value to set + void SetSlotNumber(const unsigned int &a) { slotNum_ = a; } + + ///@brief Sets the calculated arrival time of the signal + ///@param[in] a : The value to set + void SetTime(const double &a) { time_ = a; } + + ///@brief Sets the trace recorded on board + ///@param[in] a : The value to set + void SetTrace(const std::vector &a) { trace_ = a; } + + ///@brief Sets the flag for channels generated on-board + ///@param[in] a : True if we this channel was generated on-board + void SetVirtualChannel(const bool &a) { isVirtualChannel_ = a; } + + ///@brief Clear all variables and set them to some default values. + void Clear(); + +private: + bool cfdForceTrig_; /// CFD was forced to trigger. + bool cfdTrigSource_; /// The ADC that the CFD/FPGA synched with. + bool isPileup_; /// Pile-up flag from Pixie. + bool isSaturated_; /// Saturation flag from Pixie. + bool isVirtualChannel_; /// Flagged if generated virtually in Pixie DSP. + + double energy_; /// Raw pixie energy. + double baseline_;///Baseline that was recorded with the energy sums + double time_; + + unsigned int cfdTime_; /// CFD trigger time + unsigned int chanNum_; /// Channel number. + unsigned int crateNum_; ///The Crate number for the channel + unsigned int eventTimeHigh_; /// Upper 16 bits of pixie16 event time. + unsigned int eventTimeLow_; /// Lower 32 bits of pixie16 event time. + unsigned int externalTimeHigh_; ///Upper 16 bits of external time stamp + unsigned int externalTimeLow_; ///Lower 32 bits of external time stamp + unsigned int slotNum_; ///Slot number + + std::vector eSums_;///Energy sums recorded by the module + std::vector qdc_; ///QDCs recorded by the module + std::vector trace_; /// ADC trace capture. +}; + +#endif \ No newline at end of file diff --git a/Analysis/ScanLibraries/include/XiaListModeDataDecoder.hpp b/Analysis/ScanLibraries/include/XiaListModeDataDecoder.hpp new file mode 100644 index 000000000..29fb8b8d9 --- /dev/null +++ b/Analysis/ScanLibraries/include/XiaListModeDataDecoder.hpp @@ -0,0 +1,77 @@ +/// @file XiaListModeDataDecoder.hpp +/// @brief Class that handles decoding list mode data from XIA Pixie-16 +/// modules. +/// @author S. V. Paulauskas +/// @date December 23, 2016 +#ifndef PIXIESUITE_XIALISTMODEDATADECODER_HPP +#define PIXIESUITE_XIALISTMODEDATADECODER_HPP + +#include + +#include "XiaData.hpp" +#include "XiaListModeDataMask.hpp" + +///Class to decode Xia List mode Data +class XiaListModeDataDecoder { +public: + ///Default constructor + XiaListModeDataDecoder() {}; + + ///Default destructor + ~XiaListModeDataDecoder() {}; + + ///Main decoding method + ///@param[in] buf : Pointer to the beginning of the data buffer. + ///@param[in] mask : The mask set that we need to decode the data + ///@return A vector containing all of the decoded XiaData events. + std::vector DecodeBuffer(unsigned int *buf, + const XiaListModeDataMask &mask); + + ///Method to calculate the arrival time of the signal in samples + ///@param[in] mask : The data mask containing the necessary information + /// to calculate the time. + ///@param[in] data : The data that we will use to calculate the time + ///@return The calculated time in clock samples + static double CalculateTimeInSamples(const XiaListModeDataMask &mask, + const XiaData &data); + + ///Method to calculate the arrival time of the signal in nanoseconds + ///@param[in] mask : The data mask containing the necessary information + /// to calculate the time. + ///@param[in] data : The data that we will use to calculate the time + ///@return The calculated time in nanoseconds + static double CalculateTimeInNs(const XiaListModeDataMask &mask, + const XiaData &data); +private: + ///Method to decode word zero from the header. + ///@param[in] word : The word that we need to decode + ///@param[in] data : The XiaData object that we are going to fill. + ///@return The pair of the header length and event length for use in + /// subsequent processing. + std::pair DecodeWordZero( + const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask); + + ///Method to decode word two from the header. + ///@param[in] word : The word that we need to decode + ///@param[in] data : The XiaData object that we are going to fill. + ///@param[in] mask : The data mask to decode the data + void DecodeWordTwo(const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask); + + ///Method to decode word three from the header. + ///@param[in] word : The word that we need to decode + ///@param[in] data : The XiaData object that we are going to fill. + ///@param[in] mask : The data mask to decode the data + ///@return The trace length + unsigned int DecodeWordThree(const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask); + + ///Method to decode word three from the header. + ///@param[in] word : The word that we need to decode + ///@param[in] data : The XiaData object that we are going to fill. + void DecodeTrace(unsigned int *buf, XiaData &data, + const unsigned int &traceLength); +}; + +#endif //PIXIESUITE_XIALISTMODEDATADECODER_HPP diff --git a/Analysis/ScanLibraries/include/XiaListModeDataEncoder.hpp b/Analysis/ScanLibraries/include/XiaListModeDataEncoder.hpp new file mode 100644 index 000000000..d1d82359a --- /dev/null +++ b/Analysis/ScanLibraries/include/XiaListModeDataEncoder.hpp @@ -0,0 +1,78 @@ +/// @file XiaListModeDataEncoder.hpp +/// @brief Class that handles encoding Pixie-16 list mode data from a XiaData +/// class +/// @author S. V. Paulauskas +/// @date December 30, 2016 +#ifndef PIXIESUITE_XIALISTMODEDATAENCODER_HPP +#define PIXIESUITE_XIALISTMODEDATAENCODER_HPP + +#include + +#include "XiaData.hpp" +//For the FIRMWARE enum +#include "XiaListModeDataMask.hpp" + +class XiaListModeDataEncoder { +public: + ///Default constructor + XiaListModeDataEncoder() {}; + + ///Default destructor + ~XiaListModeDataEncoder() {}; + + ///Method that will create a Pixie List Mode Data Event from an XiaData + /// object. + ///@param[in] data : The data that we want to encode + ///@param[in] firmware : The firmware version to encode into + ///@param[in] frequency : The sampling frequency in MHz or MS/s + ///@return A vector containing the encoded data. + std::vector EncodeXiaData(const XiaData &data, + const DataProcessing::FIRMWARE &firmware, + const unsigned int &frequency); + +private: + ///Encodes the first word of the data buffer. + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + unsigned int EncodeWordZero(const XiaData &data, + const XiaListModeDataMask &mask); + + ///Encodes the second word of the data buffer. + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + unsigned int EncodeWordOne(const XiaData &data, + const XiaListModeDataMask &mask); + + ///Encodes the third word of the data buffer. + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + unsigned int EncodeWordTwo(const XiaData &data, + const XiaListModeDataMask &mask); + + ///Encodes the fourth word of the data buffer. + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + unsigned int EncodeWordThree(const XiaData &data, + const XiaListModeDataMask &mask); + + ///Encodes the Trace + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + std::vector EncodeTrace(const std::vector &trc, + const std::pair &mask); + + ///Encodes the Esums + ///@param[in] data : The data to encode + ///@param[in] mask : The object with the data masks + ///@return The encoded data word. + std::vector EncodeEsums(const XiaData &data, + const XiaListModeDataMask &mask); +}; + +#endif //PIXIESUITE_XIALISTMODEDATAENCODER_HPP diff --git a/Analysis/ScanLibraries/include/XiaListModeDataMask.hpp b/Analysis/ScanLibraries/include/XiaListModeDataMask.hpp new file mode 100644 index 000000000..99240464c --- /dev/null +++ b/Analysis/ScanLibraries/include/XiaListModeDataMask.hpp @@ -0,0 +1,170 @@ +/// @file XiaListModeDataMask.hpp +/// @brief Class that provides the data masks for XIA list mode data +/// @author S. V. Paulauskas +/// @date December 29, 2016 +#ifndef PIXIESUITE_XIALISTMODEDATAMASK_HPP +#define PIXIESUITE_XIALISTMODEDATAMASK_HPP + +#include +#include + +#include "HelperEnumerations.hpp" + +///A class that provides the necessary data masks and bit shifts to decode the +/// XIA Pixie-16 List Mode Data headers. To decode the data we apply the mask +/// to the 32-bit header words, then shift the result by the specified amount +/// to remove the lease significant bits. We do not include a method for the +/// Event Time Low header word (Word 1) since this value takes the entire +/// 32-bit word. The values of the bit shifts are taken from documentation +/// provided by XIA LLC. +class XiaListModeDataMask { +public: + ///Default constructor + XiaListModeDataMask() { + frequency_ = 0; + firmware_ = DataProcessing::UNKNOWN; + } + + ///Constructor accepting a FIRMWARE enum as an argument + ///@param[in] firmware : The value we want to set for the firmware + ///@param[in] freq : The value in MS/s or MHz that we want to assign to the + /// frequency. + XiaListModeDataMask(const DataProcessing::FIRMWARE &firmware, + const unsigned int &freq) { + firmware_ = firmware; + frequency_ = freq; + } + + ///Constructor accepting a string with the firmware type and the frequency + ///@param[in] firmware : The value we want to set for the firmware + ///@param[in] freq : The value in MS/s or MHz that we want to assign to the + /// frequency. + XiaListModeDataMask(const std::string &firmware, + const unsigned int &freq) { + firmware_ = ConvertStringToFirmware(firmware); + frequency_ = freq; + } + + ///Default Destructor + ~XiaListModeDataMask() {} + + ///Getter for the Mask and Shift of the Channel Number. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetChannelNumberMask() const { + return std::make_pair(0x0000000F, 0); + } + + ///Getter for the Mask and Shift of the Slot Id. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetSlotIdMask() const { + return std::make_pair(0x000000F0, 4); + } + + ///Getter for the Mask and Shift of the Crate ID. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetCrateIdMask() const { + return std::make_pair(0x00000F00, 8); + } + + ///Getter for the Mask and Shift of the Header Length. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetHeaderLengthMask() const { + return std::make_pair(0x0001F000, 12); + } + + ///Getter for the Mask and Shift of the Event Length. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetEventLengthMask() const; + + ///Getter for the Mask and Shift of the Finish Code. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetFinishCodeMask() const { + return std::make_pair(0x80000000, 31); + } + + ///Getter for the Mask and Shift of the Event Time High. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetEventTimeHighMask() const { + return std::make_pair(0x0000FFFF, 0); + } + + ///Getter for the Mask and Shift of the Event Time High. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetCfdFractionalTimeMask() const; + + ///Getter for the Mask and Shift of the Cfd Forced Trigger Bit mask. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetCfdForcedTriggerBitMask() const; + + ///Getter for the Mask and Shift of the CFD Trigger Source Bit. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetCfdTriggerSourceMask() const; + + //Getter for the CFD size + ///@return The decimal size of the CFD, i.e. 13-bit = 8192. It returns a + /// double since we're generally using this size in calculations of the + /// arrival time of the pulse. + double GetCfdSize() const; + + ///Getter for the Mask and Shift of the Energy. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetEventEnergyMask() const; + + ///Getter for the Mask and Shift of the Trace-out-of-range Flag. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetTraceOutOfRangeFlagMask() const; + + ///Getter for the Mask and Shift of the Trace Length. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetTraceLengthMask() const; + + ///Getter for the Mask and shift for the trace words. + ///@return The pair of the mask and bit shift to use to decode the data. + std::pair GetTraceMask() const { + return std::make_pair(0x0000FFFF, 16); + }; + + ///Getter for the value of the FIRMWARE so that we can test that things + /// are working as expected. + ///@return The current value of the internal firmware_ variable. + DataProcessing::FIRMWARE GetFirmware() const { return firmware_; } + + ///Getter for the value of the frequency that we're using. + ///@return The current value of the internal frequency_ variable + unsigned int GetFrequency() const { return frequency_; } + + ///Sets the firmware version + ///@param[in] firmware : The firmware type that we would like to set. + void SetFirmware(const DataProcessing::FIRMWARE &firmware) { + firmware_ = firmware; + } + + ///Sets the firmware version + ///@param[in] type : The string that we are going to convert to the + /// more useful FIRMWARE enum. + void SetFirmware(const std::string &type) { + firmware_ = ConvertStringToFirmware(type); + }; + + ///Sets the frequency of the module that we are working with. + ///@param[in] freq : The frequency of the module in MS/s or MHz that we + /// are working with. + void SetFrequency(const unsigned int &freq) { frequency_ = freq; } + + ///Converts a string to a firmware version this is used to set the + /// firmware using SetFirmware(string) method. + ///@param[in] type : A string of the firmware version that we would like. + /// It can be prepended with the "R" or not. + ///@return The firmware ENUM for the firmware type. + DataProcessing::FIRMWARE ConvertStringToFirmware(const std::string &type); + +private: + ///The firmware version that we are using. + DataProcessing::FIRMWARE firmware_; + ///The frequency of the module that we want to decode. + unsigned int frequency_; + + std::string BadMaskErrorMessage(const std::string &func) const; +}; + +#endif //PIXIESUITE_XIALISTMODEDATAMASK_HPP diff --git a/Analysis/ScanLibraries/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt new file mode 100644 index 000000000..2c2e99346 --- /dev/null +++ b/Analysis/ScanLibraries/source/CMakeLists.txt @@ -0,0 +1,28 @@ +#Set the scan sources that we will make a lib out of +set(PaassScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp + ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp + XiaListModeDataEncoder.cpp) + +if(USE_ROOT) + list(APPEND PaassScanSources RootScanner.cpp) +endif(USE_ROOT) + +#Add the sources to the library +add_library(PaassScanObjects OBJECT ${PaassScanSources}) + +if(BUILD_SHARED_LIBS) + message(STATUS "Building Scan Shared Objects") + add_library(PaassScan SHARED $) + target_link_libraries(PaassScan PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) + if (${CURSES_FOUND}) + target_link_libraries(PaassScan ${CURSES_LIBRARIES}) + endif() + install(TARGETS PaassScan DESTINATION lib) +endif(BUILD_SHARED_LIBS) + +#Create PixieScan static library and add ncurses if we have it +add_library(PaassScanStatic STATIC $) +target_link_libraries(PaassScanStatic PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) +if (${CURSES_FOUND}) + target_link_libraries(PaassScanStatic ${CURSES_LIBRARIES}) +endif() diff --git a/Scan/ScanLib/source/ChannelData.cpp b/Analysis/ScanLibraries/source/ChannelData.cpp similarity index 96% rename from Scan/ScanLib/source/ChannelData.cpp rename to Analysis/ScanLibraries/source/ChannelData.cpp index 0158cd70b..1b94125c1 100644 --- a/Scan/ScanLib/source/ChannelData.cpp +++ b/Analysis/ScanLibraries/source/ChannelData.cpp @@ -21,7 +21,7 @@ ChannelData::ChannelData(XiaData *event_){ yvals = NULL; Clear(); event = event_; - size = event->adcTrace.size(); + size = event->GetTrace().size(); if(size != 0){ xvals = new float[size]; yvals = new float[size]; @@ -74,7 +74,7 @@ void ChannelData::Clear() { size = 0; if(xvals){ delete[] xvals; } if(yvals){ delete[] yvals; } - if(event){ event->clear(); } + if(event){ event->Clear(); } event = NULL; xvals = NULL; diff --git a/Analysis/ScanLibraries/source/ChannelEvent.cpp b/Analysis/ScanLibraries/source/ChannelEvent.cpp new file mode 100644 index 000000000..e4bbb25ca --- /dev/null +++ b/Analysis/ScanLibraries/source/ChannelEvent.cpp @@ -0,0 +1,184 @@ +///@file ChannelEvent.cpp +///@author S. V. Paulauskas (from C. R. Thornsberry's work) +///@date December 2, 2016 + +#include + +#include "ChannelEvent.hpp" + +/// Default constructor. +ChannelEvent::ChannelEvent(){ + event = NULL; + xvals = NULL; + yvals = NULL; + cfdvals = NULL; + Clear(); +} + +/// Constructor from a XiaData. ChannelEvent will take ownership of the XiaData. +ChannelEvent::ChannelEvent(XiaData *event_){ + event = NULL; + xvals = NULL; + yvals = NULL; + cfdvals = NULL; + Clear(); + event = event_; + size = event->GetTrace().size(); + if(size != 0){ + xvals = new float[size]; + yvals = new float[size]; + } +} + +ChannelEvent::~ChannelEvent(){ + if(event){ delete event; } + if(xvals){ delete[] xvals; } + if(yvals){ delete[] yvals; } +} + +float ChannelEvent::CorrectBaseline(){ + if(!event || size == 0){ return -9999; } + else if(baseline_corrected){ return maximum; } + + // Find the baseline + baseline = 0.0; + size_t sample_size = (10 <= size ? 10:size); + for(size_t i = 0; i < sample_size; i++){ + baseline += (float)event->GetTrace()[i]; + } + baseline = baseline/sample_size; + + // Calculate the standard deviation + stddev = 0.0; + for(size_t i = 0; i < sample_size; i++){ + stddev += ((float)event->GetTrace()[i] - baseline)*((float)event->GetTrace()[i] - baseline); + } + stddev = std::sqrt((1.0/sample_size) * stddev); + + // Find the maximum value, the maximum bin, and correct the baseline + maximum = -9999.0; + for(size_t i = 0; i < event->GetTrace().size(); i++){ + xvals[i] = i; + yvals[i] = event->GetTrace()[i]-baseline; + if(yvals[i] > maximum){ + maximum = yvals[i]; + max_index = i; + } + } + + baseline_corrected = true; + + return maximum; +} + +float ChannelEvent::FindLeadingEdge(const float &thresh_/*=0.05*/){ + if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } + else if(phase >= 0.0){ return phase; } + + // Check if this is a valid pulse + if(maximum <= 0 || max_index == 0){ return -9999; } + + for(size_t index = max_index; index > 0; index--){ + if(yvals[index] <= thresh_ * maximum){ + // Interpolate and return the value + // y = thresh_ * maximum + // x = (x1 + (y-y1)/(y2-y1)) + // x1 = index, x2 = index+1 + // y1 = yvals[index], y2 = yvals[index+1] + if(yvals[index+1] == yvals[index]){ return index+1; } + else{ return (phase = (index + (thresh_ * maximum - yvals[index])/(yvals[index+1] - yvals[index]))); } + } + } + + return -9999; +} + +float ChannelEvent::IntegratePulse(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ + if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } + + size_t stop = (stop_ == 0?size:stop_); + + qdc = 0.0; + for(size_t i = start_+1; i < stop; i++){ // Integrate using trapezoidal rule. + qdc += 0.5*(yvals[i-1] + yvals[i]); + } + + return qdc; +} + +float ChannelEvent::FindQDC(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ + if(qdc >= 0.0){ return qdc; } + + qdc = IntegratePulse(start_, stop_); + + return qdc; +} + +/// Perform CFD analysis on the waveform. +float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/, const size_t &D_/*=1*/, const size_t &L_/*=1*/){ + if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } + if(!cfdvals){ + if(size == 0) + return -9999; + cfdvals = new float[size]; + } + + float cfdMinimum = 9999; + size_t cfdMinIndex = 0; + + cfdCrossing = -9999; + + // Compute the cfd waveform. + for(size_t cfdIndex = 0; cfdIndex < size; ++cfdIndex){ + cfdvals[cfdIndex] = 0.0; + if(cfdIndex >= L_ + D_ - 1){ + for(size_t i = 0; i < L_; i++) + cfdvals[cfdIndex] += F_ * yvals[cfdIndex - i] - yvals[cfdIndex - i - D_]; + } + if(cfdvals[cfdIndex] < cfdMinimum){ + cfdMinimum = cfdvals[cfdIndex]; + cfdMinIndex = cfdIndex; + } + } + + // Find the zero-crossing. + if(cfdMinIndex > 0){ + // Find the zero-crossing. + for(size_t cfdIndex = cfdMinIndex-1; cfdIndex >= 0; cfdIndex--){ + if(cfdvals[cfdIndex] >= 0.0 && cfdvals[cfdIndex+1] < 0.0){ + cfdCrossing = xvals[cfdIndex] - cfdvals[cfdIndex]*(xvals[cfdIndex+1]-xvals[cfdIndex])/(cfdvals[cfdIndex+1]-cfdvals[cfdIndex]); + break; + } + } + } + + return cfdCrossing; +} + +void ChannelEvent::Clear(){ + phase = -9999; + maximum = -9999; + baseline = -9999; + stddev = -9999; + qdc = -9999; + cfdCrossing = -9999; + max_index = 0; + + hires_energy = -9999; + hires_time = -9999; + + valid_chan = false; + baseline_corrected = false; + ignore = false; + + size = 0; + if(xvals){ delete[] xvals; } + if(yvals){ delete[] yvals; } + if(cfdvals){ delete[] cfdvals; } + if(event){ event->Clear(); } + + event = NULL; + xvals = NULL; + yvals = NULL; + cfdvals = NULL; +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/source/RootScanner.cpp b/Analysis/ScanLibraries/source/RootScanner.cpp new file mode 100644 index 000000000..2be64fdee --- /dev/null +++ b/Analysis/ScanLibraries/source/RootScanner.cpp @@ -0,0 +1,189 @@ +#include "RootScanner.hpp" + +#include + +#include "TSystem.h" +#include "TList.h" +#include "TObject.h" +#include "TAxis.h" +#include "TH1.h" +#include "TH2.h" +#include "TGraph.h" + +RootScanner::RootScanner() : + ScanInterface() +{ + new TApplication("scanner", 0, NULL); + + canvas_ = new TCanvas("canvas", ""); +} +RootScanner::~RootScanner() { + canvas_->Close(); + delete canvas_; +} + +/** IdleTask is called whenever a scan is not busy doing things. This method + * may be used to update things which need to be updated every so often + * (e.g. a root TCanvas). + * \return Nothing. + */ +void RootScanner::IdleTask() { + gSystem->ProcessEvents(); + usleep(100000); +} + +void RootScanner::ResetZoom(TVirtualPad *pad /*= gPad*/) { + AxisInfo* padZoomInfo = &zoomInfo_[pad]; + for (int i=0;ilimitMin[i] = std::numeric_limits::max(); + padZoomInfo->limitMax[i] = std::numeric_limits::min(); + padZoomInfo->rangeUserMin[i] = std::numeric_limits::max(); + padZoomInfo->rangeUserMax[i] = std::numeric_limits::min(); + } + padZoomInfo->reset = true; +} + +//Update the zoom levels on a pad. +void RootScanner::UpdateZoom(TVirtualPad *pad /*= gPad*/) { + //Get zoom info for this pad. + auto itr = zoomInfo_.find(pad); + if (itr == zoomInfo_.end()) ResetZoom(pad); + AxisInfo* padZoomInfo = &zoomInfo_[pad]; + + //If zoom has been reset we continue, otherwise we get current axis limits. + if (padZoomInfo->reset) padZoomInfo->reset = false; + else { + //Get the user zoom settings. + padZoomInfo->rangeUserMin[0] = pad->GetUxmin(); + padZoomInfo->rangeUserMax[0] = pad->GetUxmax(); + padZoomInfo->rangeUserMin[1] = pad->GetUymin(); + padZoomInfo->rangeUserMax[1] = pad->GetUymax(); +// padZoomInfo->rangeUserMin[2] = pad->GetUzmin(); +// padZoomInfo->rangeUserMax[2] = pad->GetUzmax(); + } + + //Determine if the user had zoomed or unzoomed by comparing the current axis + // limits to those taken from the canvas. + bool userZoom[numAxes_]; + for (int i=0; irangeUserMin[i] > padZoomInfo->limitMin[i] || + padZoomInfo->rangeUserMax[i] < padZoomInfo->limitMax[i]); + } + + //Get the list of items on the pad. + TList *list = gPad->GetListOfPrimitives(); + + bool limitChange = false; + + //Loop over the objects in the list to determine pad limits. + for( TObject *obj = list->First(); obj; obj = list->After(obj)) { + TAxis *xAxis, *yAxis, *zAxis = NULL; //Pointers to the axes. + + //Check if the object is a histogram + if ( TH1* hist = dynamic_cast(obj) ) { + xAxis = hist->GetXaxis(); + yAxis = hist->GetYaxis(); + + //Check if hist is 2D + if (dynamic_cast(hist) ) { + zAxis = hist->GetZaxis(); + } + else{ + if (hist->GetBinContent(hist->GetMaximumBin()) * 1.1 > padZoomInfo->limitMax[1]) { + padZoomInfo->limitMax[1] = 1.1 * hist->GetBinContent(hist->GetMaximumBin()); + } + } + } + //Check if the object is a graph + else if ( TGraph* graph = dynamic_cast(obj) ) { + xAxis = graph->GetXaxis(); + yAxis = graph->GetYaxis(); + } + //Not an object we care about so we continue. + else continue; + + //If the axis min / max are outside current stored values then we update + // the values. + if (xAxis->GetXmin() < padZoomInfo->limitMin[0]) { + padZoomInfo->limitMin[0] = xAxis->GetXmin(); + limitChange = true; + } + if (xAxis->GetXmax() > padZoomInfo->limitMax[0]) { + padZoomInfo->limitMax[0] = xAxis->GetXmax(); + limitChange = true; + } + if (yAxis->GetXmin() < padZoomInfo->limitMin[1]) { + padZoomInfo->limitMin[1] = yAxis->GetXmin(); + limitChange = true; + } + if (yAxis->GetXmax() > padZoomInfo->limitMax[1]) { + padZoomInfo->limitMax[1] = yAxis->GetXmax(); + limitChange = true; + } + if (zAxis) { + if (zAxis->GetXmin() < padZoomInfo->limitMin[1]) { + padZoomInfo->limitMin[1] = zAxis->GetXmin(); + limitChange = true; + } + if (yAxis->GetXmax() > padZoomInfo->limitMax[1]) { + padZoomInfo->limitMax[1] = zAxis->GetXmax(); + limitChange = true; + } + + } + + } + + //If the user didn't zoom we store the current axis limits in the userZoom + // values. + for (int axis = 0; axis < 3; axis++) { + if (!userZoom[axis]) { + padZoomInfo->rangeUserMin[axis] = padZoomInfo->limitMin[axis]; + padZoomInfo->rangeUserMax[axis] = padZoomInfo->limitMax[axis]; + } + } + + //Loop over the objects again and set the proper limits for each item. + for( TObject *obj = list->First(); obj; obj = list->After(obj)) { + TAxis *xAxis, *yAxis; //Pointers to the axes. + //Check if the object is a histogram + if ( TH1* hist = dynamic_cast(obj) ) { + xAxis = hist->GetXaxis(); + yAxis = hist->GetYaxis(); + + if (limitChange) { + //Set the axes limits + xAxis->SetLimits(padZoomInfo->limitMin[0], padZoomInfo->limitMax[0]); + yAxis->SetLimits(padZoomInfo->limitMin[1], padZoomInfo->limitMax[1]); + + //Check if hist is 2D + if (dynamic_cast(hist) ) { + TAxis *zAxis = hist->GetZaxis(); + zAxis->SetLimits(padZoomInfo->limitMin[2], padZoomInfo->limitMax[2]); + } + //We assume if not 2D then its 1D. + else { + //Set the histogram maximum + hist->SetMaximum(padZoomInfo->limitMax[1]); + } + } + + } + //Check if the object is a graph + else if ( TGraph* graph = dynamic_cast(obj) ) { + xAxis = graph->GetXaxis(); + yAxis = graph->GetYaxis(); + } + else continue; + + //Set the range of the axis to the determined userZoom values. + xAxis->SetRangeUser(padZoomInfo->rangeUserMin[0], padZoomInfo->rangeUserMax[0]); + yAxis->SetRangeUser(padZoomInfo->rangeUserMin[1], padZoomInfo->rangeUserMax[1]); + } + + if (limitChange) { + pad->Modified(); + } + +} + diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Analysis/ScanLibraries/source/ScanInterface.cpp similarity index 92% rename from Scan/ScanLib/source/ScanInterface.cpp rename to Analysis/ScanLibraries/source/ScanInterface.cpp index 94bd47e7b..49e31d673 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Analysis/ScanLibraries/source/ScanInterface.cpp @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -386,6 +387,10 @@ ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ scan_init = false; file_open = false; + //Initialize the setup and output file names + output_filename = ""; + setup_filename = ""; + kill_all = false; run_ctrl_exit = false; @@ -396,22 +401,28 @@ ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ if(core_){ core = core_; } else{ core = NULL; } - // Push back all of the arguments. Annoying, but we only need to do this once. - baseOpts.push_back(optionExt("batch", no_argument, NULL, 'b', "", "Run in batch mode (i.e. with no command line)")); - baseOpts.push_back(optionExt("config", required_argument, NULL, 'c', - "", "Specify path to setup to use for scan")); - baseOpts.push_back(optionExt("counts", no_argument, NULL, 0, "", "Write all recorded channel counts to a file")); - baseOpts.push_back(optionExt("debug", no_argument, NULL, 0, "", "Enable readout debug mode")); - baseOpts.push_back(optionExt("dry-run", no_argument, NULL, 0, "", "Extract spills from file, but do no processing")); - baseOpts.push_back(optionExt("fast-fwd", required_argument, NULL, 0, "", "Skip ahead to a specified word in the file (start of file at zero)")); - baseOpts.push_back(optionExt("help", no_argument, NULL, 'h', "", "Display this dialogue")); - baseOpts.push_back(optionExt("input", required_argument, NULL, 'i', "", "Specifies the input file to analyze")); - baseOpts.push_back(optionExt("output", required_argument, NULL, 'o', "", "Specifies the name of the output file. Default is \"out\"")); - baseOpts.push_back(optionExt("quiet", no_argument, NULL, 'q', "", "Toggle off verbosity flag")); - baseOpts.push_back(optionExt("shm", no_argument, NULL, 's', "", "Enable shared memory readout")); - baseOpts.push_back(optionExt("version", no_argument, NULL, 'v', "", "Display version information")); - - optstr = "bc:hi:o:qsv"; + //Setup all the arguments that are known to the program. + baseOpts = { + optionExt("batch", no_argument, NULL, 'b', "", "Run in batch mode (i.e. with no command line)"), + optionExt("config", required_argument, NULL, 'c', "", "Specify path to setup to use for scan"), + optionExt("counts", no_argument, NULL, 0, "", "Write all recorded channel counts to a file"), + optionExt("debug", no_argument, NULL, 0, "", "Enable readout debug mode"), + optionExt("dry-run", no_argument, NULL, 0, "", "Extract spills from file, but do no processing"), + optionExt("fast-fwd", required_argument, NULL, 0, "", "Skip ahead to a specified word in the file (start of file at zero)"), + optionExt("firmware", required_argument, NULL, 'f', "", + "Sets the firmware revision for decoding the data. " + "See the wiki or HelperEnumerations.hpp " + "for more information."), + optionExt("frequency", required_argument, NULL, 0, "", "Specifies the sampling frequency used to collect the data."), + optionExt("help", no_argument, NULL, 'h', "", "Display this dialogue"), + optionExt("input", required_argument, NULL, 'i', "", "Specifies the input file to analyze"), + optionExt("output", required_argument, NULL, 'o', "", "Specifies the name of the output file. Default is \"out\""), + optionExt("quiet", no_argument, NULL, 'q', "", "Toggle off verbosity flag"), + optionExt("shm", no_argument, NULL, 's', "", "Enable shared memory readout"), + optionExt("version", no_argument, NULL, 'v', "", "Display version information") + }; + + optstr = "bc:f:hi:o:qsv"; progName = std::string(PROG_NAME); msgHeader = progName + ": "; @@ -461,7 +472,7 @@ void ScanInterface::RunControl(){ bool full_spill = false; while(true){ - if(kill_all == true){ + if(kill_all == true){ break; } else if(!is_running){ @@ -832,6 +843,8 @@ bool ScanInterface::Setup(int argc, char *argv[]){ dry_run_mode = false; shm_mode = false; num_spills_recvd = 0; + unsigned int samplingFrequency = 0; + std::string firmware = ""; std::string input_filename = ""; // Add derived class options to the option list. @@ -872,6 +885,10 @@ bool ScanInterface::Setup(int argc, char *argv[]){ else if(strcmp("fast-fwd", longOpts[idx].name) == 0) { file_start_offset = atoll(optarg); } + else if(strcmp("frequency", longOpts[idx].name) == 0) + samplingFrequency = (unsigned int)std::stoi(optarg); + else if(strcmp("firmware", longOpts[idx].name) == 0) + firmware = optarg; else{ for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ if(strcmp(iter->name, longOpts[idx].name) == 0){ @@ -894,6 +911,9 @@ bool ScanInterface::Setup(int argc, char *argv[]){ case 'c' : setup_filename = optarg; break; + case 'f' : + firmware = optarg; + break; case 'h' : help(argv[0]); return false; @@ -938,6 +958,19 @@ bool ScanInterface::Setup(int argc, char *argv[]){ // Link this object to the Unpacker for cross-calls. core->SetInterface(this); + //Initialize the data mask for decoding the data + ///@TODO We need to be able to handle mixed systems, which is not + /// implemented yet. + if(samplingFrequency == 0 || firmware == "") { + if (samplingFrequency == 0) + throw std::invalid_argument( + "ScanInterface::Setup - The frequency has not been set."); + if(firmware == "") + throw std::invalid_argument("ScanInterface::Setup - The firmware " + "has not been set."); + } else + core->InitializeDataMask(firmware, samplingFrequency); + if(debug_mode) core->SetDebugMode(); diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Analysis/ScanLibraries/source/Unpacker.cpp similarity index 57% rename from Scan/ScanLib/source/Unpacker.cpp rename to Analysis/ScanLibraries/source/Unpacker.cpp index 7668425fa..080f78130 100644 --- a/Scan/ScanLib/source/Unpacker.cpp +++ b/Analysis/ScanLibraries/source/Unpacker.cpp @@ -1,41 +1,40 @@ /** \file Unpacker.cpp * \brief A class to handle the unpacking of UTK/ORNL style pixie16 data spills. * - * This class is intended to be used as a replacement of pixiestd.cpp from Stan - * Paulauskas's pixie_scan. The majority of function names and arguments are + * This class is intended to be used as a replacement of PixieStd.cpp from + * pixie_scan. The majority of function names and arguments are * preserved as much as possible while allowing for more standardized unpacking * of pixie16 data. - * CRT * * \author C. R. Thornsberry * \date Feb. 12th, 2016 */ -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include + #include "Unpacker.hpp" #include "XiaData.hpp" +#include "XiaListModeDataDecoder.hpp" + +using namespace std; -void clearDeque(std::deque &list){ +void clearDeque(deque &list){ while(!list.empty()){ delete list.front(); list.pop_front(); } } -/** Scan the event list and sort it by timestamp. - * \return Nothing. - */ +///Scan the event list and sort it by timestamp. +/// @return Nothing. void Unpacker::TimeSort(){ - for(std::vector >::iterator iter = eventList.begin(); iter != eventList.end(); iter++){ - sort(iter->begin(), iter->end(), &XiaData::compareTime); - } + for(vector >::iterator iter = eventList.begin(); + iter != eventList.end(); iter++) + sort(iter->begin(), iter->end(), &XiaData::CompareTime); } /** Scan the time sorted event list and package the events into a raw @@ -65,32 +64,34 @@ bool Unpacker::BuildRawEvent(){ realStopTime = eventStartTime; unsigned int mod, chan; - std::string type, subtype, tag; + string type, subtype, tag; XiaData *current_event = NULL; - // Loop over all time-sorted modules. - for(std::vector >::iterator iter = eventList.begin(); iter != eventList.end(); iter++){ + // Loop over all time-sorted modules. + for(vector >::iterator iter = eventList.begin(); iter != eventList.end(); iter++){ if(iter->empty()) continue; // Loop over the list of channels that fired in this buffer while(!iter->empty()){ current_event = iter->front(); - mod = current_event->modNum; - chan = current_event->chanNum; + mod = current_event->GetModuleNumber(); + chan = current_event->GetChannelNumber(); if(mod > MAX_PIXIE_MOD || chan > MAX_PIXIE_CHAN){ // Skip this channel - std::cout << "BuildRawEvent: Encountered non-physical Pixie ID (mod = " << mod << ", chan = " << chan << ")\n"; + cout << "BuildRawEvent: Encountered non-physical Pixie ID (mod = " << mod << ", chan = " << chan << ")\n"; delete current_event; iter->pop_front(); continue; } - double currtime = current_event->time; + double currtime = current_event->GetTime(); // Check for backwards time-skip. This is un-handled currently and needs fixed CRT!!! if(currtime < eventStartTime) - std::cout << "BuildRawEvent: Detected backwards time-skip from start=" << eventStartTime << " to " << current_event->time << "???\n"; + cout << "BuildRawEvent: Detected backwards time-skip from " + "start=" << eventStartTime << " to " + << current_event->GetTime() << "???\n"; // If the time difference between the current and previous event is // larger than the event width, finalize the current event, otherwise @@ -129,16 +130,16 @@ bool Unpacker::BuildRawEvent(){ * \return True if the XiaData's module number is valid and false otherwise. */ bool Unpacker::AddEvent(XiaData *event_){ - if(event_->modNum > MAX_PIXIE_MOD){ return false; } + if(event_->GetModuleNumber() > MAX_PIXIE_MOD){ return false; } // Check for the need to add a new deque to the event list. - if(event_->modNum+1 > (unsigned int)eventList.size()){ - while (eventList.size() < event_->modNum + 1) { + if(event_->GetModuleNumber()+1 > (unsigned int)eventList.size()){ + while (eventList.size() < event_->GetModuleNumber() + 1) { eventList.push_back(std::deque()); } } - eventList.at(event_->modNum).push_back(event_); + eventList.at(event_->GetModuleNumber()).push_back(event_); return true; } @@ -173,8 +174,8 @@ bool Unpacker::GetFirstTime(double &time){ for(std::vector >::iterator iter = eventList.begin(); iter != eventList.end(); iter++){ if(iter->empty()) continue; - if(iter->front()->time < time) - time = iter->front()->time; + if(iter->front()->GetTime() < time) + time = iter->front()->GetTime(); } return true; @@ -199,162 +200,25 @@ void Unpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ ClearRawEvent(); } -/** Called form ReadSpill. Scan the current spill and construct a list of - * events which fired by obtaining the module, channel, trace, etc. of the - * timestamped event. This method will construct the event list for - * later processing. - * \param[in] buf Pointer to an array of unsigned ints containing raw buffer data. - * \param[out] bufLen The number of words in the buffer. - * \return The number of XiaDatas read from the buffer. - */ -int Unpacker::ReadBuffer(unsigned int *buf, unsigned long &bufLen){ - // multiplier for high bits of 48-bit time - static const double HIGH_MULT = pow(2., 32.); - - unsigned int modNum; - unsigned long numEvents = 0; - unsigned int *bufStart = buf; - - // Determine the number of words in the buffer - bufLen = *buf++; - - // Read the module number - modNum = *buf++; - - XiaData *lastVirtualChannel = NULL; - - if(bufLen > 0){ // Check if the buffer has data - if(bufLen == 2){ // this is an empty channel - return 0; - } - while( buf < bufStart + bufLen ){ - XiaData *currentEvt = new XiaData(); - - // decoding event data... see pixie16app.c - // buf points to the start of channel data - unsigned int chanNum = (buf[0] & 0x0000000F); - unsigned int slotNum = (buf[0] & 0x000000F0) >> 4; - unsigned int crateNum = (buf[0] & 0x00000F00) >> 8; - unsigned int headerLength = (buf[0] & 0x0001F000) >> 12; - unsigned int eventLength = (buf[0] & 0x1FFE0000) >> 17; - - currentEvt->virtualChannel = ((buf[0] & 0x20000000) != 0); - currentEvt->saturatedBit = ((buf[0] & 0x40000000) != 0); - currentEvt->pileupBit = ((buf[0] & 0x80000000) != 0); - - // Rev. D header lengths not clearly defined in pixie16app_defs - //! magic numbers here for now - if(headerLength == 1){ - // this is a manual statistics block inserted by the poll program - /*stats.DoStatisticsBlock(&buf[1], modNum); - buf += eventLength; - numEvents = -10;*/ - continue; - } - if(headerLength != 4 && headerLength != 8 && headerLength != 12 && headerLength != 16){ - std::cout << "ReadBuffer: Unexpected header length: " << headerLength << std::endl; - std::cout << "ReadBuffer: Buffer " << modNum << " of length " << bufLen << std::endl; - std::cout << "ReadBuffer: CHAN:SLOT:CRATE " << chanNum << ":" << slotNum << ":" << crateNum << std::endl; - // advance to next event and continue - // buf += EventLength; - // continue; - - // skip the rest of this buffer - return numEvents; - } - - unsigned int lowTime = buf[1]; - unsigned int highTime = buf[2] & 0x0000FFFF; - unsigned int cfdTime = (buf[2] & 0xFFFF0000) >> 16; - unsigned int energy = buf[3] & 0x0000FFFF; - unsigned int traceLength = (buf[3] & 0xFFFF0000) >> 16; - - if(headerLength == 8 || headerLength == 16){ - // Skip the onboard partial sums for now - // trailing, leading, gap, baseline - } - - if(headerLength >= 12){ - int offset = headerLength - 8; - for (int i=0; i < currentEvt->numQdcs; i++){ - currentEvt->qdcValue[i] = buf[offset + i]; - } - } - - // One last check - if( traceLength / 2 + headerLength != eventLength ){ - std::cout << "ReadBuffer: Bad event length (" << eventLength << ") does not correspond with length of header ("; - std::cout << headerLength << ") and length of trace (" << traceLength << ")" << std::endl; - buf += eventLength; - continue; - } - - // Handle multiple crates - modNum += 100 * crateNum; - - currentEvt->chanNum = chanNum; - currentEvt->modNum = modNum; - /*if(currentEvt->virtualChannel){ - DetectorLibrary* modChan = DetectorLibrary::get(); - - currentEvt->modNum += modChan->GetPhysicalModules(); - if(modChan->at(modNum, chanNum).HasTag("construct_trace")){ - lastVirtualChannel = currentEvt; - } - }*/ - - channel_counts[modNum][chanNum]++; - - currentEvt->energy = energy; - if(currentEvt->saturatedBit){ currentEvt->energy = 16383; } - - currentEvt->trigTime = lowTime; - currentEvt->cfdTime = cfdTime; - currentEvt->eventTimeHi = highTime; - currentEvt->eventTimeLo = lowTime; - currentEvt->time = highTime * HIGH_MULT + lowTime; - - buf += headerLength; - // Check if trace data follows the channel header - if( traceLength > 0 ){ - // sbuf points to the beginning of trace data - unsigned short *sbuf = (unsigned short *)buf; - - currentEvt->reserve(traceLength); - - /*if(currentEvt->saturatedBit) - currentEvt->trace.SetValue("saturation", 1);*/ - - if( lastVirtualChannel != NULL && lastVirtualChannel->adcTrace.empty() ){ - lastVirtualChannel->assign(traceLength, 0); - } - // Read the trace data (2-bytes per sample, i.e. 2 samples per word) - for(unsigned int k = 0; k < traceLength; k ++){ - currentEvt->push_back(sbuf[k]); - - if(lastVirtualChannel != NULL){ - lastVirtualChannel->adcTrace[k] += sbuf[k]; - } - } - buf += traceLength / 2; - } - - AddEvent(currentEvt); - - numEvents++; - } - } - else{ // if buffer has data - std::cout << "ReadBuffer: ERROR IN ReadBuffData, LIST UNKNOWN" << std::endl; - return -100; - } - - return numEvents; +///Called form ReadSpill. Scan the current spill and construct a list of +///events which fired by obtaining the module, channel, trace, etc. of the +///timestamped event. This method will construct the event list for +///later processing. +///@param[in] buf : Pointer to an array of unsigned ints containing raw +/// buffer data. +///@return The number of XiaDatas read from the buffer. +int Unpacker::ReadBuffer(unsigned int *buf){ + static XiaListModeDataDecoder decoder; + decodedList_ = decoder.DecodeBuffer(buf, mask_); + for (vector::iterator it = decodedList_.begin(); + it != decodedList_.end(); it++) + AddEvent(*it); + return (int)decodedList_.size(); } Unpacker::Unpacker() : eventWidth(62), // ~ 500 ns in 8 ns pixie clock ticks. - debug_mode(false), + debug_mode(false), running(true), interface(NULL), TOTALREAD(1000000), // Maximum number of data words to read. @@ -386,17 +250,13 @@ Unpacker::~Unpacker(){ * \param[in] is_verbose Toggle the verbosity flag on/off. * \return True if the spill was read successfully and false otherwise. */ -bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbose/*=true*/){ +bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, + bool is_verbose/*=true*/){ const unsigned int maxVsn = 14; // No more than 14 pixie modules per crate unsigned int nWords_read = 0; - - //static clock_t clockBegin; // Initialization time - //time_t tmsBegin; int retval = 0; // return value from various functions - - unsigned long bufLen; - + // Various event counters unsigned long numEvents = 0; static int counter = 0; // the number of times this function is called @@ -423,14 +283,14 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos // Check sanity of record length and vsn if(lenRec > maxWords || (vsn > maxVsn && vsn != 9999 && vsn != 1000)){ if(is_verbose){ - std::cout << "ReadSpill: SANITY CHECK FAILED: lenRec = " << lenRec << ", vsn = " << vsn << ", read " << nWords_read << " of " << nWords << std::endl; + cout << "ReadSpill: SANITY CHECK FAILED: lenRec = " << lenRec << ", vsn = " << vsn << ", read " << nWords_read << " of " << nWords << endl; } return false; } // If the record length is 6, this is an empty channel. // Skip this vsn and continue with the next - //! Revision specific, so move to ReadBuffData + ///@TODO Revision specific, so move to ReadBuffData if(lenRec==6){ nWords_read += lenRec; lastVsn=vsn; @@ -442,7 +302,7 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos if(vsn < maxVsn){ if(lastVsn != 0xFFFFFFFF && vsn != lastVsn+1){ if(is_verbose){ - std::cout << "ReadSpill: MISSING BUFFER " << lastVsn+1 << ", lastVsn = " << lastVsn << ", vsn = " << vsn << ", lenrec = " << lenRec << std::endl; + cout << "ReadSpill: MISSING BUFFER " << lastVsn+1 << ", lastVsn = " << lastVsn << ", vsn = " << vsn << ", lenrec = " << lenRec << endl; } ClearEventList(); fullSpill=false; // WHY WAS THIS TRUE!?!? CRT @@ -450,15 +310,15 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos // Read the buffer. After read, the vector eventList will //contain pointers to all channels that fired in this buffer - retval = ReadBuffer(&data[nWords_read], bufLen); + retval = ReadBuffer(&data[nWords_read]); // If the return value is less than the error code, //reading the buffer failed for some reason. //Print error message and reset variables if necessary if(retval <= -100){ - if(is_verbose){ std::cout << "ReadSpill: READOUT PROBLEM " << retval << " in event " << counter << std::endl; } + if(is_verbose){ cout << "ReadSpill: READOUT PROBLEM " << retval << " in event " << counter << endl; } if(retval == -100){ - if(is_verbose){ std::cout << "ReadSpill: Remove list " << lastVsn << " " << vsn << std::endl; } + if(is_verbose){ cout << "ReadSpill: Remove list " << lastVsn << " " << vsn << endl; } ClearEventList(); } return false; @@ -478,7 +338,7 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos if(is_verbose){ /*struct tm * timeinfo; timeinfo = localtime (&theTime); - std::cout << "ReadSpill: Read wall clock time of " << asctime(timeinfo);*/ + cout << "ReadSpill: Read wall clock time of " << asctime(timeinfo);*/ } nWords_read += lenRec; continue; @@ -490,13 +350,13 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos else{ // Bail out if we have lost our place, // (bad vsn) and process events - std::cout << "ReadSpill: UNEXPECTED VSN " << vsn << std::endl; + cout << "ReadSpill: UNEXPECTED VSN " << vsn << endl; break; } } // while still have words if(nWords > TOTALREAD || nWords_read > TOTALREAD){ - std::cout << "ReadSpill: Values of nn - " << nWords << " nk - "<< nWords_read << " TOTALREAD - " << TOTALREAD << std::endl; + cout << "ReadSpill: Values of nn - " << nWords << " nk - "<< nWords_read << " TOTALREAD - " << TOTALREAD << endl; return false; } @@ -510,7 +370,7 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos // Check the number of read words if(is_verbose && nWords_read != nWords){ - std::cout << "ReadSpill: Received spill of " << nWords << " words, but read " << nWords_read << " words\n"; + cout << "ReadSpill: Received spill of " << nWords << " words, but read " << nWords_read << " words\n"; } // If there are events to process, continue @@ -540,17 +400,17 @@ bool Unpacker::ReadSpill(unsigned int *data, unsigned int nWords, bool is_verbos // Every once in a while (when evcount is a multiple of 1000) // print the time elapsed doing the analysis if((evCount % 1000 == 0 || evCount == 1) && theTime != 0){ - std::cout << std::endl << "ReadSpill: Data read up to poll status time " << ctime(&theTime); + cout << endl << "ReadSpill: Data read up to poll status time " << ctime(&theTime); } } else { - if(is_verbose){ std::cout << "ReadSpill: Spill split between buffers" << std::endl; } + if(is_verbose){ cout << "ReadSpill: Spill split between buffers" << endl; } ClearEventList(); // This tosses out all events read into the deque so far return false; } } else if(retval != -10){ - if(is_verbose){ std::cout << "ReadSpill: bad buffer, numEvents = " << numEvents << std::endl; } + if(is_verbose){ cout << "ReadSpill: bad buffer, numEvents = " << numEvents << endl; } ClearEventList(); // This tosses out all events read into the deque so far return false; } @@ -566,7 +426,7 @@ void Unpacker::Write(){ if(count_output.good()){ for(unsigned int i = 0; i <= MAX_PIXIE_MOD; i++){ for(unsigned int j = 0; j <= MAX_PIXIE_CHAN; j++){ - count_output << i << "\t" << j << "\t" << channel_counts[i][j] << std::endl; + count_output << i << "\t" << j << "\t" << channel_counts[i][j] << endl; } } count_output.close(); diff --git a/Analysis/ScanLibraries/source/XiaData.cpp b/Analysis/ScanLibraries/source/XiaData.cpp new file mode 100644 index 000000000..90527e606 --- /dev/null +++ b/Analysis/ScanLibraries/source/XiaData.cpp @@ -0,0 +1,23 @@ +///@file XiaData.cpp +///@brief A class that holds information from the XIA LLC. Pixie-16 List +/// Mode Data +///@authors C. R. Thornsberry and S. V. Paulauskas +#include "XiaData.hpp" + +///Clears all of the variables. The vectors are all cleared using the clear() +/// method. This method is called when the class is first initalizied so that +/// it has some default values for the software to use in the event that they +/// are needed. +void XiaData::Clear(){ + cfdForceTrig_ = cfdTrigSource_ = isPileup_ = isSaturated_ = false; + isVirtualChannel_ = false; + + energy_ = baseline_ = 0.0; + + chanNum_ = crateNum_ = slotNum_ = cfdTime_ = 0; + eventTimeHigh_ = eventTimeLow_ = externalTimeLow_ = externalTimeHigh_ = 0; + + eSums_.clear(); + qdc_.clear(); + trace_.clear(); +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/source/XiaListModeDataDecoder.cpp b/Analysis/ScanLibraries/source/XiaListModeDataDecoder.cpp new file mode 100644 index 000000000..90d591d25 --- /dev/null +++ b/Analysis/ScanLibraries/source/XiaListModeDataDecoder.cpp @@ -0,0 +1,276 @@ +/// @file XiaListModeDataDecoder.hpp +/// @brief Class that handles decoding list mode data from XIA Pixie-16 +/// modules. +/// @author S. V. Paulauskas +/// @date December 23, 2016 +#include +#include +#include + +#include + +#include "HelperEnumerations.hpp" +#include "XiaListModeDataDecoder.hpp" + +using namespace std; +using namespace DataProcessing; + +vector XiaListModeDataDecoder::DecodeBuffer( + unsigned int *buf, const XiaListModeDataMask &mask) { + + unsigned int *bufStart = buf; + ///@NOTE : These two pieces here are the Pixie Module Data Header. They + /// tell us the number of words read from the module (bufLen) and the VSN + /// of the module (module number). + unsigned int bufLen = *buf++; + unsigned int modNum = *buf++; + + //A buffer length of zero is an issue, we'll throw a length error. + if (bufLen == 0) + throw length_error("Unpacker::ReadBuffer - The buffer length was " + "sized 0. This is a huge issue."); + + //For empty buffers we just return an empty vector. + static const unsigned int emptyBufferLength = 2; + if (bufLen == emptyBufferLength) + return vector(); + + stringstream msg; + vector events; + static unsigned int numSkippedBuffers = 0; + + while (buf < bufStart + bufLen) { + XiaData *data = new XiaData(); + bool hasExternalTimestamp = false; + bool hasQdc = false; + bool hasEnergySums = false; + + pair lengths = + DecodeWordZero(buf[0], *data, mask); + unsigned int headerLength = lengths.first; + unsigned int eventLength = lengths.second; + + data->SetEventTimeLow(buf[1]); + DecodeWordTwo(buf[2], *data, mask); + unsigned int traceLength = DecodeWordThree(buf[3], *data, mask); + + //We check the header length here to set the appropriate flags for + // processing the rest of the header words. If we encounter a header + // length that we do not know we will throw an error as this + // generally indicates an issue with the data file or processing at a + // higher level. + switch (headerLength) { + case STATS_BLOCK : // Manual statistics block inserted by poll + // this is a manual statistics block inserted by the poll program + /*stats.DoStatisticsBlock(&buf[1], modNum); + buf += eventLength; + numEvents = -10;*/ + continue; + case HEADER : + break; + case HEADER_W_ETS : + hasExternalTimestamp = true; + break; + case HEADER_W_QDC : + hasQdc = true; + break; + case HEADER_W_ESUM : + hasEnergySums = true; + break; + case HEADER_W_ESUM_ETS : + hasExternalTimestamp = hasEnergySums = true; + break; + case HEADER_W_ESUM_QDC : + hasEnergySums = hasQdc = true; + break; + case HEADER_W_ESUM_QDC_ETS : + hasEnergySums = hasExternalTimestamp = hasQdc = true; + break; + case HEADER_W_QDC_ETS : + hasQdc = hasExternalTimestamp = true; + break; + default: + numSkippedBuffers++; + cerr << "XiaListModeDataDecoder::ReadBuffer : We encountered " + "an unrecognized header length (" << headerLength + << "). " << endl + << "Skipped " << numSkippedBuffers + << " buffers in the file." << endl + << "Unexpected header length: " << headerLength << endl + << "ReadBuffer: Buffer " << modNum << " of length " + << bufLen << endl + << "ReadBuffer: CRATE:SLOT(MOD):CHAN " + << data->GetCrateNumber() << ":" + << data->GetSlotNumber() << "(" << modNum << "):" + << data->GetChannelNumber() << endl; + return vector(); + } + + if (hasExternalTimestamp) { + //Do nothing for now + } + + if (hasEnergySums) { + // Skip the onboard partial sums for now + // trailing, leading, gap, baseline + } + + if (hasQdc) { + static const unsigned int numQdcs = 8; + vector tmp; + unsigned int offset = headerLength - numQdcs; + for (unsigned int i = 0; i < numQdcs; i++) { + tmp.push_back(buf[offset + i]); + } + data->SetQdc(tmp); + } + + ///@TODO Figure out where to put this... + //channel_counts[modNum][chanNum]++; + + ///@TODO This needs to be revised to take into account the bit + /// resolution of the modules. I've currently set it to the maximum + /// bit resolution of any module (16-bit). + if (data->IsSaturated()) + data->SetEnergy(65536); + + //We set the time according to the revision and firmware. + data->SetTime(CalculateTimeInSamples(mask, *data)); + + // One last check to ensure event length matches what we think it + // should be. + if (traceLength / 2 + headerLength != eventLength) { + numSkippedBuffers++; + cerr << "XiaListModeDataDecoder::ReadBuffer : Event" + "length (" << eventLength << ") does not correspond to " + "header length (" << headerLength + << ") and trace length (" + << traceLength / 2 << "). Skipped a total of " + << numSkippedBuffers << " buffers in this file." << endl; + return vector(); + } else //Advance the buffer past the header and to the trace + buf += headerLength; + + if (traceLength > 0) { + DecodeTrace(buf, *data, traceLength); + buf += traceLength / 2; + } + events.push_back(data); + }// while(buf < bufStart + bufLen) + return events; +} + +std::pair XiaListModeDataDecoder::DecodeWordZero( + const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask) { + + data.SetChannelNumber(word & mask.GetChannelNumberMask().first); + data.SetSlotNumber((word & mask.GetSlotIdMask().first) + >> mask.GetSlotIdMask().second); + data.SetCrateNumber((word & mask.GetCrateIdMask().first) + >> mask.GetCrateIdMask().second); + data.SetPileup((word & mask.GetFinishCodeMask().first) != 0); + + //We have to check if we have one of these three firmwares since they + // have the Trace-Out-of-Range flag in this word. + switch(mask.GetFirmware()) { + case R17562: + case R20466: + case R27361: + data.SetSaturation((bool) + ((word & mask.GetTraceOutOfRangeFlagMask().first) + >> mask.GetTraceOutOfRangeFlagMask().second)); + break; + default: + break; + } + + return make_pair((word & mask.GetHeaderLengthMask().first) + >> mask.GetHeaderLengthMask().second, + (word & mask.GetEventLengthMask().first) + >> mask.GetEventLengthMask().second); +} + +void XiaListModeDataDecoder::DecodeWordTwo( + const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask) { + data.SetEventTimeHigh(word & mask.GetEventTimeHighMask().first); + data.SetCfdFractionalTime((word & mask.GetCfdFractionalTimeMask().first) + >> mask.GetCfdFractionalTimeMask().second); + data.SetCfdForcedTriggerBit( + (bool) ((word & mask.GetCfdForcedTriggerBitMask().first) + >> mask.GetCfdForcedTriggerBitMask().second)); + data.SetCfdTriggerSourceBit( + (bool) (word & mask.GetCfdTriggerSourceMask().first) + >> mask.GetCfdTriggerSourceMask().second); +} + +unsigned int XiaListModeDataDecoder::DecodeWordThree( + const unsigned int &word, XiaData &data, + const XiaListModeDataMask &mask) { + data.SetEnergy(word & mask.GetEventEnergyMask().first); + + //Reverse the logic that we used in DecodeWordZero, since if we do not + // have these three firmwares we need to check this word for the + // Trace-Out-of-Range flag. + switch(mask.GetFirmware()) { + case R17562: + case R20466: + case R27361: + break; + default: + data.SetSaturation((bool) + ((word & mask.GetTraceOutOfRangeFlagMask().first) + >> mask.GetTraceOutOfRangeFlagMask().second)); + break; + } + + return ((word & mask.GetTraceLengthMask().first) + >> mask.GetTraceLengthMask().second); +} + +void XiaListModeDataDecoder::DecodeTrace(unsigned int *buf, XiaData &data, + const unsigned int &traceLength) { + vector tmp; + // sbuf points to the beginning of trace data + unsigned short *sbuf = (unsigned short *) buf; + + // Read the trace data (2-bytes per sample, i.e. 2 samples per word) + for (unsigned int k = 0; k < traceLength; k++) + tmp.push_back((unsigned int &&) sbuf[k]); + + data.SetTrace(tmp); +} + +double XiaListModeDataDecoder::CalculateTimeInSamples( + const XiaListModeDataMask &mask, const XiaData &data) { + double filterTime = + data.GetEventTimeLow() + data.GetEventTimeHigh() * pow(2., 32); + + if (data.GetCfdFractionalTime() == 0 || data.GetCfdForcedTriggerBit()) + return filterTime; + + double cfdTime = 0, multiplier = 1; + if (mask.GetFrequency() == 100) + cfdTime = data.GetCfdFractionalTime() / mask.GetCfdSize(); + + if (mask.GetFrequency() == 250) { + multiplier = 2; + cfdTime = data.GetCfdFractionalTime() / mask.GetCfdSize() - + data.GetCfdTriggerSourceBit(); + } + + if (mask.GetFrequency() == 500) { + multiplier = 10; + cfdTime = data.GetCfdFractionalTime() / mask.GetCfdSize() + + data.GetCfdTriggerSourceBit() - 1; + } + + return filterTime * multiplier + cfdTime; +} + +double XiaListModeDataDecoder::CalculateTimeInNs( + const XiaListModeDataMask &mask, const XiaData &data) { + double conversionToNs = 1. / (mask.GetFrequency() * 1.e6); + return CalculateTimeInSamples(mask, data) * conversionToNs; +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/source/XiaListModeDataEncoder.cpp b/Analysis/ScanLibraries/source/XiaListModeDataEncoder.cpp new file mode 100644 index 000000000..bb402ddc8 --- /dev/null +++ b/Analysis/ScanLibraries/source/XiaListModeDataEncoder.cpp @@ -0,0 +1,154 @@ +/// @file XiaListModeDataEncoder.hpp +/// @brief Class that handles encoding Pixie-16 list mode data from a XiaData +/// class +/// @author S. V. Paulauskas +/// @date December 30, 2016 +#include +#include +#include + +#include + +#include "HelperEnumerations.hpp" +#include "XiaListModeDataEncoder.hpp" + +using namespace std; +using namespace DataProcessing; + +std::vector XiaListModeDataEncoder::EncodeXiaData( + const XiaData &data, + const FIRMWARE &firmware, + const unsigned int &frequency) { + if (data == XiaData()) + throw invalid_argument("XiaListModeDataEncoder::EncodeXiaData - We " + "received an empty XiaData structure."); + if (firmware == UNKNOWN) + throw invalid_argument("XiaListModeDataEncoder::EncodeXiaData - We " + "cannot encode against an UNKNOWN " + "firmware."); + if (frequency != 100 && frequency != 250 && frequency != 500) + throw invalid_argument("XiaListModeDataEncoder::EncodeXiaData - We " + "cannot encode against an unknown " + "frequency."); + vector header; + XiaListModeDataMask mask(firmware, frequency); + + header.push_back(EncodeWordZero(data, mask)); + header.push_back(EncodeWordOne(data,mask)); + header.push_back(EncodeWordTwo(data,mask)); + header.push_back(EncodeWordThree(data,mask)); + + //The following calls are required in this order due to the structure of + // the XIA list mode data format. + if(data.GetEnergySums().size() != 0) { + vector tmp = EncodeEsums(data, mask); + header.insert(header.end(), tmp.begin(), tmp.end()); + } + + ///Each QDC value takes up a single 32-bit word. No need to do anything + /// special here. + if(data.GetQdc().size() != 0) { + for(unsigned int i = 0; i < data.GetQdc().size(); i++) + header.push_back((unsigned int &&)data.GetQdc().at(i)); + } + + if(data.GetExternalTimeLow() != 0) { + //The External timestamps work essentially the same as the internal time + // stamps in terms of the structure. The major difference here is that + // the upper bits of the high word are all zero. No special + // processing needed in this case. + header.push_back(data.GetExternalTimeLow()); + header.push_back(data.GetExternalTimeHigh()); + } + + ///Trace comes last since it comes after the header. + if(data.GetTrace().size() != 0) { + vector tmp = EncodeTrace(data.GetTrace(), + mask.GetTraceMask()); + header.insert(header.end(), tmp.begin(), tmp.end()); + } + + return header; +} + +unsigned int XiaListModeDataEncoder::EncodeWordZero( + const XiaData &data, const XiaListModeDataMask &mask) { + //These magic numbers are dependent upon the XIA List Mode Data Structure. + // For more information about them please consult the relevant + // documentation. + unsigned int headerLength = 4; + if (data.GetExternalTimeLow() != 0) + headerLength += 2; + if (data.GetEnergySums().size() != 0) + headerLength += 4; + if (data.GetQdc().size() != 0) + headerLength += 8; + unsigned int eventLength = + (unsigned int)ceil(data.GetTrace().size() * 0.5) + headerLength; + + unsigned int word = 0; + word |= data.GetChannelNumber() & mask.GetChannelNumberMask().first; + word |= (data.GetSlotNumber() << mask.GetSlotIdMask().second) & + mask.GetSlotIdMask().first; + word |= (data.GetCrateNumber() << mask.GetCrateIdMask().second) & + mask.GetCrateIdMask().first; + word |= (headerLength << mask.GetHeaderLengthMask().second) & + mask.GetHeaderLengthMask().first; + word |= (eventLength << mask.GetEventLengthMask().second) & + mask.GetEventLengthMask().first; + word |= (data.IsPileup() << mask.GetFinishCodeMask().second) & + mask.GetFinishCodeMask().first; + return word; +} + +unsigned int XiaListModeDataEncoder::EncodeWordOne( + const XiaData &data, const XiaListModeDataMask &mask) { + return data.GetEventTimeLow(); +} + +unsigned int XiaListModeDataEncoder::EncodeWordTwo( + const XiaData &data, const XiaListModeDataMask &mask){ + unsigned int word = 0; + word |= data.GetEventTimeHigh() & mask.GetEventTimeHighMask().first; + word |= (data.GetCfdFractionalTime() << mask.GetCfdFractionalTimeMask().second) & + mask.GetCfdFractionalTimeMask().first; + word |= (data.GetCfdForcedTriggerBit() << mask.GetCfdForcedTriggerBitMask() + .second) & mask.GetCfdForcedTriggerBitMask().first; + word |= (data.GetCfdTriggerSourceBit() << mask.GetCfdTriggerSourceMask().second) & + mask.GetCfdTriggerSourceMask().first; + return word; +} + +unsigned int XiaListModeDataEncoder::EncodeWordThree( + const XiaData &data, const XiaListModeDataMask &mask){ + unsigned int word = 0; + word |= (unsigned int) data.GetEnergy() & mask.GetEventEnergyMask().first; + word |= (data.IsSaturated() << mask.GetTraceOutOfRangeFlagMask() + .second) & mask.GetTraceOutOfRangeFlagMask().first; + word |= (data.GetTrace().size() << mask.GetTraceLengthMask().second) & + mask.GetTraceLengthMask().first; + return word; +} + +vector XiaListModeDataEncoder::EncodeTrace( + const std::vector &trc, const std::pair &mask){ + vector tmp; + for(vector::const_iterator it = trc.begin(); + it != trc.end(); it+=2) { + vector::const_iterator next = it + 1; + unsigned int word = 0; + word |= *it; + if(next != trc.end()) + word |= *next << mask.second; + tmp.push_back(word); + } + return tmp; +} + +///@TODO This needs to be updated so that it actually formats the baseline in +/// one of the IEEE standard formats properly before we return. +vector XiaListModeDataEncoder::EncodeEsums( + const XiaData &data, const XiaListModeDataMask &mask){ + return data.GetEnergySums(); +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/source/XiaListModeDataMask.cpp b/Analysis/ScanLibraries/source/XiaListModeDataMask.cpp new file mode 100644 index 000000000..309b22254 --- /dev/null +++ b/Analysis/ScanLibraries/source/XiaListModeDataMask.cpp @@ -0,0 +1,350 @@ +/// @file XiaListModeDataMask.cpp +/// @brief Class that provides the data masks for XIA list mode data +/// @author S. V. Paulauskas +/// @date December 29, 2016 +#include +#include +#include + +#include "XiaListModeDataMask.hpp" + +using namespace std; +using namespace DataProcessing; + +FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { + FIRMWARE firmware = UNKNOWN; + unsigned int firmwareNumber = 0; + stringstream msg; + + //First convert the string into a number + if (type.find("R") == 0 || type.find("r") == 0) { + string tmp(type.begin() + 1, type.end()); + firmwareNumber = (unsigned int) atoi(tmp.c_str()); + } else + firmwareNumber = (unsigned int) atoi(type.c_str()); + + if (firmwareNumber >= 17562 && firmwareNumber < 20466) + firmware = R17562; + else if (firmwareNumber >= 20466 && firmwareNumber < 27361) + firmware = R20466; + else if (firmwareNumber >= 27361 && firmwareNumber < 29432) + firmware = R27361; + else if (firmwareNumber >= 29432 && firmwareNumber < 30474) + firmware = R29432; + else if (firmwareNumber >= 30474 && firmwareNumber < 30980) + firmware = R30474; + else if (firmwareNumber >= 30980 && firmwareNumber < 30981) + firmware = R30980; + else if (firmwareNumber >= 30981 && firmwareNumber < 34688) + firmware = R30981; + else if (firmwareNumber == + 34688) //compare exactly here since nothing higher + firmware = R34688; + else { + msg << "XiaListModeDataMask::CovnertStringToFirmware : " + << "Unrecognized firmware option - " << type << endl; + throw invalid_argument(msg.str()); + } + return firmware; +} + +///The CFD Fractional Time always starts on bit 16 of Word 2. The range of +/// this value changes. +pair +XiaListModeDataMask::GetCfdFractionalTimeMask() const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R17562: + case R29432: + mask = 0xFFFF0000; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x7FFF0000; + break; + default: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R20466: + mask = 0xFFFF0000; + break; + case R27361: + case R29432: + mask = 0x7FFF0000; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x3FFF0000; + break; + default: + break; + } + } else if (frequency_ == 500) { + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x1FFF0000; + break; + default: + break; + } + } + return make_pair(mask, 16); +} + +std::pair XiaListModeDataMask::GetEventLengthMask() +const { + if(firmware_ == UNKNOWN) + throw invalid_argument(BadMaskErrorMessage("GetEventLengthMask")); + unsigned int mask = 0; + unsigned int bit = 0; + switch(firmware_) { + case R17562: + case R20466: + case R27361: + mask = 0x3FFE0000; + bit = 17; + break; + case R29432: + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x7FFE0000; + bit = 17; + break; + default: + break; + } + return make_pair(mask, bit); +} + +pair +XiaListModeDataMask::GetCfdForcedTriggerBitMask() const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdForcedTriggerBitMask")); + unsigned int mask = 0; + unsigned int bit = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x80000000; + bit = 31; + break; + default: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x80000000; + bit = 31; + break; + default: + break; + } + } + return make_pair(mask, bit); +} + +pair +XiaListModeDataMask::GetCfdTriggerSourceMask() const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdTriggerSourceMask")); + unsigned int mask = 0; + unsigned int bit = 0; + if (frequency_ == 250) { + switch (firmware_) { + case R27361: + case R29432: + mask = 0x80000000; + bit = 31; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x40000000; + bit = 30; + break; + default: + break; + } + } else if (frequency_ == 500) { + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0xE0000000; + bit = 29; + break; + default: + break; + } + } + return make_pair(mask, bit); +} + +/// The energy always starts out on Bit 0 of Word 3 so we do not need to +/// define a variable for the bit. +pair XiaListModeDataMask::GetEventEnergyMask() +const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetEventEnergyMask")); + unsigned int mask = 0; + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0x00007FFF; + break; + case R17562: + case R20466: + case R27361: + case R34688: + mask = 0x0000FFFF; + break; + default: + break; + } + return make_pair(mask, 0); +} + +//The Trace-out-of-range flag moves around on us. For most revisions it on +// bit 15 of Word 3, but for the most recent firmware its been moved to bit 31. +pair +XiaListModeDataMask::GetTraceOutOfRangeFlagMask() const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetTraceOutOfRangeFlagMask")); + + unsigned int mask = 0; + unsigned int bit = 0; + switch (firmware_) { + case R17562: + case R20466: + case R27361: + mask = 0x40000000; + bit = 30; + break; + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0x00008000; + bit = 15; + break; + case R34688: + mask = 0x80000000; + bit = 31; + break; + default: + break; + } + return make_pair(mask, bit); +} + +//Trace Length always starts on bit 16 of Word 3. +pair XiaListModeDataMask::GetTraceLengthMask() +const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetTraceLengthMask")); + unsigned int mask = 0; + switch (firmware_) { + case R17562: + case R20466: + case R27361: + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0xFFFF0000; + break; + case R34688: + mask = 0x7FFF0000; + break; + default: + break; + } + return make_pair(mask, 16); +} + +string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) const { + stringstream msg; + msg << "XiaListModeDataMask::" << func << " : " + << "Could not obtain a mask for firmware code " << firmware_ + << " and frequency " << frequency_ << ". Check your settings."; + return msg.str(); +} + +double XiaListModeDataMask::GetCfdSize() const { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdSize")); + if (frequency_ == 500) + return 8192.; + + double val = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R17562: + case R29432: + val = 65536; + break; + case R30474: + case R30980: + case R30981: + case R34688: + val = 32768; + break; + default: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R20466: + val = 65536; + break; + case R27361: + case R29432: + val = 32768; + break; + case R30980: + case R30981: + case R34688: + case R30474: + val = 16384; + break; + default: + break; + } + } + + return val; +} diff --git a/Analysis/ScanLibraries/tests/CMakeLists.txt b/Analysis/ScanLibraries/tests/CMakeLists.txt new file mode 100644 index 000000000..f4ac7581a --- /dev/null +++ b/Analysis/ScanLibraries/tests/CMakeLists.txt @@ -0,0 +1,26 @@ +add_executable(unittest-XiaListModeDataDecoder + unittest-XiaListModeDataDecoder.cpp + ../source/XiaData.cpp + ../source/XiaListModeDataDecoder.cpp + ../source/XiaListModeDataMask.cpp) +target_link_libraries(unittest-XiaListModeDataDecoder UnitTest++ ${LIBS}) +install(TARGETS unittest-XiaListModeDataDecoder DESTINATION bin/unittests) + +add_executable(unittest-XiaListModeDataEncoder + unittest-XiaListModeDataEncoder.cpp + ../source/XiaData.cpp + ../source/XiaListModeDataEncoder.cpp + ../source/XiaListModeDataMask.cpp) +target_link_libraries(unittest-XiaListModeDataEncoder UnitTest++ ${LIBS}) +install(TARGETS unittest-XiaListModeDataEncoder DESTINATION bin/unittests) + +add_executable(unittest-XiaListModeDataMask + unittest-XiaListModeDataMask.cpp + ../source/XiaData.cpp + ../source/XiaListModeDataMask.cpp) +target_link_libraries(unittest-XiaListModeDataMask UnitTest++ ${LIBS}) +install(TARGETS unittest-XiaListModeDataMask DESTINATION bin/unittests) + +add_executable(unittest-XiaData unittest-XiaData.cpp ../source/XiaData.cpp) +target_link_libraries(unittest-XiaData UnitTest++ ${LIBS}) +install(TARGETS unittest-XiaData DESTINATION bin/unittests) \ No newline at end of file diff --git a/Analysis/ScanLibraries/tests/unittest-XiaData.cpp b/Analysis/ScanLibraries/tests/unittest-XiaData.cpp new file mode 100644 index 000000000..55053acc0 --- /dev/null +++ b/Analysis/ScanLibraries/tests/unittest-XiaData.cpp @@ -0,0 +1,168 @@ +///@file unittest-XiaData.cpp +///@brief A program that will execute unit tests on XiaData +///@author S. V. Paulauskas +///@date December 5, 2016 +#include + +#include + +#include + +#include "UnitTestSampleData.hpp" +#include "XiaData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_decoded_data; + +XiaData lhs, rhs; + +TEST_FIXTURE(XiaData, Test_GetBaseline) { + SetBaseline(baseline); + CHECK_EQUAL(baseline, GetBaseline()); +} + +TEST_FIXTURE(XiaData, Test_GetId) { + SetSlotNumber(slotId); + SetChannelNumber(channelNumber); + SetCrateNumber(crateId); + CHECK_EQUAL(crateId * 208 + GetModuleNumber() * 16 + + channelNumber, GetId()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdForcedTrig) { + SetCfdForcedTriggerBit(cfd_forced_trigger); + CHECK(GetCfdForcedTriggerBit()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdFractionalTime) { + SetCfdFractionalTime(cfd_fractional_time); + CHECK_EQUAL(cfd_fractional_time, GetCfdFractionalTime()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdTriggerSourceBit) { + SetCfdTriggerSourceBit(cfd_source_trigger_bit); + CHECK(GetCfdTriggerSourceBit()); +} + +TEST_FIXTURE(XiaData, Test_GetSetChannelNumber) { + SetChannelNumber(channelNumber); + CHECK_EQUAL(channelNumber, GetChannelNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCrateNumber) { + SetCrateNumber(crateId); + CHECK_EQUAL(crateId, GetCrateNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEnergy) { + SetEnergy(energy); + CHECK_EQUAL(energy, GetEnergy()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEnergySums) { + SetEnergySums(energy_sums); + CHECK_ARRAY_EQUAL(energy_sums, GetEnergySums(), + energy_sums.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEventTimeHigh) { + SetEventTimeHigh(ts_high); + CHECK_EQUAL(ts_high, GetEventTimeHigh()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEventTimeLow) { + SetEventTimeLow(ts_low); + CHECK_EQUAL(ts_low, GetEventTimeLow()); +} + +TEST_FIXTURE(XiaData, Test_GetSetExternalTimeHigh) { + SetExternalTimeHigh(ex_ts_high); + CHECK_EQUAL(ex_ts_high, GetExternalTimeHigh()); +} + +TEST_FIXTURE(XiaData, Test_GetSetExternalTimeLow) { + SetExternalTimeLow(ex_ts_low); + CHECK_EQUAL(ex_ts_low, GetExternalTimeLow()); +} + +TEST_FIXTURE(XiaData, Test_GetSetPileup) { + SetPileup(pileup_bit); + CHECK(IsPileup()); +} + +TEST_FIXTURE(XiaData, Test_GetSetQdc) { + SetQdc(qdc); + CHECK_ARRAY_EQUAL(qdc, GetQdc(), qdc.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetSaturation) { + SetSaturation(trace_out_of_range); + CHECK(IsSaturated()); +} + +TEST_FIXTURE(XiaData, Test_GetSetSlotNumber) { + SetSlotNumber(slotId); + CHECK_EQUAL(slotId, GetSlotNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetTrace) { + SetTrace(trace); + CHECK_ARRAY_EQUAL(trace, GetTrace(), trace.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetVirtualChannel) { + SetVirtualChannel(virtual_channel); + CHECK(IsVirtualChannel()); +} + +TEST_FIXTURE(XiaData, Test_GetTime) { + SetTime(ts); + CHECK_EQUAL(ts, GetTime()); +} + +///This will test that the Time for the rhs is greater than the lhs +TEST(Test_CompareTime){ + lhs.Clear(); rhs.Clear(); + + lhs.SetTime(ts); + rhs.SetTime(ts+10); + + CHECK(lhs.CompareTime(&lhs, &rhs)); +} + +//This will test that the ID for the rhs is greater than the lhs +TEST(Test_CompareId) { + lhs.Clear(); rhs.Clear(); + lhs.SetChannelNumber(channelNumber); + lhs.SetSlotNumber(slotId); + lhs.SetCrateNumber(crateId); + + rhs.SetChannelNumber(channelNumber); + rhs.SetSlotNumber(slotId+2); + rhs.SetCrateNumber(crateId); + + CHECK(lhs.CompareId(&lhs, &rhs)); +} + +TEST(Test_Equality) { + lhs.Clear(); rhs.Clear(); + lhs.SetChannelNumber(channelNumber); + lhs.SetSlotNumber(slotId); + lhs.SetCrateNumber(crateId); + rhs = lhs; + CHECK(lhs == rhs); +} + +TEST(Test_LessThanOperator) { + lhs.Clear(); rhs.Clear(); + lhs.SetTime(ts); + rhs = lhs; + rhs.SetTime(ts+10); + CHECK(lhs < rhs); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} + diff --git a/Analysis/ScanLibraries/tests/unittest-XiaListModeDataDecoder.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataDecoder.cpp new file mode 100644 index 000000000..50d3dbdf8 --- /dev/null +++ b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataDecoder.cpp @@ -0,0 +1,76 @@ +///@file unittest-XiaListModeDataDecoder.cpp +///@brief Unit tests for the XiaListModeDataDecoder class +///@author S. V. Paulauskas +///@author December 25, 2016 +#include + +#include + +#include "HelperEnumerations.hpp" +#include "UnitTestSampleData.hpp" +#include "XiaListModeDataDecoder.hpp" + +using namespace std; +using namespace DataProcessing; +using namespace unittest_encoded_data; +using namespace unittest_decoded_data; + +///@TODO These need to be expanded so that we cover all of the nine different +/// firmware and frequency combinations. +static const XiaListModeDataMask mask(R30474, 250); +using namespace unittest_encoded_data::R30474_250; + +//Test the error handling in the class +TEST_FIXTURE(XiaListModeDataDecoder, TestBufferLengthChecks) { + //Check that we throw a length error when the buffer length is zero + CHECK_THROW(DecodeBuffer(&empty_buffer[0], mask), length_error); + //Check that we return an empty vector when we have an empty module + CHECK_EQUAL(empty_buffer[1], + DecodeBuffer(&empty_module_buffer[0], mask).size()); +} +///Test if we can decode a simple 4 word header that includes the Pixie +/// Module Data Header. +TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { + //Check that we get an empty vector when the header has an impossible size. + CHECK_EQUAL((unsigned int)0, + DecodeBuffer(&header_w_bad_headerlen[0], mask).size()); + + //Check that we can decode a simple 4-word header. + XiaData result_data = *(DecodeBuffer(&header[0], mask).front()); + + CHECK_EQUAL(slotId, result_data.GetSlotNumber()); + CHECK_EQUAL(channelNumber, result_data.GetChannelNumber()); + CHECK_EQUAL(energy, result_data.GetEnergy()); + CHECK_EQUAL(ts_high, result_data.GetEventTimeHigh()); + CHECK_EQUAL(ts_low, result_data.GetEventTimeLow()); + CHECK_EQUAL(ts, result_data.GetTime()); +} + +//Test if we can decode a trace properly +TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { + //Testing that we return an empty event list. + CHECK_EQUAL((unsigned int)0, + DecodeBuffer(&header_w_bad_eventlen[0], mask).size()); + + XiaData result = *(DecodeBuffer(&header_N_trace[0], mask).front()); + CHECK_ARRAY_EQUAL(unittest_trace_variables::trace, result.GetTrace(), + unittest_trace_variables::trace.size()); +} + +//Test if we can decode the qdc properly +TEST_FIXTURE(XiaListModeDataDecoder, TestQdcDecoding) { + XiaData result = *(DecodeBuffer(&header_N_qdc[0], mask).front()); + CHECK_ARRAY_EQUAL(qdc, result.GetQdc(), qdc.size()); +} + +//Test that we can get the right timestamp if we involve the CFD. +TEST_FIXTURE(XiaListModeDataDecoder, TestCfdTimeCalculation) { + XiaData result = *(DecodeBuffer(&header_N_Cfd[0], mask).front()); + CHECK_EQUAL(cfd_fractional_time, result.GetCfdFractionalTime()); + CHECK_CLOSE(ts_w_cfd, result.GetTime(), 1e-5); +} + + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/tests/unittest-XiaListModeDataEncoder.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataEncoder.cpp new file mode 100644 index 000000000..e85e64dbe --- /dev/null +++ b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataEncoder.cpp @@ -0,0 +1,65 @@ +///@file unittest-XiaListModeDataEncoder.cpp +///@brief Unit tests for the XiaListModeDataDecoder class +///@author S. V. Paulauskas +///@author December 25, 2016 +#include + +#include + +#include "HelperEnumerations.hpp" +#include "UnitTestSampleData.hpp" +#include "XiaListModeDataEncoder.hpp" + +using namespace std; +using namespace DataProcessing; +using namespace unittest_encoded_data; +using namespace unittest_decoded_data; +using namespace unittest_encoded_data::R30474_250; + +TEST_FIXTURE(XiaListModeDataEncoder, TestEncodingThrows) { + //Check that we throw a range error when we pass an empty XiaData class + CHECK_THROW(EncodeXiaData(XiaData(), R30474, 250), invalid_argument); + + //Check that we catch an invalid_argument when we pass a bogus firmware + CHECK_THROW(EncodeXiaData(XiaData(), UNKNOWN, 250), invalid_argument); + + //Check that we catch an invalid_argument when we pass a bogus frequency + CHECK_THROW(EncodeXiaData(XiaData(), R30474, 2500), invalid_argument); +} + +///Test if we can encode some headers with different information. +///@TODO Add headers for Esums and external TS. +TEST_FIXTURE(XiaListModeDataEncoder, TestSimpleHeaderEncoding) { + XiaData data; + data.SetEnergy(energy); + data.SetSlotNumber(slotId); + data.SetChannelNumber(channelNumber); + data.SetCrateNumber(crateId); + data.SetEventTimeLow(ts_low); + data.SetEventTimeHigh(ts_high); + + //Check that we can handle just a simple 4 word header + CHECK_ARRAY_EQUAL(header_vec, EncodeXiaData(data, R30474, 250), + header_vec.size()); + + //Check that we can handle a header with a trace + data.SetTrace(unittest_trace_variables::trace); + CHECK_ARRAY_EQUAL(header_vec_w_trc, EncodeXiaData(data, R30474, 250), + header_vec_w_trc.size()); + + //Check that we can handle a QDC + data.SetQdc(qdc); + data.SetTrace(vector()); + CHECK_ARRAY_EQUAL(header_vec_w_qdc, EncodeXiaData(data, R30474, 250), + header_vec_w_qdc.size()); + + //Check that we can handle a QDC and a Trace + data.SetQdc(qdc); + data.SetTrace(unittest_trace_variables::trace); + CHECK_ARRAY_EQUAL(header_vec_w_qdc_n_trc, EncodeXiaData(data, R30474, 250), + header_vec_w_qdc_n_trc.size()); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/ScanLibraries/tests/unittest-XiaListModeDataMask.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataMask.cpp new file mode 100644 index 000000000..04ae447b5 --- /dev/null +++ b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataMask.cpp @@ -0,0 +1,238 @@ +///@file unittest-XiaListModeDataMask.cpp +///@brief Unit testing of the XiaListModeDataMask class +///@author S. V. Paulauskas +///@date December 29, 2016 +#include +#include + +#include + +#include "HelperEnumerations.hpp" +#include "XiaListModeDataMask.hpp" + +using namespace std; +using namespace DataProcessing; + +//Test that we can convert all the firmware names to the right values. +TEST_FIXTURE(XiaListModeDataMask, TestConvertStringToFirmware) { + //Check the exact names. + CHECK_EQUAL(R17562, ConvertStringToFirmware("R17562")); + CHECK_EQUAL(R17562, ConvertStringToFirmware("17562")); + + CHECK_EQUAL(R20466, ConvertStringToFirmware("R20466")); + CHECK_EQUAL(R20466, ConvertStringToFirmware("20466")); + + CHECK_EQUAL(R27361, ConvertStringToFirmware("R27361")); + CHECK_EQUAL(R27361, ConvertStringToFirmware("27361")); + + CHECK_EQUAL(R29432, ConvertStringToFirmware("R29432")); + CHECK_EQUAL(R29432, ConvertStringToFirmware("29432")); + + CHECK_EQUAL(R30474, ConvertStringToFirmware("R30474")); + CHECK_EQUAL(R30474, ConvertStringToFirmware("30474")); + + CHECK_EQUAL(R30980, ConvertStringToFirmware("R30980")); + CHECK_EQUAL(R30980, ConvertStringToFirmware("30980")); + + CHECK_EQUAL(R30981, ConvertStringToFirmware("R30981")); + CHECK_EQUAL(R30981, ConvertStringToFirmware("30981")); + + CHECK_EQUAL(R34688, ConvertStringToFirmware("R34688")); + CHECK_EQUAL(R34688, ConvertStringToFirmware("34688")); + + //Check values in between numbers + CHECK_EQUAL(R17562, ConvertStringToFirmware("19000")); + CHECK_EQUAL(R20466, ConvertStringToFirmware("23000")); + CHECK_EQUAL(R27361, ConvertStringToFirmware("28000")); + CHECK_EQUAL(R29432, ConvertStringToFirmware("29700")); + CHECK_EQUAL(R30474, ConvertStringToFirmware("30670")); + CHECK_EQUAL(R30981, ConvertStringToFirmware("32000")); + + //Two cases for absolute failure of the method is when we have a firmware + // version that is higher than the highest known one, and a version + // smaller than the smallest known version. + CHECK_THROW(ConvertStringToFirmware("45000"), invalid_argument); + CHECK_THROW(ConvertStringToFirmware("12"), invalid_argument); +} + +TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { + //We do not need to test more than on version of these since they are + // identical across all firmware versions. + SetFirmware(R30474); + CHECK_EQUAL((unsigned int) 0x0000000F, GetChannelNumberMask().first); + CHECK_EQUAL((unsigned int) 0, GetChannelNumberMask().second); + + CHECK_EQUAL((unsigned int) 0x000000F0, GetSlotIdMask().first); + CHECK_EQUAL((unsigned int) 4, GetSlotIdMask().second); + + CHECK_EQUAL((unsigned int) 0x00000F00, GetCrateIdMask().first); + CHECK_EQUAL((unsigned int) 8, GetCrateIdMask().second); + + CHECK_EQUAL((unsigned int) 0x0001F000, GetHeaderLengthMask().first); + CHECK_EQUAL((unsigned int) 12, GetHeaderLengthMask().second); + + CHECK_EQUAL((unsigned int) 0x80000000, GetFinishCodeMask().first); + CHECK_EQUAL((unsigned int) 31, GetFinishCodeMask().second); + + CHECK_EQUAL((unsigned int) 0x0000FFFF, GetEventTimeHighMask().first); + CHECK_EQUAL((unsigned int) 0, GetEventTimeHighMask().second); +} + +///Tests for the 100 MHz versions +TEST_FIXTURE(XiaListModeDataMask, Test_100MSps_Word2) { + SetFrequency(100); + + SetFirmware(R29432); + CHECK_EQUAL((unsigned int) 0xFFFF0000, GetCfdFractionalTimeMask().first); + CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); + + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().first); + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().second); + + CHECK_EQUAL((unsigned int) 0, GetCfdTriggerSourceMask().first); + CHECK_EQUAL((unsigned int) 0, GetCfdTriggerSourceMask().second); + + vector firm = {R30474, R30980, R30981, R34688}; + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL((unsigned int) 0x7FFF0000, + GetCfdFractionalTimeMask().first); + CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); + + CHECK_EQUAL((unsigned int) 0x80000000, + GetCfdForcedTriggerBitMask().first); + CHECK_EQUAL((unsigned int) 31, GetCfdForcedTriggerBitMask().second); + + CHECK_EQUAL((unsigned int) 0, GetCfdTriggerSourceMask().first); + CHECK_EQUAL((unsigned int) 0, GetCfdTriggerSourceMask().second); + } +} + +///Tests for the 250 MHz versions +TEST_FIXTURE(XiaListModeDataMask, Test_250Msps_Word2) { + SetFrequency(250); + + SetFirmware(R29432); + CHECK_EQUAL((unsigned int) 0x7FFF0000, GetCfdFractionalTimeMask().first); + CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); + + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().first); + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().second); + + CHECK_EQUAL((unsigned int) 0x80000000, GetCfdTriggerSourceMask().first); + CHECK_EQUAL((unsigned int) 31, GetCfdTriggerSourceMask().second); + + vector firm = {R30474, R30980, R30981, R34688}; + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL((unsigned int) 0x3FFF0000, + GetCfdFractionalTimeMask().first); + CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); + + CHECK_EQUAL((unsigned int) 0x80000000, + GetCfdForcedTriggerBitMask().first); + CHECK_EQUAL((unsigned int) 31, GetCfdForcedTriggerBitMask().second); + + CHECK_EQUAL((unsigned int) 0x40000000, GetCfdTriggerSourceMask().first); + CHECK_EQUAL((unsigned int) 30, GetCfdTriggerSourceMask().second); + } +} + +///Tests for the 500 MHz versions +TEST_FIXTURE(XiaListModeDataMask, Test_500MSps_Word2) { + SetFrequency(500); + + vector firm = {R29432, R30474, R30980, R30981, R34688}; + + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL((unsigned int) 0x1FFF0000, + GetCfdFractionalTimeMask().first); + CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); + + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().first); + CHECK_EQUAL((unsigned int) 0, GetCfdForcedTriggerBitMask().second); + + CHECK_EQUAL((unsigned int) 0xE0000000, GetCfdTriggerSourceMask().first); + CHECK_EQUAL((unsigned int) 29, GetCfdTriggerSourceMask().second); + } +} + +TEST_FIXTURE(XiaListModeDataMask, Test_R29432_To_R30981_Word3) { + vector freq = {100, 250, 500}; + + vector firm = {R29432, R30474, R30980, R30981}; + + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + for (vector::iterator it1 = freq.begin(); + it1 != freq.end(); it1++) { + SetFrequency(*it1); + CHECK_EQUAL((unsigned int) 0x00007FFF, GetEventEnergyMask().first); + CHECK_EQUAL((unsigned int) 0, GetEventEnergyMask().second); + + CHECK_EQUAL((unsigned int) 0x00008000, + GetTraceOutOfRangeFlagMask().first); + CHECK_EQUAL((unsigned int) 15, GetTraceOutOfRangeFlagMask().second); + + CHECK_EQUAL((unsigned int) 0xFFFF0000, GetTraceLengthMask().first); + CHECK_EQUAL((unsigned int) 16, GetTraceLengthMask().second); + } + } +} + +TEST_FIXTURE(XiaListModeDataMask, Test_R34688_Word3) { + SetFirmware(R34688); + vector freq = {100, 250, 500}; + for (vector::iterator it = freq.begin(); + it != freq.end(); it++) { + SetFrequency(*it); + CHECK_EQUAL((unsigned int) 0x0000FFFF, GetEventEnergyMask().first); + CHECK_EQUAL((unsigned int) 0, GetEventEnergyMask().second); + + CHECK_EQUAL((unsigned int) 0x80000000, + GetTraceOutOfRangeFlagMask().first); + CHECK_EQUAL((unsigned int) 31, GetTraceOutOfRangeFlagMask().second); + + CHECK_EQUAL((unsigned int) 0x7FFF0000, GetTraceLengthMask().first); + CHECK_EQUAL((unsigned int) 16, GetTraceLengthMask().second); + } +} + +TEST_FIXTURE(XiaListModeDataMask, Test_Cfd_Size_Mask) { + //This firmware has a unique CFD size. + SetFirmware(R29432); + SetFrequency(100); + CHECK_EQUAL(65536, GetCfdSize()); + //This firmware has a different format for the 250 MS/s + SetFrequency(250); + CHECK_EQUAL(32768, GetCfdSize()); + + + //All of the 500 MS/s modules have the same sized CFD. + SetFrequency(500); + vector firm = {R29432, R30474, R30980, R30981, R34688}; + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL(8192, GetCfdSize()); + } + + //The 100 MHz and 250 MS/s revisions have the same structure for the + // following four firmwares + firm = {R30474, R30980, R30981, R34688}; + SetFrequency(100); + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL(32768, GetCfdSize()); + } + + SetFrequency(250); + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + SetFirmware(*it); + CHECK_EQUAL(16384, GetCfdSize()); + } +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/ScanLib/CMakeLists.txt b/Analysis/Scanor/CMakeLists.txt similarity index 100% rename from Scan/ScanLib/CMakeLists.txt rename to Analysis/Scanor/CMakeLists.txt diff --git a/Scan/scanor/include/GetArguments.hpp b/Analysis/Scanor/include/GetArguments.hpp similarity index 100% rename from Scan/scanor/include/GetArguments.hpp rename to Analysis/Scanor/include/GetArguments.hpp diff --git a/Scan/scanor/include/Scanor.hpp b/Analysis/Scanor/include/Scanor.hpp similarity index 100% rename from Scan/scanor/include/Scanor.hpp rename to Analysis/Scanor/include/Scanor.hpp diff --git a/Scan/scanor/include/ScanorInterface.hpp b/Analysis/Scanor/include/ScanorInterface.hpp similarity index 100% rename from Scan/scanor/include/ScanorInterface.hpp rename to Analysis/Scanor/include/ScanorInterface.hpp diff --git a/Scan/scanor/source/CMakeLists.txt b/Analysis/Scanor/source/CMakeLists.txt similarity index 100% rename from Scan/scanor/source/CMakeLists.txt rename to Analysis/Scanor/source/CMakeLists.txt diff --git a/Scan/scanor/source/GetArguments.cpp b/Analysis/Scanor/source/GetArguments.cpp similarity index 100% rename from Scan/scanor/source/GetArguments.cpp rename to Analysis/Scanor/source/GetArguments.cpp diff --git a/Scan/scanor/source/Scanor.cpp b/Analysis/Scanor/source/Scanor.cpp similarity index 100% rename from Scan/scanor/source/Scanor.cpp rename to Analysis/Scanor/source/Scanor.cpp diff --git a/Scan/scanor/source/ScanorInterface.cpp b/Analysis/Scanor/source/ScanorInterface.cpp similarity index 100% rename from Scan/scanor/source/ScanorInterface.cpp rename to Analysis/Scanor/source/ScanorInterface.cpp diff --git a/Scan/scanor/source/messlog.f b/Analysis/Scanor/source/messlog.f similarity index 100% rename from Scan/scanor/source/messlog.f rename to Analysis/Scanor/source/messlog.f diff --git a/Scan/scanor/source/mildatim.f b/Analysis/Scanor/source/mildatim.f similarity index 100% rename from Scan/scanor/source/mildatim.f rename to Analysis/Scanor/source/mildatim.f diff --git a/Scan/scanor/source/scanof.f b/Analysis/Scanor/source/scanof.f similarity index 100% rename from Scan/scanor/source/scanof.f rename to Analysis/Scanor/source/scanof.f diff --git a/Scan/scanor/source/scanor.f b/Analysis/Scanor/source/scanor.f similarity index 100% rename from Scan/scanor/source/scanor.f rename to Analysis/Scanor/source/scanor.f diff --git a/Scan/scanor/source/scanorux.f b/Analysis/Scanor/source/scanorux.f similarity index 100% rename from Scan/scanor/source/scanorux.f rename to Analysis/Scanor/source/scanorux.f diff --git a/Scan/scanor/source/set2cc.f b/Analysis/Scanor/source/set2cc.f similarity index 100% rename from Scan/scanor/source/set2cc.f rename to Analysis/Scanor/source/set2cc.f diff --git a/Scan/util/CMakeLists.txt b/Analysis/Utilities/CMakeLists.txt similarity index 100% rename from Scan/util/CMakeLists.txt rename to Analysis/Utilities/CMakeLists.txt diff --git a/Scan/util/include/Skeleton.hpp b/Analysis/Utilities/include/Skeleton.hpp similarity index 100% rename from Scan/util/include/Skeleton.hpp rename to Analysis/Utilities/include/Skeleton.hpp diff --git a/Scan/util/include/filterer.hpp b/Analysis/Utilities/include/filterer.hpp similarity index 100% rename from Scan/util/include/filterer.hpp rename to Analysis/Utilities/include/filterer.hpp diff --git a/Scan/util/include/scope.hpp b/Analysis/Utilities/include/scope.hpp similarity index 92% rename from Scan/util/include/scope.hpp rename to Analysis/Utilities/include/scope.hpp index d4144a79e..c2151eed4 100644 --- a/Scan/util/include/scope.hpp +++ b/Analysis/Utilities/include/scope.hpp @@ -7,13 +7,11 @@ #include #include -// PixieCore libraries #include "Unpacker.hpp" -#include "ScanInterface.hpp" + +#include "RootScanner.hpp" class ChannelEvent; -class TApplication; -class TCanvas; class TGraph; class TH2F; class TF1; @@ -72,7 +70,7 @@ class scopeUnpacker : public Unpacker { // class scopeScanner /////////////////////////////////////////////////////////////////////////////// -class scopeScanner : public ScanInterface { +class scopeScanner : public RootScanner { public: /// Default constructor. scopeScanner(int mod = 0, int chan = 0); @@ -137,14 +135,6 @@ class scopeScanner : public ScanInterface { */ virtual void SyntaxStr(char *name_); - /** IdleTask is called whenever a scan is running in shared - * memory mode, and a spill has yet to be received. This method may - * be used to update things which need to be updated every so often - * (e.g. a root TCanvas) when working with a low data rate. - * \return Nothing. - */ - virtual void IdleTask(); - /** Initialize the map file, the config file, the processor handler, * and add all of the required processors. * \param[in] prefix_ String to append to the beginning of system output. @@ -223,11 +213,10 @@ class scopeScanner : public ScanInterface { std::string saveFile_; ///< The name of the file to save a trace. - TApplication *rootapp; ///< Root application pointer. - TCanvas *canvas; ///< The main plotting canvas. TGraph *graph; ///< The TGraph for plotting traces. - TGraph *cfdGraph; ///< The TGraph for plotting cfd analysis. TLine *cfdLine; + TF1 *cfdPol3; + TF1 *cfdPol2; TH2F *hist; ///modNum*16+current_event->chanNum), 1); + count1cc_(8000, (current_event->GetId()), 1); #endif // Check that this channel event exists. diff --git a/Scan/util/source/filterer.cpp b/Analysis/Utilities/source/filterer.cpp similarity index 100% rename from Scan/util/source/filterer.cpp rename to Analysis/Utilities/source/filterer.cpp diff --git a/Scan/util/source/headReader.cpp b/Analysis/Utilities/source/headReader.cpp similarity index 100% rename from Scan/util/source/headReader.cpp rename to Analysis/Utilities/source/headReader.cpp diff --git a/Scan/util/source/scope.cpp b/Analysis/Utilities/source/scope.cpp similarity index 80% rename from Scan/util/source/scope.cpp rename to Analysis/Utilities/source/scope.cpp index a6207a858..62122a8ba 100644 --- a/Scan/util/source/scope.cpp +++ b/Analysis/Utilities/source/scope.cpp @@ -1,7 +1,9 @@ -#include #include +#include // PixieCore libraries +#include "ChannelEvent.hpp" +#include "HelperFunctions.hpp" #include "XiaData.hpp" // Local files @@ -14,11 +16,9 @@ #endif // Root files -#include "TApplication.h" #include "TSystem.h" #include "TStyle.h" #include "TMath.h" -#include "TCanvas.h" #include "TGraph.h" #include "TH2F.h" #include "TAxis.h" @@ -88,18 +88,20 @@ void scopeUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ if(!running) break; - //Get the first event int he FIFO. + //Get the first event in the FIFO. current_event = rawEvent.front(); rawEvent.pop_front(); - // Safety catches for null event or empty adcTrace. - if(!current_event || current_event->adcTrace.empty()){ + // Safety catches for null event or empty ->GetTrace(). + if(!current_event || current_event->GetTrace().empty()){ continue; } // Pass this event to the correct processor - int maximum = *std::max_element(current_event->adcTrace.begin(),current_event->adcTrace.end()); - if(current_event->modNum == mod_ && current_event->chanNum == chan_){ + double maximum = + TraceFunctions::FindMaximum(current_event->GetTrace(), + current_event->GetTrace().size()).second; + if(current_event->GetModuleNumber() == mod_ && current_event->GetChannelNumber() == chan_){ //Check threhsold. if (maximum < threshLow_) { delete current_event; @@ -123,7 +125,7 @@ void scopeUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ /////////////////////////////////////////////////////////////////////////////// /// Default constructor. -scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : ScanInterface() { +scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : RootScanner() { need_graph_update = false; resetGraph_ = false; acqRun_ = true; @@ -143,17 +145,14 @@ scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : ScanInterface() { num_displayed = 0; time(&last_trace); - // Variables for root graphics - rootapp = new TApplication("scope", 0, NULL); - gSystem->Load("libTree"); - - canvas = new TCanvas("scope_canvas", "scopeScanner"); - graph = new TGraph(); - cfdGraph = new TGraph(); cfdLine = new TLine(); - cfdLine->SetLineColor(2); - + cfdLine->SetLineColor(kRed); + cfdPol3 = new TF1("cfdPol3", "pol3"); + cfdPol3->SetLineColor(kGreen+1); + cfdPol2 = new TF1("cfdPol2", "pol2"); + cfdPol2->SetLineColor(kMagenta+1); + hist = new TH2F("hist","",256,0,1,256,0,1); SetupFunc(); @@ -169,11 +168,10 @@ scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : ScanInterface() { /// Destructor. scopeScanner::~scopeScanner(){ - canvas->Close(); - delete canvas; delete graph; - delete cfdGraph; delete cfdLine; + delete cfdPol3; + delete cfdPol2; delete hist; delete paulauskasFunc; } @@ -187,14 +185,10 @@ TF1 *scopeScanner::SetupFunc() { void scopeScanner::ResetGraph(unsigned int size) { delete graph; - delete cfdGraph; graph = new TGraph(size); graph->SetMarkerStyle(kFullDotSmall); - cfdGraph = new TGraph(size); - cfdGraph->SetLineColor(4); - if(size != x_vals.size()){ std::cout << msgHeader << "Changing trace length from " << x_vals.size()*ADC_TIME_STEP << " to " << size*ADC_TIME_STEP << " ns.\n"; x_vals.resize(size); @@ -212,80 +206,69 @@ void scopeScanner::ResetGraph(unsigned int size) { } void scopeScanner::Plot(){ + static float histAxis[2][2]; + if(chanEvents_.size() < numAvgWaveforms_) return; - ///The limits of the vertical axis - static float axisVals[2][2]; //The max and min values of the graph, first index is the axis, second is the min / max - static float userZoomVals[2][2]; - static bool userZoom[2]; - - //Get the user zoom settings. - userZoomVals[0][0] = canvas->GetUxmin(); - userZoomVals[0][1] = canvas->GetUxmax(); - userZoomVals[1][0] = canvas->GetUymin(); - userZoomVals[1][1] = canvas->GetUymax(); - if(chanEvents_.front()->size != x_vals.size()){ // The length of the trace has changed. resetGraph_ = true; } if (resetGraph_) { ResetGraph(chanEvents_.front()->size); + ResetZoom(); for (int i=0;i<2;i++) { - axisVals[i][0] = 1E9; - axisVals[i][1] = -1E9; - userZoomVals[i][0] = 1E9; - userZoomVals[i][1] = -1E9; - userZoom[i] = false; - } - } - - //Determine if the user had zoomed or unzoomed. - for (int i=0; i<2; i++) { - userZoom[i] = (userZoomVals[i][0] != axisVals[i][0] || userZoomVals[i][1] != axisVals[i][1]); + histAxis[i][0] = 1E9; + histAxis[i][1] = -1E9; + } } //For a waveform pulse we use a graph. if (numAvgWaveforms_ == 1) { int index = 0; for (size_t i = 0; i < chanEvents_.front()->size; ++i) { - graph->SetPoint(index, x_vals[i], chanEvents_.front()->event->adcTrace.at(i)); + graph->SetPoint(index, x_vals[i], chanEvents_.front()->event->GetTrace().at(i)); index++; } - //Get and set the updated graph limits. - if (graph->GetXaxis()->GetXmin() < axisVals[0][0]) axisVals[0][0] = graph->GetXaxis()->GetXmin(); - if (graph->GetXaxis()->GetXmax() > axisVals[0][1]) axisVals[0][1] = graph->GetXaxis()->GetXmax(); - graph->GetXaxis()->SetLimits(axisVals[0][0], axisVals[0][1]); - - if (graph->GetYaxis()->GetXmin() < axisVals[1][0]) axisVals[1][0] = graph->GetYaxis()->GetXmin(); - if (graph->GetYaxis()->GetXmax() > axisVals[1][1]) axisVals[1][1] = graph->GetYaxis()->GetXmax(); - graph->GetYaxis()->SetLimits(axisVals[1][0], axisVals[1][1]); - - //Set the users zoom window. - for (int i = 0; i < 2; i++) { - if (!userZoom[i]) { - for (int j = 0; j < 2; j++) userZoomVals[i][j] = axisVals[i][j]; - } - } - graph->GetXaxis()->SetRangeUser(userZoomVals[0][0], userZoomVals[0][1]); - graph->GetYaxis()->SetRangeUser(userZoomVals[1][0], userZoomVals[1][1]); + UpdateZoom(); graph->Draw("AP0"); float lowVal = (chanEvents_.front()->max_index - fitLow_) * ADC_TIME_STEP; float highVal = (chanEvents_.front()->max_index + fitHigh_) * ADC_TIME_STEP; + ///@TODO Renable the CFD with the proper functionality. + /* if(performCfd_){ + ChannelEvent *evt = chanEvents_.front(); + // Find the zero-crossing of the cfd waveform. - float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_, cfdD_, cfdL_); + float cfdCrossing = evt->AnalyzeCFD(cfdF_); - // Draw the cfd waveform. - for(size_t cfdIndex = 0; cfdIndex < chanEvents_.front()->size; cfdIndex++) - cfdGraph->SetPoint((int)cfdIndex, x_vals[cfdIndex], chanEvents_.front()->cfdvals[cfdIndex] + chanEvents_.front()->baseline); + // Draw the cfd crossing line. cfdLine->DrawLine(cfdCrossing*ADC_TIME_STEP, userZoomVals[1][0], cfdCrossing*ADC_TIME_STEP, userZoomVals[1][1]); - cfdGraph->Draw("LSAME"); + + // Draw the 3rd order polynomial. + cfdPol3->SetParameter(0, evt->cfdPar[0]); + cfdPol3->SetParameter(1, evt->cfdPar[1]/ADC_TIME_STEP); + cfdPol3->SetParameter(2, evt->cfdPar[2]/std::pow(ADC_TIME_STEP, 2.0)); + cfdPol3->SetParameter(3, evt->cfdPar[3]/std::pow(ADC_TIME_STEP, 3.0)); + // Find the pulse maximum by fitting with a third order polynomial. + if(evt->event->adcTrace[evt->max_index-1] >= evt->event->adcTrace[evt->max_index+1]) // Favor the left side of the pulse. + cfdPol3->SetRange((evt->max_index - 2)*ADC_TIME_STEP, (evt->max_index + 1)*ADC_TIME_STEP); + else // Favor the right side of the pulse. + cfdPol3->SetRange((evt->max_index - 1)*ADC_TIME_STEP, (evt->max_index + 2)*ADC_TIME_STEP); + cfdPol3->Draw("SAME"); + + // Draw the 2nd order polynomial. + cfdPol2->SetParameter(0, evt->cfdPar[4]); + cfdPol2->SetParameter(1, evt->cfdPar[5]/ADC_TIME_STEP); + cfdPol2->SetParameter(2, evt->cfdPar[6]/std::pow(ADC_TIME_STEP, 2.0)); + cfdPol2->SetRange((evt->cfdIndex - 1)*ADC_TIME_STEP, (evt->cfdIndex + 1)*ADC_TIME_STEP); + cfdPol2->Draw("SAME"); } + */ if(performFit_){ paulauskasFunc->SetRange(lowVal, highVal); @@ -298,33 +281,25 @@ void scopeScanner::Plot(){ //Determine the maximum and minimum values of the events. for (unsigned int i = 0; i < numAvgWaveforms_; i++) { ChannelEvent* evt = chanEvents_.at(i); - float evtMin = *std::min_element(evt->event->adcTrace.begin(), evt->event->adcTrace.end()); - float evtMax = *std::max_element(evt->event->adcTrace.begin(), evt->event->adcTrace.end()); + float evtMin = *std::min_element(evt->event->GetTrace().begin(), evt->event->GetTrace().end()); + float evtMax = *std::max_element(evt->event->GetTrace().begin(), evt->event->GetTrace().end()); evtMin -= fabs(0.1 * evtMax); evtMax += fabs(0.1 * evtMax); - if (evtMin < axisVals[1][0]) axisVals[1][0] = evtMin; - if (evtMax > axisVals[1][1]) axisVals[1][1] = evtMax; - } - - //Set the users zoom window. - for (int i=0; i<2; i++) { - if (!userZoom[i]) { - for (int j=0; j<2; j++) - userZoomVals[i][j] = axisVals[i][j]; - } + if (evtMin < histAxis[1][0]) histAxis[1][0] = evtMin; + if (evtMax > histAxis[1][1]) histAxis[1][1] = evtMax; } //Reset the histogram hist->Reset(); //Rebin the histogram - hist->SetBins(x_vals.size(), x_vals.front(), x_vals.back() + ADC_TIME_STEP, axisVals[1][1] - axisVals[1][0], axisVals[1][0], axisVals[1][1]); + hist->SetBins(x_vals.size(), x_vals.front(), x_vals.back() + ADC_TIME_STEP, histAxis[1][1] - histAxis[1][0], histAxis[1][0], histAxis[1][1]); //Fill the histogram for (unsigned int i = 0; i < numAvgWaveforms_; i++) { ChannelEvent* evt = chanEvents_.at(i); for (size_t i=0; i < evt->size; ++i) { - hist->Fill(x_vals[i], evt->event->adcTrace[i]); + hist->Fill(x_vals[i], evt->event->GetTrace()[i]); } } @@ -346,10 +321,9 @@ void scopeScanner::Plot(){ hist->Draw("COLZ"); prof->Draw("SAMES"); - hist->GetXaxis()->SetRangeUser(userZoomVals[0][0], userZoomVals[0][1]); - hist->GetYaxis()->SetRangeUser(userZoomVals[1][0], userZoomVals[1][1]); + UpdateZoom(); - canvas->Update(); + GetCanvas()->Update(); TPaveStats* stats = (TPaveStats*) prof->GetListOfFunctions()->FindObject("stats"); if (stats) { stats->SetX1NDC(0.55); @@ -364,7 +338,7 @@ void scopeScanner::Plot(){ } // Update the canvas. - canvas->Update(); + GetCanvas()->Update(); // Save the TGraph to a file. if (saveFile_ != "") { @@ -428,9 +402,9 @@ bool scopeScanner::AddEvent(XiaData *event_){ ChannelEvent *channel_event = new ChannelEvent(event_); //Process the waveform. - //channel_event->FindLeadingEdge(); - channel_event->CorrectBaseline(); - channel_event->FindQDC(); + ///@TODO : Renable this with the Helper functions. + //channel_event->ComputeBaseline(); + //channel_event->FindQDC(); //Push the channel event into the deque. chanEvents_.push_back(channel_event); @@ -580,7 +554,7 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vectorGetListOfFunctions()->FindObject(paulauskasFunc->GetName()); - canvas->Update(); + GetCanvas()->Update(); performFit_ = false; } else{ std::cout << msgHeader << "Fitting is not enabled.\n"; } @@ -655,12 +629,12 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vectorGetLogy()){ - canvas->SetLogy(0); + if(GetCanvas()->GetLogy()){ + GetCanvas()->SetLogy(0); std::cout << msgHeader << "y-axis set to linear.\n"; } else{ - canvas->SetLogy(1); + GetCanvas()->SetLogy(1); std::cout << msgHeader << "y-axis set to log.\n"; } } @@ -673,22 +647,12 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vectorProcessEvents(); - usleep(SLEEP_WAIT); -} #ifndef USE_HRIBF int main(int argc, char *argv[]){ // Define a new unpacker object. scopeScanner scanner; - + // Set the output message prefix. scanner.SetProgramName(std::string(PROG_NAME)); @@ -709,30 +673,31 @@ scopeScanner *scanner = NULL; // Do some startup stuff. extern "C" void startup_() { - scanner = new scopeScanner(); + scanner = new scopeScanner(); - // Handle command line arguments from SCANOR - scanner->Setup(GetNumberArguments(), GetArguments()); - - // Get a pointer to a class derived from Unpacker. - ScanorInterface::get()->SetUnpacker(scanner->GetCore()); + // Handle command line arguments from SCANOR + scanner->Setup(GetNumberArguments(), GetArguments()); + + // Get a pointer to a class derived from Unpacker. + ScanorInterface::get()->SetUnpacker(scanner->GetCore()); } ///@brief Defines the main interface with the SCANOR library, the program /// essentially starts here. ///@param [in] iexist : unused paramter from SCANOR call extern "C" void drrsub_(uint32_t &iexist) { - drrmake_(); - hd1d_(8000, 2, 256, 256, 0, 255, "Run DAMM you!", strlen("Run DAMM you!")); - endrr_(); + drrmake_(); + hd1d_(8000, 2, 256, 256, 0, 255, "Run DAMM you!", strlen("Run DAMM you!")); + endrr_(); } // Catch the exit call from scanor and clean up c++ objects CRT extern "C" void cleanup_() { - // Do some cleanup. - std::cout << "\nCleaning up..\n"; - scanner->Close(); - delete scanner; + // Do some cleanup. + std::cout << "\nCleaning up..\n"; + scanner->Close(); + delete scanner; } #endif + diff --git a/Scan/utkscan/CMakeLists.txt b/Analysis/Utkscan/CMakeLists.txt similarity index 90% rename from Scan/utkscan/CMakeLists.txt rename to Analysis/Utkscan/CMakeLists.txt index 76e70143c..5e273441d 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Analysis/Utkscan/CMakeLists.txt @@ -1,8 +1,5 @@ #CMake file for UTKScan. - -option(BUILD_UTKSCAN_TESTS "Build unit tests for utkscan" ON) option(UTKSCAN_GAMMA_GATES "Gamma-Gamma gates in GeProcessor" OFF) -option(USE_GSL "Use GSL for Pulse Fitting" ON) option(UTKSCAN_ONLINE "Options for online scans" OFF) option(UTKSCAN_TREE_DEBUG "Debugging info for TreeCorrelator" OFF) option(UTKSCAN_VERBOSE "Make Scan More Verbose" OFF) @@ -31,12 +28,6 @@ if(UTKSCAN_VERBOSE) add_definitions(-D VERBOSE) endif(UTKSCAN_VERBOSE) -#Check if GSL is installed -if(USE_GSL) - find_package(GSL REQUIRED) - add_definitions("-D usegsl") -endif(USE_GSL) - #------------------------------------------------------------------------------ #Add the local include directories to the build tree @@ -61,6 +52,7 @@ add_subdirectory(processors) if(NOT USE_HRIBF) set(SCAN_NAME utkscan) add_executable(${SCAN_NAME} + $ $ $ $ @@ -68,6 +60,7 @@ if(NOT USE_HRIBF) else(USE_HRIBF) set(SCAN_NAME utkscanor) add_executable(${SCAN_NAME} + $ $ $ $ @@ -77,7 +70,8 @@ else(USE_HRIBF) endif(NOT USE_HRIBF) #Add libraries to be linked with utkscan -target_link_libraries(${SCAN_NAME} ${LIBS} ScanStatic) +target_link_libraries(${SCAN_NAME} ${LIBS} PaassScanStatic ResourceStatic + PaassCoreStatic PugixmlStatic) #If we have GSL installed link if(USE_GSL) @@ -96,5 +90,4 @@ install(TARGETS ${SCAN_NAME} DESTINATION bin) #Install configuration files to the share directory install(DIRECTORY share/utkscan DESTINATION share) -#------------------------------------------------------------------------------ - +#------------------------------------------------------------------------------ \ No newline at end of file diff --git a/Scan/utkscan/core/CMakeLists.txt b/Analysis/Utkscan/analyzers/CMakeLists.txt similarity index 100% rename from Scan/utkscan/core/CMakeLists.txt rename to Analysis/Utkscan/analyzers/CMakeLists.txt diff --git a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/CfdAnalyzer.hpp similarity index 73% rename from Scan/utkscan/analyzers/include/CfdAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/CfdAnalyzer.hpp index b43e0c689..20b6c7547 100644 --- a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp +++ b/Analysis/Utkscan/analyzers/include/CfdAnalyzer.hpp @@ -6,26 +6,32 @@ #ifndef __CFDANALYZER_HPP_ #define __CFDANALYZER_HPP_ -#include "HighResTimingData.hpp" +#include "TimingDriver.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" //! Class to analyze traces using a digital CFD class CfdAnalyzer : public TraceAnalyzer { public: - /** Default constructor */ - CfdAnalyzer(); + /** Default constructor taking an argument*/ + CfdAnalyzer(const std::string &s); + /** Default Destructor */ - ~CfdAnalyzer(){}; + ~CfdAnalyzer() {}; + /** Declare the plots */ - virtual void DeclarePlots(void) const {}; + void DeclarePlots(void) const {}; + /** Do the analysis on traces * \param [in] trace : the trace to analyze * \param [in] detType : the detector type * \param [in] detSubtype : detector subtype * \param [in] tagMap : the map of tags for the channel */ - virtual void Analyze(Trace &trace, const std::string &detType, + void Analyze(Trace &trace, const std::string &detType, const std::string &detSubtype, const std::map &tagMap); +private: + TimingDriver *driver_; }; + #endif diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/FittingAnalyzer.hpp similarity index 81% rename from Scan/utkscan/analyzers/include/FittingAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/FittingAnalyzer.hpp index b1e9fbc31..5decfb50a 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Analysis/Utkscan/analyzers/include/FittingAnalyzer.hpp @@ -12,7 +12,7 @@ #include -#include "FitDriver.hpp" +#include "TimingDriver.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" @@ -23,19 +23,18 @@ class FittingAnalyzer : public TraceAnalyzer { FittingAnalyzer(const std::string &s); /** Default Destructor */ - ~FittingAnalyzer() {}; - /** Declare plots for the analyzer */ - virtual void DeclarePlots(void); + ~FittingAnalyzer(); + /** Analyzes the traces * \param [in] trace : the trace to analyze * \param [in] detType : the detector type we have * \param [in] detSubtype : the subtype of the detector * \param [in] tagMap : the map of tags for the channel */ - virtual void Analyze(Trace &trace, const std::string &detType, + void Analyze(Trace &trace, const std::string &detType, const std::string &detSubtype, const std::map & tagMap); private: - FitDriver::FITTER_TYPE fitterType_; + TimingDriver *driver_; }; #endif // __FITTINGANALYZER_HPP_ // David is awesome. diff --git a/Scan/utkscan/analyzers/include/TauAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/TauAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TauAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/TauAnalyzer.hpp diff --git a/Scan/utkscan/analyzers/include/TraceAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/TraceAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TraceAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/TraceAnalyzer.hpp diff --git a/Scan/utkscan/analyzers/include/TraceExtractor.hpp b/Analysis/Utkscan/analyzers/include/TraceExtractor.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TraceExtractor.hpp rename to Analysis/Utkscan/analyzers/include/TraceExtractor.hpp diff --git a/Scan/utkscan/analyzers/include/TraceFilter.hpp b/Analysis/Utkscan/analyzers/include/TraceFilter.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TraceFilter.hpp rename to Analysis/Utkscan/analyzers/include/TraceFilter.hpp diff --git a/Scan/utkscan/analyzers/include/TraceFilterAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/TraceFilterAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TraceFilterAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/TraceFilterAnalyzer.hpp diff --git a/Scan/utkscan/analyzers/include/TrapFilterParameters.hpp b/Analysis/Utkscan/analyzers/include/TrapFilterParameters.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/TrapFilterParameters.hpp rename to Analysis/Utkscan/analyzers/include/TrapFilterParameters.hpp diff --git a/Scan/utkscan/analyzers/include/WaaAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/WaaAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/WaaAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/WaaAnalyzer.hpp diff --git a/Analysis/Utkscan/analyzers/include/WaveformAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/WaveformAnalyzer.hpp new file mode 100644 index 000000000..b8be4abb3 --- /dev/null +++ b/Analysis/Utkscan/analyzers/include/WaveformAnalyzer.hpp @@ -0,0 +1,38 @@ +/** \file WaveformAnalyzer.hpp + * \brief Class to analyze traces. + * \author S. V. Paulauskas + */ +#ifndef __WAVEFORMANALYZER_HPP_ +#define __WAVEFORMANALYZER_HPP_ + +#include "Globals.hpp" +#include "Messenger.hpp" +#include "Trace.hpp" +#include "TraceAnalyzer.hpp" + +//! Class to waveform analysis +class WaveformAnalyzer : public TraceAnalyzer { +public: + /** Default Constructor */ + WaveformAnalyzer(); + + /** Default destructor */ + ~WaveformAnalyzer() { delete messenger_; } + + /** Declare the plots */ + void DeclarePlots(void) const {} + + /** Do the analysis on traces + * \param [in] trace : the trace to analyze + * \param [in] type : the detector type + * \param [in] subtype : detector subtype + * \param [in] tags : the map of the tags for the channel */ + void Analyze(Trace &trace, const std::string &type, + const std::string &subtype, + const std::map &tags); + +private: + Messenger *messenger_;//!< A pointer for the messenger class +}; + +#endif // __WAVEFORMANALYZER_HPP_ diff --git a/Scan/utkscan/analyzers/source/CMakeLists.txt b/Analysis/Utkscan/analyzers/source/CMakeLists.txt similarity index 52% rename from Scan/utkscan/analyzers/source/CMakeLists.txt rename to Analysis/Utkscan/analyzers/source/CMakeLists.txt index f6862fdac..36e0e5517 100644 --- a/Scan/utkscan/analyzers/source/CMakeLists.txt +++ b/Analysis/Utkscan/analyzers/source/CMakeLists.txt @@ -9,12 +9,7 @@ set(ANALYZER_SOURCES WaveformAnalyzer.cpp) if(USE_GSL) - set(ANALYZER_SOURCES ${ANALYZER_SOURCES} FittingAnalyzer.cpp) - if(${GSL_VERSION} GREATER 1.9) - set(ANALYZER_SOURCES ${ANALYZER_SOURCES} Gsl2Fitter.cpp) - else(${GSL_VERSION} LESS 2.0) - set(ANALYZER_SOURCES ${ANALYZER_SOURCES} Gsl1Fitter.cpp) - endif(${GSL_VERSION} GREATER 1.9) + set(ANALYZER_SOURCES ${ANALYZER_SOURCES} FittingAnalyzer.cpp) endif(USE_GSL) add_library(AnalyzerObjects OBJECT ${ANALYZER_SOURCES}) diff --git a/Analysis/Utkscan/analyzers/source/CfdAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/CfdAnalyzer.cpp new file mode 100644 index 000000000..c9af60cbd --- /dev/null +++ b/Analysis/Utkscan/analyzers/source/CfdAnalyzer.cpp @@ -0,0 +1,62 @@ +/** \file CfdAnalyzer.cpp + * \brief Uses a Digital CFD to obtain waveform phases + * + * This code will obtain the phase of a waveform using a digital CFD. + * Currently the only method is a polynomial fit to the crossing point. + * For 100-250 MHz systems, this is not going to produce good timing. + * This code was originally written by S. Padgett. + * + * \author S. V. Paulauskas + * \date 22 July 2011 + */ +#include +#include +#include + +#include "CfdAnalyzer.hpp" +#include "HelperFunctions.hpp" +#include "PolynomialCfd.hpp" +#include "TraditionalCfd.hpp" + +using namespace std; + +CfdAnalyzer::CfdAnalyzer(const std::string &s) : TraceAnalyzer() { + name = "CfdAnalyzer"; + if (s == "polynomial" || s == "poly") + driver_ = new PolynomialCfd(); + else if(s == "traditional" || s == "trad") + driver_ = new TraditionalCfd(); + else + driver_ = NULL; + +} + +void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, + const std::string &detSubtype, + const std::map &tagMap) { + TraceAnalyzer::Analyze(trace, detType, detSubtype, tagMap); + + if (!driver_) { + EndAnalyze(); + return; + } + + if (trace.HasValue("saturation") || trace.empty() || + trace.GetWaveform().empty()) { + EndAnalyze(); + return; + } + + const pair baseline(trace.GetValue("baseline"), + trace.GetValue("sigmaBaseline")); + const pair max(trace.GetValue("maxpos"), + trace.GetValue("extrapolatedMaxVal")); + + const pair pars = + Globals::get()->cfdPars(detType + ":" + detSubtype); + + trace.InsertValue("phase", + driver_->CalculatePhase(trace.GetBaselineSubtractedTrace() + , pars, max, baseline)); + EndAnalyze(); +} diff --git a/Analysis/Utkscan/analyzers/source/FittingAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/FittingAnalyzer.cpp new file mode 100644 index 000000000..d37b2c5fc --- /dev/null +++ b/Analysis/Utkscan/analyzers/source/FittingAnalyzer.cpp @@ -0,0 +1,89 @@ +/** \file FittingAnalyzer.cpp + * \brief Uses a chi^2 minimization to fit waveforms + * + * Obtains the phase of a waveform using a Chi^2 fitting algorithm + * implemented through the GSL libraries. We have now set up two different + * functions for this processor. One of them handles the fast SiPMT signals, + * which tend to be more Gaussian in shape than the standard PMT signals. + * + * \author S. V. Paulauskas + * \date 22 July 2011 + * + * @TODO This currently doesn't actually set the values for the GSL fitter + * since we have it set as a TimingDriver type. We'll have to figure out how + * to address that. + */ +#include +#include +#include + +#include "FittingAnalyzer.hpp" +#include "GslFitter.hpp" + +using namespace std; + +FittingAnalyzer::FittingAnalyzer(const std::string &s) { + name = "FittingAnalyzer"; + if (s == "GSL" || s == "gsl") { + driver_ = new GslFitter(); + } else { + driver_ = NULL; + } +} + +FittingAnalyzer::~FittingAnalyzer() { + delete driver_; +} + +void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, + const std::string &detSubtype, + const std::map &tagMap) { + TraceAnalyzer::Analyze(trace, detType, detSubtype, tagMap); + + if (!driver_) { + EndAnalyze(); + return; + } + + if (trace.HasValue("saturation") || trace.empty() || + trace.GetWaveform().size() == 0) { + EndAnalyze(); + return; + } + + Globals *globals = Globals::get(); + + const pair baseline(trace.GetValue("baseline"), + trace.GetValue("sigmaBaseline")); + const pair max(trace.GetValue("maxpos"), + trace.GetValue("maxval")); + + //We need to check and make sure that we don't need to use the timing + // functions for the SiPM fast signals + bool isFastSiPm = detType == "beta" && detSubtype == "double" + && tagMap.find("timing") != tagMap.end(); + + if (!isFastSiPm) { + if (baseline.second > globals->sigmaBaselineThresh()) { + EndAnalyze(); + return; + } + } else { + if (baseline.second > globals->siPmtSigmaBaselineThresh()) { + EndAnalyze(); + return; + } + } + + pair pars = globals->fitPars(detType + ":" + detSubtype); + if (isFastSiPm) + pars = globals->fitPars(detType + ":" + detSubtype + ":timing"); + + driver_->SetQdc(trace.GetValue("qdc")); + double phase = driver_->CalculatePhase(trace.GetWaveform(), + pars, max, baseline); + + trace.InsertValue("phase", phase + max.first); + + EndAnalyze(); +} \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/TauAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/TauAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/TauAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/TauAnalyzer.cpp diff --git a/Scan/utkscan/analyzers/source/TraceAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/TraceAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/TraceAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/TraceAnalyzer.cpp diff --git a/Scan/utkscan/analyzers/source/TraceExtractor.cpp b/Analysis/Utkscan/analyzers/source/TraceExtractor.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/TraceExtractor.cpp rename to Analysis/Utkscan/analyzers/source/TraceExtractor.cpp diff --git a/Scan/utkscan/analyzers/source/TraceFilter.cpp b/Analysis/Utkscan/analyzers/source/TraceFilter.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/TraceFilter.cpp rename to Analysis/Utkscan/analyzers/source/TraceFilter.cpp diff --git a/Scan/utkscan/analyzers/source/TraceFilterAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/TraceFilterAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/TraceFilterAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/TraceFilterAnalyzer.cpp diff --git a/Scan/utkscan/analyzers/source/WaaAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/WaaAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/WaaAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/WaaAnalyzer.cpp diff --git a/Analysis/Utkscan/analyzers/source/WaveformAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/WaveformAnalyzer.cpp new file mode 100644 index 000000000..67c2bcb70 --- /dev/null +++ b/Analysis/Utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -0,0 +1,87 @@ +/** \file WaveformAnalyzer.cpp + *\brief Preliminary waveform analysis + * + *Does preliminary waveform analysis on traces. The parameters set here + *will be used for the high resolution timing algorithms to do their thing. + * + *\author S. V. Paulauskas + *\date July 16, 2009 +*/ +#include +#include +#include + +#include + +#include "HelperFunctions.hpp" +#include "WaveformAnalyzer.hpp" + +using namespace std; + +WaveformAnalyzer::WaveformAnalyzer() : TraceAnalyzer() { + name = "WaveformAnalyzer"; + messenger_ = new Messenger(); +} + +void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, + const std::string &subtype, + const std::map &tags) { + TraceAnalyzer::Analyze(trace, type, subtype, tags); + + if (trace.HasValue("saturation") || trace.empty()) { + EndAnalyze(); + return; + } + + Globals *globals = Globals::get(); + + pair range = + globals->waveformRange(type + ":" + subtype); + + if (type == "beta" && subtype == "double" && + tags.find("timing") != tags.end()) + range = globals->waveformRange(type + ":" + subtype + ":timing"); + + try { + //First we calculate the position of the maximum. + pair max = + TraceFunctions::FindMaximum(trace, globals->traceDelay() / + (globals->adcClockInSeconds() * + 1.e9)); + + //If the max value is a saturation we mark it here. + if (max.second >= globals->bitResolution()) + trace.InsertValue("saturation", 1); + + //Next we calculate the baseline and its standard deviation + pair baseline = + TraceFunctions::CalculateBaseline(trace, + make_pair(0, max.first - + range.first)); + vector traceNoBaseline; + for (unsigned int i = 0; i < trace.size(); i++) + traceNoBaseline.push_back(trace[i] - baseline.first); + + //Finally, we calculate the QDC in the waveform range and subtract + // the baseline from it. + pair waveformRange(max.first - range.first, + max.first + range.second); + double qdc = + TraceFunctions::CalculateQdc(traceNoBaseline, waveformRange); + + //Now we are going to set all the different values into the trace. + trace.InsertValue("qdc", qdc); + trace.InsertValue("baseline", baseline.first); + trace.InsertValue("sigmaBaseline", baseline.second); + trace.InsertValue("maxval", max.second - baseline.first); + trace.InsertValue("extrapolatedMaxVal", + TraceFunctions::ExtrapolateMaximum(trace, max) + .first - baseline.first); + trace.InsertValue("maxpos", (int)max.first); + trace.SetBaselineSubtractedTrace(traceNoBaseline); + trace.SetWaveformRange(waveformRange); + } catch (range_error &ex) { + cerr << "WaveformAnalyzer::Analyze - " << ex.what() << endl; + EndAnalyze(); + } +} \ No newline at end of file diff --git a/Analysis/Utkscan/core/CMakeLists.txt b/Analysis/Utkscan/core/CMakeLists.txt new file mode 100644 index 000000000..b71414f04 --- /dev/null +++ b/Analysis/Utkscan/core/CMakeLists.txt @@ -0,0 +1,5 @@ +if(BUILD_UNITTESTS) + add_subdirectory(tests) +endif(BUILD_UNITTESTS) + +add_subdirectory(source) \ No newline at end of file diff --git a/Scan/utkscan/core/include/BarBuilder.hpp b/Analysis/Utkscan/core/include/BarBuilder.hpp similarity index 100% rename from Scan/utkscan/core/include/BarBuilder.hpp rename to Analysis/Utkscan/core/include/BarBuilder.hpp diff --git a/Scan/utkscan/core/include/BarDetector.hpp b/Analysis/Utkscan/core/include/BarDetector.hpp similarity index 100% rename from Scan/utkscan/core/include/BarDetector.hpp rename to Analysis/Utkscan/core/include/BarDetector.hpp diff --git a/Scan/utkscan/core/include/Calibrator.hpp b/Analysis/Utkscan/core/include/Calibrator.hpp similarity index 100% rename from Scan/utkscan/core/include/Calibrator.hpp rename to Analysis/Utkscan/core/include/Calibrator.hpp diff --git a/Scan/utkscan/core/include/ChanEvent.hpp b/Analysis/Utkscan/core/include/ChanEvent.hpp similarity index 88% rename from Scan/utkscan/core/include/ChanEvent.hpp rename to Analysis/Utkscan/core/include/ChanEvent.hpp index af10983c7..f4909bfa2 100644 --- a/Scan/utkscan/core/include/ChanEvent.hpp +++ b/Analysis/Utkscan/core/include/ChanEvent.hpp @@ -5,13 +5,11 @@ #define __CHANEVENT_HPP #include -#include "XiaData.hpp" - #include "DetectorLibrary.hpp" -#include "pixie16app_defs.h" #include "Identifier.hpp" #include "Globals.hpp" #include "Trace.hpp" +#include "XiaData.hpp" /*! \brief A channel event * @@ -28,9 +26,9 @@ class ChanEvent { ChanEvent(){ZeroNums();}; ///Constructor setting XIA Data - ChanEvent(const XiaData &xiadata) { - data_ = xiadata; - trace = xiadata.adcTrace; + ChanEvent(const XiaData &data) { + data_ = data; + trace = data.GetTrace(); } ///Default Destructor @@ -58,15 +56,15 @@ class ChanEvent { /** \return the CFD source bit */ bool GetCfdSourceBit() const { - return(data_.cfdTrigSource); + return(data_.GetCfdTriggerSourceBit()); } /** \return true if the CFD was forced trigger */ bool CfdForceTrig() const { - return(data_.cfdForceTrig); + return(data_.GetCfdForcedTriggerBit()); } double GetEnergy() const { - return(data_.energy); /**< \return the raw energy */ + return(data_.GetEnergy()); /**< \return the raw energy */ } double GetCalEnergy() const { return(calEnergy); /**< \return the calibrated energy */ @@ -75,7 +73,7 @@ class ChanEvent { return correctedTime; /**< \return the corrected time */ } double GetTime() const { - return(data_.time); /**< \return the raw time in clock ticks*/ + return(data_.GetTime()); /**< \return the raw time in clock ticks*/ } double GetCalTime() const { return calTime; /**< \return the calibrated time */ @@ -84,7 +82,7 @@ class ChanEvent { return(highResTime); /**< \return the high-resolution time in ns*/ } double GetEventTime() const { - return(data_.eventTime); /**< \return the event time */ + return(data_.GetTime()); /**< \return the event time */ } const Trace& GetTrace() const { return(trace); /**< \return a reference to the trace */ @@ -93,13 +91,13 @@ class ChanEvent { return(trace); /** \return a reference which can alter the trace */ } unsigned long GetTrigTime() const { - return(data_.trigTime); /**< \return the channel trigger time */ + return(data_.GetTime()); /**< \return the channel trigger time */ } unsigned long GetEventTimeLo() const { - return data_.eventTimeLo; /**< \return the lower 32 bits of event time */ + return data_.GetEventTimeLow(); /**< \return the lower 32 bits of event time */ } unsigned long GetEventTimeHi() const { - return data_.eventTimeHi; /**< \return the upper 32 bits of event time */ + return data_.GetEventTimeHigh(); /**< \return the upper 32 bits of event time */ } unsigned long GetRunTime0() const { return runTime0; /**< \return the lower bits of run time */ @@ -111,10 +109,10 @@ class ChanEvent { return runTime2; /**< \return the higher bits of run time */ } bool IsPileup() const { - return data_.pileupBit; //!< \return true if channel is pileup + return data_.IsPileup(); //!< \return true if channel is pileup } bool IsSaturated() const { /**< \return whether the trace is saturated */ - return data_.saturatedBit; + return data_.IsSaturated(); } //! \return The identifier in the map for the channel event diff --git a/Scan/utkscan/core/include/Correlator.hpp b/Analysis/Utkscan/core/include/Correlator.hpp similarity index 100% rename from Scan/utkscan/core/include/Correlator.hpp rename to Analysis/Utkscan/core/include/Correlator.hpp diff --git a/Scan/utkscan/core/include/DammPlotIds.hpp b/Analysis/Utkscan/core/include/DammPlotIds.hpp similarity index 100% rename from Scan/utkscan/core/include/DammPlotIds.hpp rename to Analysis/Utkscan/core/include/DammPlotIds.hpp diff --git a/Scan/utkscan/core/include/DetectorDriver.hpp b/Analysis/Utkscan/core/include/DetectorDriver.hpp similarity index 100% rename from Scan/utkscan/core/include/DetectorDriver.hpp rename to Analysis/Utkscan/core/include/DetectorDriver.hpp diff --git a/Scan/utkscan/core/include/DetectorLibrary.hpp b/Analysis/Utkscan/core/include/DetectorLibrary.hpp similarity index 100% rename from Scan/utkscan/core/include/DetectorLibrary.hpp rename to Analysis/Utkscan/core/include/DetectorLibrary.hpp diff --git a/Scan/utkscan/core/include/DetectorSummary.hpp b/Analysis/Utkscan/core/include/DetectorSummary.hpp similarity index 98% rename from Scan/utkscan/core/include/DetectorSummary.hpp rename to Analysis/Utkscan/core/include/DetectorSummary.hpp index 438030e8a..bf1b125b3 100644 --- a/Scan/utkscan/core/include/DetectorSummary.hpp +++ b/Analysis/Utkscan/core/include/DetectorSummary.hpp @@ -10,9 +10,6 @@ #include #include "ChanEvent.hpp" - -#include "pixie16app_defs.h" - #include "Globals.hpp" #include "Trace.hpp" diff --git a/Scan/utkscan/core/include/EventData.hpp b/Analysis/Utkscan/core/include/EventData.hpp similarity index 100% rename from Scan/utkscan/core/include/EventData.hpp rename to Analysis/Utkscan/core/include/EventData.hpp diff --git a/Scan/utkscan/core/include/Exceptions.hpp b/Analysis/Utkscan/core/include/Exceptions.hpp similarity index 100% rename from Scan/utkscan/core/include/Exceptions.hpp rename to Analysis/Utkscan/core/include/Exceptions.hpp diff --git a/Scan/utkscan/core/include/Globals.hpp b/Analysis/Utkscan/core/include/Globals.hpp similarity index 94% rename from Scan/utkscan/core/include/Globals.hpp rename to Analysis/Utkscan/core/include/Globals.hpp index e954e5b19..ebf0bd84b 100644 --- a/Scan/utkscan/core/include/Globals.hpp +++ b/Analysis/Utkscan/core/include/Globals.hpp @@ -20,14 +20,11 @@ #include "Exceptions.hpp" #include "Messenger.hpp" -#include "pixie16app_defs.h" #include "TrapFilterParameters.hpp" /** A macro defining what kind of NAN to throw */ #ifndef NAN - #include - #define NAN (numeric_limits::quiet_NaN()) #endif @@ -250,6 +247,13 @@ class Globals { return (std::make_pair(5, 10)); } + /** \return the requested cfd parameters parameters */ + std::pair cfdPars(const std::string &str) const { + if (fitPars_.find(str) != fitPars_.end()) + return (fitPars_.find(str)->second); + return (std::make_pair(0.5, 1)); + } + /** \return the requested fitting parameters */ std::pair fitPars(const std::string &str) const { if (fitPars_.find(str) != fitPars_.end()) @@ -266,6 +270,9 @@ class Globals { TrapFilterParameters(125, 125, 10))); } + /*! \return returns name of specified output file */ + std::string outputFile() const {return outputFilename_;} + /*! \return path to use to output files, can be different from output * file path * \param [in] fileName : the path for the configuration files */ @@ -281,9 +288,6 @@ class Globals { /** \return the configuration file */ std::string configfile() const { return (configFile_); } - /** \return the maximum words */ - unsigned int maxWords() const { return maxWords_; } - /** \return max number of traces stored in 2D spectra * with traces. If not set, by default is 16. */ unsigned short numTraces() const { return numTraces_; } @@ -292,6 +296,10 @@ class Globals { * Values should be given in seconds in respect to the beginning of the file */ std::vector > rejectRegions() const { return reject_; }; + + /*! Sets output Filename from scan interface */ + void SetOutputFilename(const std::string &a){outputFilename_ = a; } + private: /** Default Constructor */ Globals(const std::string &file); @@ -335,13 +343,14 @@ class Globals { std::map > waveformRanges_; //!< Map containing ranges for the waveforms std::map > fitPars_; //!< Map containing all of the parameters to be used in the fitting analyzer for a type:subtype + std::map > cfdPars_; //!< Map containing all of the parameters to be used in the cfd analyzer for a type:subtype std::map > trapFiltPars_; //! > reject_;//!< rejection range in time diff --git a/Scan/utkscan/core/include/HighResTimingData.hpp b/Analysis/Utkscan/core/include/HighResTimingData.hpp similarity index 98% rename from Scan/utkscan/core/include/HighResTimingData.hpp rename to Analysis/Utkscan/core/include/HighResTimingData.hpp index 6d83349b9..fd2a10b27 100644 --- a/Scan/utkscan/core/include/HighResTimingData.hpp +++ b/Analysis/Utkscan/core/include/HighResTimingData.hpp @@ -64,7 +64,7 @@ class HighResTimingData { /** \return The current value of phase_ in nanoseconds*/ double GetPhase() const { return(chan_->GetTrace().GetValue("phase") * - Globals::get()->clockInSeconds() * 1e9); + Globals::get()->adcClockInSeconds() * 1e9); } /** \return The pixie Energy */ double GetFilterEnergy() const { return(chan_->GetEnergy()); } diff --git a/Scan/utkscan/core/include/HisFile.hpp b/Analysis/Utkscan/core/include/HisFile.hpp similarity index 100% rename from Scan/utkscan/core/include/HisFile.hpp rename to Analysis/Utkscan/core/include/HisFile.hpp diff --git a/Scan/utkscan/core/include/Identifier.hpp b/Analysis/Utkscan/core/include/Identifier.hpp similarity index 63% rename from Scan/utkscan/core/include/Identifier.hpp rename to Analysis/Utkscan/core/include/Identifier.hpp index 3da8b9380..6fe4f01c7 100644 --- a/Scan/utkscan/core/include/Identifier.hpp +++ b/Analysis/Utkscan/core/include/Identifier.hpp @@ -30,48 +30,59 @@ class Identifier { Identifier(){Zero();}; /** Default Destructor */ ~Identifier(){}; + /** Constructor taking arguments and setting values - * \param [in] type : the type to set + * \param [in] atype : the type to set * \param [in] subType : the subType to set * \param [in] loc : the location to set */ - Identifier(const std::string &type, const std::string &subType, - const int &loc); + Identifier(const std::string &atype, const std::string &subType, + const unsigned int &loc) { + type_ = atype; + subtype_ = subType; + location_ = loc; + } /** Sets the DAMM ID * \param [in] a : the id to set */ - void SetDammID(int a) {dammID = a;}; + void SetDammID(unsigned int &a) {dammID_ = a;} /** Sets the type * \param [in] a : the type to set */ - void SetType(const std::string &a) {type = a;}; + void SetType(const std::string &a) {type_ = a;} /** Sets the subtype of the channel * \param [in] a : the subtype to set */ - void SetSubtype(const std::string &a) {subtype = a;}; + void SetSubtype(const std::string &a) {subtype_ = a;} /** Sets the location * \param [in] a : sets the location for the channel */ - void SetLocation(int a) {location = a;}; + void SetLocation(const unsigned int &a) {location_ = a;} - int GetDammID() const {return dammID;} /**< \return Get the dammid */ - const std::string& GetType() const {return type;} /**< \return Get the detector type */ - const std::string& GetSubtype() const {return subtype;} /**< \return Get the detector subtype */ - int GetLocation() const {return location;} /**< \return Get the detector location */ + ///@return The value of the private variable dammID + unsigned int GetDammID() const {return dammID_;} + ///@return The value of the private variable type + const std::string& GetType() const {return type_;} + ///@return the value of the private variable subtype + const std::string& GetSubtype() const {return subtype_;} + ///@return The value of the private variable location + unsigned int GetLocation() const {return location_;} /** Insert a tag to the Identifier * \param [in] s : the name of the tag to insert * \param [in] n : the value of the tag to insert */ - void AddTag(const std::string &s, int n) {tag[s] = n;} + void AddTag(const std::string &s, int n) {tag_[s] = n;} + /** Check if an identifier has a tag * \param [in] s : the tag to search for * \return true if the tag is in the identifier */ bool HasTag(const std::string &s) const { - if(tag.count(s) > 0) + if(tag_.count(s) > 0) return(true); - return(false);}; + return(false);} + /** \return Get the requested tag * \param [in] s : the name of the tag to get */ int GetTag(const std::string &s) const; /** \return The map with the list of tags */ - std::map GetTagMap(void) const {return (tag);}; + std::map GetTagMap(void) const {return tag_;} /** Zeroes an identifier * @@ -88,9 +99,9 @@ class Identifier { * \param [in] x : the Identifier to compare to * \return true if this is equal to x */ bool operator==(const Identifier &x) const { - return (type == x.type && - subtype == x.subtype && - location == x.location); + return (type_ == x.type_ && + subtype_ == x.subtype_ && + location_ == x.location_); } /** Not - Equality operator for identifier @@ -104,33 +115,42 @@ class Identifier { * \param [in] x : the Identifier to compare * \return true if this is less than x */ bool operator<(const Identifier &x) const { - if (type.compare(x.type) > 0) + if (type_.compare(x.type_) > 0) return false; - else if (type.compare(x.type) < 0) + else if (type_.compare(x.type_) < 0) return true; else { - if (subtype.compare(x.subtype) > 0) + if (subtype_.compare(x.subtype_) > 0) return false; - else if (subtype.compare(x.subtype)) + else if (subtype_.compare(x.subtype_)) return true; else { - return (location < x.location); + return (location_ < x.location_); } } } + ///@param[in] rhs : The right hand side that we are comparing with. + ///@return The negative of the less than operator. + bool operator>(const Identifier & rhs) const { + return !operator<(rhs); + } + /** \return The name of the place associated with the channel */ std::string GetPlaceName() const { std::stringstream ss; - ss << GetType() << "_" << GetSubtype() << "_" << GetLocation(); + ss << type_ << "_" << subtype_ << "_" << location_; return ss.str(); } private: - std::string type; /**< Specifies the detector type */ - std::string subtype; /**< Specifies the detector sub type */ - int dammID; /**< Damm spectrum number for plotting calibrated energies */ - int location; /**< Specifies the real world location of the channel. + std::string type_; /**< Specifies the detector type */ + std::string subtype_; /**< Specifies the detector sub type */ + unsigned int dammID_; /**< Damm spectrum number for plotting + * calibrated energies */ + unsigned int location_; /**< Specifies the real world location of the + * channel. For the DSSD this variable is the strip number */ - std::map tag; /**< A list of tags associated with the Identifier */ + std::map tag_; /**< A list of tags associated with the + * Identifier */ }; #endif diff --git a/Scan/utkscan/core/include/MersenneTwister.hpp b/Analysis/Utkscan/core/include/MersenneTwister.hpp similarity index 100% rename from Scan/utkscan/core/include/MersenneTwister.hpp rename to Analysis/Utkscan/core/include/MersenneTwister.hpp diff --git a/Scan/utkscan/core/include/Messenger.hpp b/Analysis/Utkscan/core/include/Messenger.hpp similarity index 100% rename from Scan/utkscan/core/include/Messenger.hpp rename to Analysis/Utkscan/core/include/Messenger.hpp diff --git a/Scan/utkscan/core/include/Notebook.hpp b/Analysis/Utkscan/core/include/Notebook.hpp similarity index 100% rename from Scan/utkscan/core/include/Notebook.hpp rename to Analysis/Utkscan/core/include/Notebook.hpp diff --git a/Scan/utkscan/core/include/OutputHisFile.hpp b/Analysis/Utkscan/core/include/OutputHisFile.hpp similarity index 100% rename from Scan/utkscan/core/include/OutputHisFile.hpp rename to Analysis/Utkscan/core/include/OutputHisFile.hpp diff --git a/Scan/utkscan/core/include/PlaceBuilder.hpp b/Analysis/Utkscan/core/include/PlaceBuilder.hpp similarity index 100% rename from Scan/utkscan/core/include/PlaceBuilder.hpp rename to Analysis/Utkscan/core/include/PlaceBuilder.hpp diff --git a/Scan/utkscan/core/include/Places.hpp b/Analysis/Utkscan/core/include/Places.hpp similarity index 100% rename from Scan/utkscan/core/include/Places.hpp rename to Analysis/Utkscan/core/include/Places.hpp diff --git a/Scan/utkscan/core/include/Plots.hpp b/Analysis/Utkscan/core/include/Plots.hpp similarity index 100% rename from Scan/utkscan/core/include/Plots.hpp rename to Analysis/Utkscan/core/include/Plots.hpp diff --git a/Scan/utkscan/core/include/PlotsRegister.hpp b/Analysis/Utkscan/core/include/PlotsRegister.hpp similarity index 100% rename from Scan/utkscan/core/include/PlotsRegister.hpp rename to Analysis/Utkscan/core/include/PlotsRegister.hpp diff --git a/Scan/utkscan/core/include/RandomPool.hpp b/Analysis/Utkscan/core/include/RandomPool.hpp similarity index 100% rename from Scan/utkscan/core/include/RandomPool.hpp rename to Analysis/Utkscan/core/include/RandomPool.hpp diff --git a/Scan/utkscan/core/include/RawEvent.hpp b/Analysis/Utkscan/core/include/RawEvent.hpp similarity index 99% rename from Scan/utkscan/core/include/RawEvent.hpp rename to Analysis/Utkscan/core/include/RawEvent.hpp index a17b14e35..e9ea26d82 100644 --- a/Scan/utkscan/core/include/RawEvent.hpp +++ b/Analysis/Utkscan/core/include/RawEvent.hpp @@ -17,8 +17,6 @@ #include #include -#include "pixie16app_defs.h" - #include "Globals.hpp" #include "DetectorSummary.hpp" #include "ChanEvent.hpp" diff --git a/Scan/utkscan/core/include/SheCorrelator.hpp b/Analysis/Utkscan/core/include/SheCorrelator.hpp similarity index 100% rename from Scan/utkscan/core/include/SheCorrelator.hpp rename to Analysis/Utkscan/core/include/SheCorrelator.hpp diff --git a/Scan/utkscan/core/include/StatsData.hpp b/Analysis/Utkscan/core/include/StatsData.hpp similarity index 100% rename from Scan/utkscan/core/include/StatsData.hpp rename to Analysis/Utkscan/core/include/StatsData.hpp diff --git a/Scan/utkscan/core/include/TimingCalibrator.hpp b/Analysis/Utkscan/core/include/TimingCalibrator.hpp similarity index 100% rename from Scan/utkscan/core/include/TimingCalibrator.hpp rename to Analysis/Utkscan/core/include/TimingCalibrator.hpp diff --git a/Scan/utkscan/core/include/TimingMapBuilder.hpp b/Analysis/Utkscan/core/include/TimingMapBuilder.hpp similarity index 100% rename from Scan/utkscan/core/include/TimingMapBuilder.hpp rename to Analysis/Utkscan/core/include/TimingMapBuilder.hpp diff --git a/Scan/utkscan/core/include/Trace.hpp b/Analysis/Utkscan/core/include/Trace.hpp similarity index 70% rename from Scan/utkscan/core/include/Trace.hpp rename to Analysis/Utkscan/core/include/Trace.hpp index ad4d3a8ab..131d80389 100644 --- a/Scan/utkscan/core/include/Trace.hpp +++ b/Analysis/Utkscan/core/include/Trace.hpp @@ -20,47 +20,47 @@ #include "PlotsRegister.hpp" //! \brief Store the information for a trace -class Trace : public std::vector { +class Trace : public std::vector { public: /** Default constructor */ - Trace() : std::vector() {} + Trace() : std::vector() {} /** An automatic conversion for the trace * \param [in] x : the trace to store in the class */ - Trace(const std::vector &x) : std::vector(x) {} + Trace(const std::vector &x) : std::vector(x) {} /** Insert a value into the trace map * \param [in] name : the name of the parameter to insert * \param [in] value : the value to insert into the map */ void InsertValue(const std::string &name, const double &value) { - doubleTraceData.insert(make_pair(name,value)); + doubleTraceData.insert(make_pair(name, value)); } /** Insert an int value into the trace * \param [in] name : the name of the variable to insert * \param [in] value : The integer value to insert into the map */ void InsertValue(const std::string &name, const int &value) { - intTraceData.insert(make_pair(name,value)); + intTraceData.insert(make_pair(name, value)); } /** Set the double value of a parameter in the trace * \param [in] name : the name of the parameter to set * \param [in] value : the double value to set the parameter to */ void SetValue(const std::string &name, const double &value) { - if(doubleTraceData.count(name) > 0) + if (doubleTraceData.count(name) > 0) doubleTraceData[name] = value; else - InsertValue(name,value); + InsertValue(name, value); } /** Set the integer value of a parameter in the trace * \param [in] name : the name of the parameter to set * \param [in] value : the int value to set the parameter to */ void SetValue(const std::string &name, const int &value) { - if(intTraceData.count(name) > 0) + if (intTraceData.count(name) > 0) intTraceData[name] = value; else - InsertValue(name,value); + InsertValue(name, value); } /** Checks to see if a parameter has a value @@ -75,21 +75,37 @@ class Trace : public std::vector { * \param [in] name : the name of the parameter to get for * \return the requested value */ double GetValue(const std::string &name) const { - if(doubleTraceData.count(name) > 0) + if (doubleTraceData.count(name) > 0) return (*doubleTraceData.find(name)).second; - if(intTraceData.count(name) > 0) + if (intTraceData.count(name) > 0) return (*intTraceData.find(name)).second; - return(NAN); + return (NAN); } /** \return Returns the waveform found inside the trace */ - std::vector GetWaveform() {return(waveform_);} + std::vector GetWaveform() { + return std::vector(baselineSubTrace_.begin() + + waveformRange_.first, + baselineSubTrace_.begin() + + waveformRange_.second); + } + + ///@return Returns the waveform that still has the baseline + std::vector GetWaveformWithBaseline() { + return std::vector(begin() + waveformRange_.first, + begin() + waveformRange_.second); + } + + ///@return Returns the waveform that still has the baseline + std::vector GetBaselineSubtractedTrace() { + return baselineSubTrace_; + } /*! \brief Declares a 1D histogram calls the C++ wrapper for DAMM * \param [in] dammId : The histogram number to define * \param [in] xSize : The range of the x-axis * \param [in] title : The title for the histogram */ - virtual void DeclareHistogram1D(int dammId, int xSize, const char* title) { + virtual void DeclareHistogram1D(int dammId, int xSize, const char *title) { histo.DeclareHistogram1D(dammId, xSize, title); } @@ -99,7 +115,7 @@ class Trace : public std::vector { * \param [in] ySize : The range of the y-axis * \param [in] title : The title of the histogram */ virtual void DeclareHistogram2D(int dammId, int xSize, int ySize, - const char* title) { + const char *title) { histo.DeclareHistogram2D(dammId, xSize, ySize, title); } @@ -113,56 +129,75 @@ class Trace : public std::vector { * \param [in] val3 : The z value to plot (if 2D histogram) * \param [in] name : The name of the histogram */ virtual void plot(int dammId, double val1, double val2 = -1, - double val3 = -1, const char* name="h") const { + double val3 = -1, const char *name = "h") const { histo.Plot(dammId, val1, val2, val3, name); } /** plot trace into a 1D histogram * \param [in] id : histogram ID to plot into */ void Plot(int id); + /** plot trace into row of a 2D histogram * \param [in] id : histogram ID to plot into * \param [in] row : the row to plot into */ void Plot(int id, int row); + /** plot trace absolute value and scaled into a 1D histogram * \param [in] id : histogram ID to plot into * \param [in] scale : the scaling for the trace */ void ScalePlot(int id, double scale); + /** plot trace absolute value and scaled into a 2D histogram * \param [in] id : histogram ID to plot into * \param [in] row : the row to plot the histogram into * \param [in] scale : the scaling for the trace */ void ScalePlot(int id, int row, double scale); + /** plot trace with a vertical offset in a 1D histogram * \param [in] id : histogram ID to plot into * \param [in] offset : the offset for the trace */ void OffsetPlot(int id, double offset); + /** plot trace with a vertical offset in a 2D histogram * \param [in] id : histogram ID to plot into * \param [in] row : the row to plot the trace into * \param [in] offset : the offset for the trace*/ void OffsetPlot(int id, int row, double offset); - /** sets the waveform - * \param[in] a : the vector with the waveform */ - void SetWaveform(const std::vector &a){waveform_ = a;} - /** sets the trigger filter if we are using the TriggerFilterAnalyzer + /** sets the waveform low and high bounds. + * \param[in] a : the range we want to set */ + void SetWaveformRange(const std::pair &a) { + waveformRange_ = a; + } + + ///@brief sets the baseline subtracted trace for use. + ///@param[in] a : The vector that we are going to assign. + void SetBaselineSubtractedTrace(const std::vector &a) { + baselineSubTrace_ = a; + } + + /** sets the trigger filter if we are using the TriggerFilterAnalyzer * \param [in] a : the vector with the trigger filter */ - void SetTriggerFilter(const std::vector &a){trigFilter_ = a;} - /** sets the energy sums vector if we are using the TriggerFilterAnalyzer - * \param [in] a : the vector of energy sums */ - void SetEnergySums(const std::vector &a){esums_ = a;} + void SetTriggerFilter(const std::vector &a) { trigFilter_ = a; } + + /** sets the energy sums vector if we are using the TriggerFilterAnalyzer + * \param [in] a : the vector of energy sums */ + void SetEnergySums(const std::vector &a) { esums_ = a; } private: - std::vector waveform_; //!< The waveform inside the trace + //!< The range of the waveform. + std::pair waveformRange_; + + std::vector baselineSubTrace_; ///!< Baseline subtracted trace std::vector trigFilter_; //!< The trigger filter for the trace std::vector esums_; //!< The Energy sums calculated from the trace std::map doubleTraceData; //!< Trace data stored as doubles - std::map intTraceData;//!< Trace data stored as ints + std::map intTraceData;//!< Trace data stored as ints /** This field is static so all instances of Trace class have access to * the same plots and plots range. */ static Plots histo; }; + #endif // __TRACE_H_ diff --git a/Scan/utkscan/core/include/TreeCorrelator.hpp b/Analysis/Utkscan/core/include/TreeCorrelator.hpp similarity index 100% rename from Scan/utkscan/core/include/TreeCorrelator.hpp rename to Analysis/Utkscan/core/include/TreeCorrelator.hpp diff --git a/Scan/utkscan/core/include/UtkScanInterface.hpp b/Analysis/Utkscan/core/include/UtkScanInterface.hpp similarity index 100% rename from Scan/utkscan/core/include/UtkScanInterface.hpp rename to Analysis/Utkscan/core/include/UtkScanInterface.hpp diff --git a/Scan/utkscan/core/include/UtkUnpacker.hpp b/Analysis/Utkscan/core/include/UtkUnpacker.hpp similarity index 100% rename from Scan/utkscan/core/include/UtkUnpacker.hpp rename to Analysis/Utkscan/core/include/UtkUnpacker.hpp diff --git a/Scan/utkscan/core/include/WalkCorrector.hpp b/Analysis/Utkscan/core/include/WalkCorrector.hpp similarity index 93% rename from Scan/utkscan/core/include/WalkCorrector.hpp rename to Analysis/Utkscan/core/include/WalkCorrector.hpp index 9bb738bff..582e6a240 100644 --- a/Scan/utkscan/core/include/WalkCorrector.hpp +++ b/Analysis/Utkscan/core/include/WalkCorrector.hpp @@ -46,8 +46,9 @@ class WalkCorrector { * \param[in] min : The lower bound of the correction range * \param[in] max : The upper bound of the correction range * \param[in] par : The vector of parameters to use for the calibration */ - void AddChannel(const Identifier& chanID, const std::string model, - double min, double max, const std::vector& par); + void AddChannel(const Identifier &chanID, const std::string &model, + const double &min, const double &max, + const std::vector &par); /** Returns time correction that should be subtracted from * the raw time. The channel is identified by Identifier class, @@ -60,12 +61,7 @@ class WalkCorrector { * \return The walk corrected value of raw */ double GetCorrection(Identifier& chanID, double raw) const; -private: - /** Map where key is a channel Identifier - * and value is a vector holding struct with calibration range - * and walk correction model and parameters. */ - std::map > channels_; - +protected: /** \return always 0. * Use if you want to switch off the correction. Also not adding * the channel to the list results in returning 0 from GetCorrection @@ -80,7 +76,7 @@ class WalkCorrector { * \param [in] par : the vector of parameters for calibration * \param [in] raw : the raw value to calibrate * \return The corrected time in pixie units */ - double Model_A(const std::vector& par, double raw) const; + double Model_A(const std::vector &par, const double &raw) const; /** This model was developed for the 93Br experiment * f(x) = a0 + a1 * x + a2 * x^2 + a3 * x^3 + @@ -106,19 +102,19 @@ class WalkCorrector { * \return corrected time in pixie units */ double Model_B2(const std::vector& par, double raw) const; - /** The correction for Small VANDLE bars + /** The correction for Small VANDLE bars * the returned value is in ns * \param [in] par : the vector of parameters for calibration * \param [in] raw : the raw value to calibrate * \return corrected time in ns */ double Model_VS(const std::vector& par, double raw) const; - /** The correction for Medium VANDLE bars + /** The correction for Medium VANDLE bars * the returned value is in ns * \param [in] par : the vector of parameters for calibration * \param [in] raw : the raw value to calibrate * \return corrected time in ns */ double Model_VM(const std::vector& par, double raw) const; - /** The correction for Large VANDLE bars + /** The correction for Large VANDLE bars * the returned value is in ns * \param [in] par : the vector of parameters for calibration * \param [in] raw : the raw value to calibrate @@ -136,5 +132,10 @@ class WalkCorrector { * \param [in] raw : the raw value to calibrate * \return corrected time in ns */ double Model_VD(const std::vector& par, double raw) const; +private: + /** Map where key is a channel Identifier + * and value is a vector holding struct with calibration range + * and walk correction model and parameters. */ + std::map > channels_; }; #endif diff --git a/Scan/utkscan/core/source/BarBuilder.cpp b/Analysis/Utkscan/core/source/BarBuilder.cpp similarity index 100% rename from Scan/utkscan/core/source/BarBuilder.cpp rename to Analysis/Utkscan/core/source/BarBuilder.cpp diff --git a/Scan/utkscan/core/source/CMakeLists.txt b/Analysis/Utkscan/core/source/CMakeLists.txt similarity index 81% rename from Scan/utkscan/core/source/CMakeLists.txt rename to Analysis/Utkscan/core/source/CMakeLists.txt index 730c3526f..c291d0414 100644 --- a/Scan/utkscan/core/source/CMakeLists.txt +++ b/Analysis/Utkscan/core/source/CMakeLists.txt @@ -20,12 +20,6 @@ set(CORE_SOURCES WalkCorrector.cpp ) -if(NOT USE_HRIBF) - set(CORE_SOURCES ${CORE_SOURCES} utkscan.cpp HisFile.cpp) -else(USE_HRIBF) - set(CORE_SOURCES ${CORE_SOURCES} utkscanor.cpp) -endif(NOT USE_HRIBF) - set (CORRELATION_SOURCES PlaceBuilder.cpp Places.cpp @@ -37,13 +31,16 @@ set (PLOTTING_SOURCES PlotsRegister.cpp ) -set (XMLPARSER_SOURCES - pugixml.cpp -) +if(NOT USE_HRIBF) + set(MAIN_SOURCES utkscan.cpp HisFile.cpp) +else(USE_HRIBF) + set(MAIN_SOURCES utkscanor.cpp) +endif(NOT USE_HRIBF) + +add_library(MainObjects OBJECT ${MAIN_SOURCES}) add_library(CoreObjects OBJECT ${CORE_SOURCES} ${CORRELATION_SOURCES} ${PLOTTING_SOURCES} - ${XMLPARSER_SOURCES} ) diff --git a/Scan/utkscan/core/source/Calibrator.cpp b/Analysis/Utkscan/core/source/Calibrator.cpp similarity index 100% rename from Scan/utkscan/core/source/Calibrator.cpp rename to Analysis/Utkscan/core/source/Calibrator.cpp diff --git a/Scan/utkscan/core/source/ChanEvent.cpp b/Analysis/Utkscan/core/source/ChanEvent.cpp similarity index 74% rename from Scan/utkscan/core/source/ChanEvent.cpp rename to Analysis/Utkscan/core/source/ChanEvent.cpp index 6aa85f1e7..0850322c0 100644 --- a/Scan/utkscan/core/source/ChanEvent.cpp +++ b/Analysis/Utkscan/core/source/ChanEvent.cpp @@ -19,7 +19,7 @@ void ChanEvent::ZeroNums() { calTime = -1; correctedTime = -1; highResTime = -1; - + trigTime = pixie::U_DELIMITER; runTime0 = pixie::U_DELIMITER; runTime1 = pixie::U_DELIMITER; @@ -27,17 +27,17 @@ void ChanEvent::ZeroNums() { } unsigned long ChanEvent::GetQdcValue(int i) const { - if (i < 0 || i >= data_.numQdcs) - return pixie::U_DELIMITER; - return data_.qdcValue[i]; + return data_.GetQdc()[i]; } const Identifier& ChanEvent::GetChanID() const { - return DetectorLibrary::get()->at(data_.modNum, data_.chanNum); + return DetectorLibrary::get()->at(data_.GetModuleNumber(), + data_.GetChannelNumber()); } int ChanEvent::GetID() const { - return DetectorLibrary::get()->GetIndex(data_.modNum, data_.chanNum); + return (int)DetectorLibrary::get()->GetIndex(data_.GetModuleNumber(), + data_.GetChannelNumber()); } //! [Zero Channel] diff --git a/Scan/utkscan/core/source/Correlator.cpp b/Analysis/Utkscan/core/source/Correlator.cpp similarity index 100% rename from Scan/utkscan/core/source/Correlator.cpp rename to Analysis/Utkscan/core/source/Correlator.cpp diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Analysis/Utkscan/core/source/DetectorDriver.cpp similarity index 93% rename from Scan/utkscan/core/source/DetectorDriver.cpp rename to Analysis/Utkscan/core/source/DetectorDriver.cpp index 311a335db..406c9377d 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Analysis/Utkscan/core/source/DetectorDriver.cpp @@ -11,17 +11,33 @@ #include #include +//This header is for decoding the XML +///@TODO The XML decoding should be moved out of this file and into a +/// dedicated class. #include "pugixml.hpp" +//These headers are core headers and are needed for basic functionality #include "DammPlotIds.hpp" #include "DetectorDriver.hpp" #include "DetectorLibrary.hpp" +#include "Display.h" #include "Exceptions.hpp" #include "HighResTimingData.hpp" #include "RandomPool.hpp" #include "RawEvent.hpp" #include "TreeCorrelator.hpp" +//These headers handle trace analysis +#include "CfdAnalyzer.hpp" +#include "FittingAnalyzer.hpp" +#include "TauAnalyzer.hpp" +#include "TraceAnalyzer.hpp" +#include "TraceExtractor.hpp" +#include "TraceFilterAnalyzer.hpp" +#include "WaaAnalyzer.hpp" +#include "WaveformAnalyzer.hpp" + +//These headers handle processing of specific detector types #include "BetaScintProcessor.hpp" #include "DoubleBetaProcessor.hpp" #include "Hen3Processor.hpp" @@ -40,19 +56,15 @@ #include "VandleProcessor.hpp" #include "ValidProcessor.hpp" -#include "CfdAnalyzer.hpp" -#include "FittingAnalyzer.hpp" -#include "TauAnalyzer.hpp" -#include "TraceAnalyzer.hpp" -#include "TraceExtractor.hpp" -#include "TraceFilterAnalyzer.hpp" -#include "WaaAnalyzer.hpp" -#include "WaveformAnalyzer.hpp" - +//These headers are for handling experiment specific processing. #include "TemplateExpProcessor.hpp" +#include "VandleOrnl2012Processor.hpp" -#ifdef useroot +#ifdef useroot //Some processors REQURE ROOT to function +#include "Anl1471Processor.hpp" +#include "IS600Processor.hpp" #include "RootProcessor.hpp" +#include "TwoChanTimingProcessor.hpp" #endif using namespace std; @@ -79,7 +91,7 @@ DetectorDriver::DetectorDriver() : histo(OFFSET, RANGE, "DetectorDriver") { m.fail(); cout << "Exception caught at DetectorDriver::DetectorDriver" << endl; cout << "\t" << e.what() << endl; - exit(EXIT_FAILURE); + throw; } catch (GeneralWarning &w) { cout << "Warning found at DetectorDriver::DetectorDriver" << endl; cout << "\t" << w.what() << endl; @@ -215,15 +227,23 @@ void DetectorDriver::LoadProcessors(Messenger& m) { vecProcess.push_back(new TemplateProcessor()); } else if (name == "TemplateExpProcessor") { vecProcess.push_back(new TemplateExpProcessor()); - } -#ifdef useroot - else if (name == "RootProcessor") { + } +#ifdef useroot //Certain process REQURE root to actually work + else if (name == "Anl1471Processor") { + vecProcess.push_back(new Anl1471Processor()); + } else if (name == "TwoChanTimingProcessor") { + vecProcess.push_back(new TwoChanTimingProcessor()); + } else if (name == "IS600Processor") { + vecProcess.push_back(new IS600Processor()); + } else if (name == "VandleOrnl2012Processor") { + vecProcess.push_back(new VandleOrnl2012Processor()); + } else if (name == "RootProcessor") { vecProcess.push_back(new RootProcessor("tree.root", "tree")); } #endif else { stringstream ss; - ss << "DetectorDriver: unknown processor type" << name; + ss << "DetectorDriver: unknown processor type : " << name; throw GeneralException(ss.str()); } stringstream ss; @@ -256,7 +276,8 @@ void DetectorDriver::LoadProcessors(Messenger& m) { } else if (name == "WaveformAnalyzer") { vecAnalyzer.push_back(new WaveformAnalyzer()); } else if (name == "CfdAnalyzer") { - vecAnalyzer.push_back(new CfdAnalyzer()); + string type = analyzer.attribute("type").as_string(); + vecAnalyzer.push_back(new CfdAnalyzer(type)); } else if (name == "WaaAnalyzer") { vecAnalyzer.push_back(new WaaAnalyzer()); } else if (name == "FittingAnalyzer") { @@ -320,7 +341,7 @@ void DetectorDriver::ProcessEvent(RawEvent& rawev) { PlotCal((*it)); string place = (*it)->GetChanID().GetPlaceName(); - if (place == "__-1") + if (place == "__9999") continue; if ( (*it)->IsSaturated() || (*it)->IsPileup() ) @@ -355,12 +376,15 @@ void DetectorDriver::ProcessEvent(RawEvent& rawev) { } catch (GeneralException &e) { /// Any exception in activation of basic places, PreProcess and Process /// will be intercepted here - cout << "Exception caught at DetectorDriver::ProcessEvent" << endl; - cout << "\t" << e.what() << endl; - exit(EXIT_FAILURE); + cout << endl + << Display::ErrorStr("Exception caught at DetectorDriver::ProcessEvent") + << endl; + throw; } catch (GeneralWarning &w) { - cout << "Warning caught at DetectorDriver::ProcessEvent" << endl; - cout << "\t" << w.what() << endl; + cout << Display::WarningStr("Warning caught at " + "DetectorDriver::ProcessEvent") + << endl; + cout << "\t" << Display::WarningStr(w.what()) << endl; } } @@ -426,9 +450,10 @@ void DetectorDriver::DeclarePlots() { (*it)->DeclarePlots(); } } catch (exception &e) { - cout << "Exception caught at DetectorDriver::DeclarePlots" << endl; - cout << "\t" << e.what() << endl; - exit(EXIT_FAILURE); + cout << Display::ErrorStr("Exception caught at " + "DetectorDriver::DeclarePlots") + << endl; + throw; } } diff --git a/Scan/utkscan/core/source/DetectorLibrary.cpp b/Analysis/Utkscan/core/source/DetectorLibrary.cpp similarity index 86% rename from Scan/utkscan/core/source/DetectorLibrary.cpp rename to Analysis/Utkscan/core/source/DetectorLibrary.cpp index facd3262f..927ec424d 100644 --- a/Scan/utkscan/core/source/DetectorLibrary.cpp +++ b/Analysis/Utkscan/core/source/DetectorLibrary.cpp @@ -31,7 +31,6 @@ DetectorLibrary* DetectorLibrary::get() { DetectorLibrary::DetectorLibrary() : vector(), locations(), numModules(0) { - GetKnownDetectors(); LoadXml(); /* At this point basic Correlator places build automatically from * map file should be created so we can call buildTree function */ @@ -213,23 +212,8 @@ bool DetectorLibrary::HasValue(int index) const { } void DetectorLibrary::Set(int index, const Identifier& value) { - /// Search the list of known detectors; if the detector type - /// is not matched, print out an error message and terminate - if (knownDetectors.find(value.GetType()) == knownDetectors.end()) { - stringstream ss; - ss << "The detector called '" << value.GetType() << "'" - << "read in from the file 'map2.txt' " - << "is unknown to this program!. This is a " - << "fatal error. Program execution halted! " - << "If you believe this detector should exist, " - << "please edit the 'getKnownDetectors' " - << "function inside the 'DetectorLibrary.cpp' file." - << endl; - ss << "The currently known detectors include:" << endl; - copy(knownDetectors.begin(), knownDetectors.end(), - ostream_iterator(ss, " ")); - throw GeneralException(ss.str()); - } + if (knownDetectors.find(value.GetType()) == knownDetectors.end()) + knownDetectors.insert(value.GetType()); unsigned int module = ModuleFromIndex(index); if (module >= numModules ) { @@ -289,25 +273,6 @@ void DetectorLibrary::PrintUsedDetectors(RawEvent& rawev) const { rawev.Init(usedTypes); } -const set& DetectorLibrary::GetKnownDetectors(void) { - const unsigned int detTypes = 25; - const string detectorStrings[detTypes] = { - "3hen", "beta", "dssd_front", "dssd_back", "ge", "generic", - "idssd_front", "ignore", "ion_chamber", "liquid", "logic", - "mcp", "mtc", "neutron_scint", "position", "pulser", "si", "ssd", - "timeclass", "tvandle", "vandle", "beta_scint", "labr3", "pspmt", - "template" - }; - - if (!knownDetectors.empty()) - return knownDetectors; - - for (unsigned int i=0; i < detTypes; i++) - knownDetectors.insert(detectorStrings[i]); - - return knownDetectors; -} - const set& DetectorLibrary::GetUsedDetectors(void) const { return usedTypes; } diff --git a/Scan/utkscan/core/source/DetectorSummary.cpp b/Analysis/Utkscan/core/source/DetectorSummary.cpp similarity index 100% rename from Scan/utkscan/core/source/DetectorSummary.cpp rename to Analysis/Utkscan/core/source/DetectorSummary.cpp diff --git a/Scan/utkscan/core/source/Globals.cpp b/Analysis/Utkscan/core/source/Globals.cpp similarity index 94% rename from Scan/utkscan/core/source/Globals.cpp rename to Analysis/Utkscan/core/source/Globals.cpp index 8d9b429b2..cf62b2e66 100644 --- a/Scan/utkscan/core/source/Globals.cpp +++ b/Analysis/Utkscan/core/source/Globals.cpp @@ -54,17 +54,14 @@ Globals::Globals(const std::string &file) { clockInSeconds_ = 10e-9; adcClockInSeconds_ = 10e-9; filterClockInSeconds_ = 10e-9; - maxWords_ = IO_BUFFER_LENGTH; } else if (revision_ == "D") { clockInSeconds_ = 10e-9; adcClockInSeconds_ = 10e-9; filterClockInSeconds_ = 10e-9; - maxWords_ = EXTERNAL_FIFO_LENGTH; } else if (revision_ == "F" || revision_ == "DF") { clockInSeconds_ = 8e-9; adcClockInSeconds_ = 4e-9; filterClockInSeconds_ = 8e-9; - maxWords_ = EXTERNAL_FIFO_LENGTH; } else { throw GeneralException("Globals: unknown revision version " + revision_); @@ -200,6 +197,20 @@ Globals::Globals(const std::string &file) { WarnOfUnknownParameter(m, it); } + pugi::xml_node cfd = doc.child("Configuration").child("Cfd"); + for (pugi::xml_node_iterator it = cfd.begin(); it != cfd.end(); ++it) { + if (std::string(it->name()).compare("Parameters") == 0) { + for (pugi::xml_node_iterator parit = it->begin(); + parit != it->end(); ++parit) { + fitPars_.insert( + std::make_pair(parit->attribute("name").as_string(), + std::make_pair(parit->child("Fraction").attribute("value").as_double(0.), + parit->child("Delay").attribute("value").as_double(0.)))); + } + } else + WarnOfUnknownParameter(m, it); + } + pugi::xml_node fit = doc.child("Configuration").child("Fitting"); for (pugi::xml_node_iterator it = fit.begin(); it != fit.end(); ++it) { if (std::string(it->name()).compare("SigmaBaselineThresh") == 0) diff --git a/Scan/utkscan/core/source/HisFile.cpp b/Analysis/Utkscan/core/source/HisFile.cpp similarity index 100% rename from Scan/utkscan/core/source/HisFile.cpp rename to Analysis/Utkscan/core/source/HisFile.cpp diff --git a/Scan/utkscan/core/source/Identifier.cpp b/Analysis/Utkscan/core/source/Identifier.cpp similarity index 61% rename from Scan/utkscan/core/source/Identifier.cpp rename to Analysis/Utkscan/core/source/Identifier.cpp index a44b3684b..7235cfb31 100644 --- a/Scan/utkscan/core/source/Identifier.cpp +++ b/Analysis/Utkscan/core/source/Identifier.cpp @@ -10,21 +10,19 @@ using namespace std; int Identifier::GetTag(const std::string &s) const { - map::const_iterator it = tag.find(s); - - if (it == tag.end()) { + map::const_iterator it = tag_.find(s); + if (it == tag_.end()) return(std::numeric_limits::max()); - } return it->second; } void Identifier::Zero() { - dammID = -1; - location = -1; - type = ""; - subtype = ""; + dammID_ = 9999; + location_ = 9999; + type_ = ""; + subtype_ = ""; - tag.clear(); + tag_.clear(); } void Identifier::PrintHeaders(void) { @@ -36,14 +34,14 @@ void Identifier::PrintHeaders(void) { } void Identifier::Print(void) const { - cout << setw(10) << type - << setw(10) << subtype - << setw(4) << location - << setw(6) << dammID + cout << setw(10) << type_ + << setw(10) << subtype_ + << setw(4) << location_ + << setw(6) << dammID_ << " "; - for (map::const_iterator it = tag.begin(); - it != tag.end(); it++) { - if (it != tag.begin()) + for (map::const_iterator it = tag_.begin(); + it != tag_.end(); it++) { + if (it != tag_.begin()) cout << ", "; cout << it->first << "=" << it->second; } diff --git a/Scan/utkscan/core/source/Messenger.cpp b/Analysis/Utkscan/core/source/Messenger.cpp similarity index 100% rename from Scan/utkscan/core/source/Messenger.cpp rename to Analysis/Utkscan/core/source/Messenger.cpp diff --git a/Scan/utkscan/core/source/Notebook.cpp b/Analysis/Utkscan/core/source/Notebook.cpp similarity index 100% rename from Scan/utkscan/core/source/Notebook.cpp rename to Analysis/Utkscan/core/source/Notebook.cpp diff --git a/Scan/utkscan/core/source/OutputHisFile.cpp b/Analysis/Utkscan/core/source/OutputHisFile.cpp similarity index 100% rename from Scan/utkscan/core/source/OutputHisFile.cpp rename to Analysis/Utkscan/core/source/OutputHisFile.cpp diff --git a/Scan/utkscan/core/source/PlaceBuilder.cpp b/Analysis/Utkscan/core/source/PlaceBuilder.cpp similarity index 100% rename from Scan/utkscan/core/source/PlaceBuilder.cpp rename to Analysis/Utkscan/core/source/PlaceBuilder.cpp diff --git a/Scan/utkscan/core/source/Places.cpp b/Analysis/Utkscan/core/source/Places.cpp similarity index 100% rename from Scan/utkscan/core/source/Places.cpp rename to Analysis/Utkscan/core/source/Places.cpp diff --git a/Scan/utkscan/core/source/Plots.cpp b/Analysis/Utkscan/core/source/Plots.cpp similarity index 100% rename from Scan/utkscan/core/source/Plots.cpp rename to Analysis/Utkscan/core/source/Plots.cpp diff --git a/Scan/utkscan/core/source/PlotsRegister.cpp b/Analysis/Utkscan/core/source/PlotsRegister.cpp similarity index 100% rename from Scan/utkscan/core/source/PlotsRegister.cpp rename to Analysis/Utkscan/core/source/PlotsRegister.cpp diff --git a/Scan/utkscan/core/source/RandomPool.cpp b/Analysis/Utkscan/core/source/RandomPool.cpp similarity index 100% rename from Scan/utkscan/core/source/RandomPool.cpp rename to Analysis/Utkscan/core/source/RandomPool.cpp diff --git a/Scan/utkscan/core/source/RawEvent.cpp b/Analysis/Utkscan/core/source/RawEvent.cpp similarity index 100% rename from Scan/utkscan/core/source/RawEvent.cpp rename to Analysis/Utkscan/core/source/RawEvent.cpp diff --git a/Scan/utkscan/core/source/ReadBuffDataA.cpp b/Analysis/Utkscan/core/source/ReadBuffDataA.cpp similarity index 100% rename from Scan/utkscan/core/source/ReadBuffDataA.cpp rename to Analysis/Utkscan/core/source/ReadBuffDataA.cpp diff --git a/Scan/utkscan/core/source/ReadBuffDataD.cpp b/Analysis/Utkscan/core/source/ReadBuffDataD.cpp similarity index 100% rename from Scan/utkscan/core/source/ReadBuffDataD.cpp rename to Analysis/Utkscan/core/source/ReadBuffDataD.cpp diff --git a/Scan/utkscan/core/source/ReadBuffDataF.cpp b/Analysis/Utkscan/core/source/ReadBuffDataF.cpp similarity index 100% rename from Scan/utkscan/core/source/ReadBuffDataF.cpp rename to Analysis/Utkscan/core/source/ReadBuffDataF.cpp diff --git a/Scan/utkscan/core/source/StatsData.cpp b/Analysis/Utkscan/core/source/StatsData.cpp similarity index 100% rename from Scan/utkscan/core/source/StatsData.cpp rename to Analysis/Utkscan/core/source/StatsData.cpp diff --git a/Scan/utkscan/core/source/TimingCalibrator.cpp b/Analysis/Utkscan/core/source/TimingCalibrator.cpp similarity index 100% rename from Scan/utkscan/core/source/TimingCalibrator.cpp rename to Analysis/Utkscan/core/source/TimingCalibrator.cpp diff --git a/Scan/utkscan/core/source/TimingMapBuilder.cpp b/Analysis/Utkscan/core/source/TimingMapBuilder.cpp similarity index 100% rename from Scan/utkscan/core/source/TimingMapBuilder.cpp rename to Analysis/Utkscan/core/source/TimingMapBuilder.cpp diff --git a/Scan/utkscan/core/source/Trace.cpp b/Analysis/Utkscan/core/source/Trace.cpp similarity index 76% rename from Scan/utkscan/core/source/Trace.cpp rename to Analysis/Utkscan/core/source/Trace.cpp index 05889703c..08edeaa83 100644 --- a/Scan/utkscan/core/source/Trace.cpp +++ b/Analysis/Utkscan/core/source/Trace.cpp @@ -21,36 +21,36 @@ Plots Trace::histo(dammIds::trace::OFFSET, dammIds::trace::RANGE, "traces"); void Trace::Plot(int id) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, 1, at(i)); + histo.Plot(id, i, 1, (int)at(i)); } } void Trace::Plot(int id, int row) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, row, at(i)); + histo.Plot(id, i, row, (int)at(i)); } } void Trace::ScalePlot(int id, double scale) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, 1, abs(at(i)) / scale); + histo.Plot(id, i, 1, abs((int)at(i)) / scale); } } void Trace::ScalePlot(int id, int row, double scale) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, row, abs(at(i)) / scale); + histo.Plot(id, i, row, abs((int)at(i)) / scale); } } void Trace::OffsetPlot(int id, double offset) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, 1, max(0., at(i) - offset)); + histo.Plot(id, i, 1, max(0., (int)at(i) - offset)); } } void Trace::OffsetPlot(int id, int row, double offset) { for (size_type i=0; i < size(); i++) { - histo.Plot(id, i, row, max(0., at(i) - offset)); + histo.Plot(id, i, row, max(0., (int)at(i) - offset)); } } diff --git a/Scan/utkscan/core/source/TreeCorrelator.cpp b/Analysis/Utkscan/core/source/TreeCorrelator.cpp similarity index 100% rename from Scan/utkscan/core/source/TreeCorrelator.cpp rename to Analysis/Utkscan/core/source/TreeCorrelator.cpp diff --git a/Scan/utkscan/core/source/UtkScanInterface.cpp b/Analysis/Utkscan/core/source/UtkScanInterface.cpp similarity index 91% rename from Scan/utkscan/core/source/UtkScanInterface.cpp rename to Analysis/Utkscan/core/source/UtkScanInterface.cpp index 30e230f62..3664f6f29 100644 --- a/Scan/utkscan/core/source/UtkScanInterface.cpp +++ b/Analysis/Utkscan/core/source/UtkScanInterface.cpp @@ -1,4 +1,7 @@ +#include + #include "DetectorDriver.hpp" +#include "Display.h" #include "UtkScanInterface.hpp" #include "UtkUnpacker.hpp" @@ -71,10 +74,16 @@ bool UtkScanInterface::Initialize(std::string prefix_) { //This should be cleaned up!! #ifndef USE_HRIBF try { - // Read in the name of the his file. + if(GetOutputFilename() == "") { + throw std::invalid_argument("The output file name was not " + "provided."); + } + output_his = new OutputHisFile(GetOutputFilename().c_str()); output_his->SetDebugMode(false); + Globals::get()->SetOutputFilename(GetOutputFilename()); + /** The DetectorDriver constructor will load processors * from the xml configuration file upon first call. * The DeclarePlots function will instantiate the DetectorLibrary @@ -89,10 +98,9 @@ bool UtkScanInterface::Initialize(std::string prefix_) { DetectorDriver::get()->DeclarePlots(); output_his->Finalize(); } catch (std::exception &e) { - // Any exceptions will be intercepted here - std::cout << prefix_ << "Exception caught at Initialize:" << std::endl; - std::cout << prefix_ << e.what() << std::endl; - exit(EXIT_FAILURE); + std::cout << Display::ErrorStr(prefix_ + "Exception caught at UtkScanInterface::Initialize") + << std::endl; + throw; } #endif return (init_ = true); diff --git a/Scan/utkscan/core/source/UtkUnpacker.cpp b/Analysis/Utkscan/core/source/UtkUnpacker.cpp similarity index 90% rename from Scan/utkscan/core/source/UtkUnpacker.cpp rename to Analysis/Utkscan/core/source/UtkUnpacker.cpp index 1e5919380..1fd7aaf07 100644 --- a/Scan/utkscan/core/source/UtkUnpacker.cpp +++ b/Analysis/Utkscan/core/source/UtkUnpacker.cpp @@ -91,7 +91,7 @@ void UtkUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/) { RawStats((*it), driver); - if ((*it)->getID() == pixie::U_DELIMITER) { + if ((*it)->GetId() == pixie::U_DELIMITER) { ss << "pattern 0 ignore"; m.warning(ss.str()); ss.str(""); @@ -99,32 +99,37 @@ void UtkUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/) { } //Do not input the channel into the list of detectors used in the event - if ((*modChan)[(*it)->getID()].GetType() == "ignore") + if ((*modChan)[(*it)->GetId()].GetType() == "ignore") continue; // Convert an XiaData to a ChanEvent - ChanEvent *event = new ChanEvent((*it)); + ChanEvent *event = new ChanEvent(*(*it)); //Add the ChanEvent pointer to the rawev and used detectors. - usedDetectors.insert((*modChan)[(*it)->getID()].GetType()); + usedDetectors.insert((*modChan)[(*it)->GetId()].GetType()); rawev.AddChan(event); ///@TODO Add back in the processing for the dtime. }//for(deque::iterator - driver->ProcessEvent(rawev); - rawev.Zero(usedDetectors); - usedDetectors.clear(); - - // If a place has a resetable type then reset it. - for (map::iterator it = - TreeCorrelator::get()->places_.begin(); - it != TreeCorrelator::get()->places_.end(); ++it) - if ((*it).second->resetable()) - (*it).second->reset(); + try { + driver->ProcessEvent(rawev); + rawev.Zero(usedDetectors); + usedDetectors.clear(); + + // If a place has a resetable type then reset it. + for (map::iterator it = + TreeCorrelator::get()->places_.begin(); + it != TreeCorrelator::get()->places_.end(); ++it) + if ((*it).second->resetable()) + (*it).second->reset(); + } catch (exception &ex) { + throw; + } eventCounter++; lastTimeOfPreviousEvent = GetRealStopTime(); + } /// This method plots information about the running time of the program, the @@ -134,13 +139,13 @@ void UtkUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/) { /// (milli)second of time. void UtkUnpacker::RawStats(XiaData *event_, DetectorDriver *driver, ScanInterface *addr_) { - int id = event_->getID(); + int id = event_->GetId(); static const int specNoBins = SE; static double runTimeSecs = 0, remainNumSecs = 0; static double runTimeMsecs = 0, remainNumMsecs = 0; static int rowNumSecs = 0, rowNumMsecs = 0; - runTimeSecs = (event_->time - GetFirstTime()) * + runTimeSecs = (event_->GetTime() - GetFirstTime()) * Globals::get()->clockInSeconds(); rowNumSecs = int(runTimeSecs / specNoBins); remainNumSecs = runTimeSecs - rowNumSecs * specNoBins; diff --git a/Scan/utkscan/core/source/WalkCorrector.cpp b/Analysis/Utkscan/core/source/WalkCorrector.cpp similarity index 90% rename from Scan/utkscan/core/source/WalkCorrector.cpp rename to Analysis/Utkscan/core/source/WalkCorrector.cpp index aa8623127..2e0e018c4 100644 --- a/Scan/utkscan/core/source/WalkCorrector.cpp +++ b/Analysis/Utkscan/core/source/WalkCorrector.cpp @@ -10,10 +10,10 @@ using namespace std; -void WalkCorrector::AddChannel(const Identifier& chanID, - const std::string model, - double min, double max, - const std::vector& par) { +void WalkCorrector::AddChannel(const Identifier &chanID, + const std::string &model, + const double &min, const double &max, + const std::vector &par) { CorrectionParams cf; unsigned required_parameters = 0; @@ -158,8 +158,8 @@ double WalkCorrector::Model_None() const { return(0.0); } -double WalkCorrector::Model_A(const std::vector& par, - double raw) const { +double WalkCorrector::Model_A(const std::vector &par, + const double &raw) const { return(par[0] + par[1] / (par[2] + raw) + par[3] * exp(-raw / par[4])); @@ -181,11 +181,11 @@ double WalkCorrector::Model_B2(const std::vector& par, double WalkCorrector::Model_VS(const std::vector &par, double raw) const { if(raw < 175) - return(1.09099*log(raw)-7.76641); + return(1.09099*log(raw)-7.76641); if(raw > 3700) - return(0.0); - return(-(9.13743e-12)*pow(raw,3.) + (1.9485e-7)*pow(raw,2.) - -0.000163286*raw-2.13918); + return(0.0); + return -(9.13743e-12)*pow(raw,3.) + (1.9485e-7)*pow(raw,2.) + -0.000163286*raw-2.13918; } double WalkCorrector::Model_VB(const std::vector &par, @@ -195,9 +195,9 @@ double WalkCorrector::Model_VB(const std::vector &par, double WalkCorrector::Model_VD(const std::vector &par, double raw) const { - return(92.7907602830327 * exp(-raw/186091.225414275) + + return 92.7907602830327 * exp(-raw/186091.225414275) + 0.59140785215161 * exp(raw/2068.14618331387) - - 95.5388835298589); + 95.5388835298589; } double WalkCorrector::Model_VM(const std::vector &par, diff --git a/Scan/utkscan/core/source/utkscan.cpp b/Analysis/Utkscan/core/source/utkscan.cpp similarity index 82% rename from Scan/utkscan/core/source/utkscan.cpp rename to Analysis/Utkscan/core/source/utkscan.cpp index 0b9fc54ae..d3ea3698f 100644 --- a/Scan/utkscan/core/source/utkscan.cpp +++ b/Analysis/Utkscan/core/source/utkscan.cpp @@ -1,6 +1,8 @@ +#include #include // Local files +#include "Display.h" #include "UtkScanInterface.hpp" #include "UtkUnpacker.hpp" @@ -27,7 +29,12 @@ int main(int argc, char *argv[]){ // Run the main loop. cout << "utkscan.cpp : Performing Execute method" << endl; - int retval = scanner.Execute(); + int retval = 0; + try { + retval = scanner.Execute(); + }catch(std::exception &ex) { + cout << Display::ErrorStr(ex.what()) << endl; + } //Cleanup the scanning cout << "utkscan.cpp : Closing things out" << endl; diff --git a/Scan/utkscan/core/source/utkscanor.cpp b/Analysis/Utkscan/core/source/utkscanor.cpp similarity index 100% rename from Scan/utkscan/core/source/utkscanor.cpp rename to Analysis/Utkscan/core/source/utkscanor.cpp diff --git a/Analysis/Utkscan/core/tests/CMakeLists.txt b/Analysis/Utkscan/core/tests/CMakeLists.txt new file mode 100644 index 000000000..24ab9b9e6 --- /dev/null +++ b/Analysis/Utkscan/core/tests/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(unittest-WalkCorrector unittest-WalkCorrector.cpp + ../source/WalkCorrector.cpp ../source/Identifier.cpp) +target_link_libraries(unittest-WalkCorrector UnitTest++ ${LIBS}) +install(TARGETS unittest-WalkCorrector DESTINATION bin/unittests) + +add_executable(unittest-Identifier unittest-Identifier ../source/Identifier.cpp) +target_link_libraries(unittest-Identifier UnitTest++ ${LIBS}) +install(TARGETS unittest-Identifier DESTINATION bin/unittests) \ No newline at end of file diff --git a/Analysis/Utkscan/core/tests/unittest-Identifier.cpp b/Analysis/Utkscan/core/tests/unittest-Identifier.cpp new file mode 100644 index 000000000..08299d619 --- /dev/null +++ b/Analysis/Utkscan/core/tests/unittest-Identifier.cpp @@ -0,0 +1,112 @@ +///@file unittest-Identifier.cpp +///@brief Program that will test functionality of Identifier +///@author S. V. Paulauskas +///@date November 25, 2016 +#include + +#include + +#include + +#include "Identifier.hpp" + +using namespace std; + +///Testing the set/get for the dammid +TEST_FIXTURE(Identifier, Test_GetAndSetDammID) { + unsigned int dammid = 12; + SetDammID(dammid); + CHECK(GetDammID() == dammid); +} + +///Testing the set/get for the location +TEST_FIXTURE(Identifier, Test_GetAndSetLocation) { + unsigned int loc = 111; + SetLocation(loc); + CHECK(GetLocation() == loc); +} + +///Testing the set/get for the type +TEST_FIXTURE(Identifier, Test_GetAndSetType) { + string type = "unittest"; + SetType(type); + CHECK(GetType() == type); +} + +///Testing the set/get for the subtype +TEST_FIXTURE(Identifier, Test_GetAndSetSubtype) { + string type = "unittest"; + SetSubtype(type); + CHECK(GetSubtype() == type); +} + +///Testing the set/get for tags +TEST_FIXTURE(Identifier, Test_GetAndSetTag) { + string tag = "unittest"; + AddTag(tag, 1234); + CHECK(GetTag(tag) == 1234); +} + +///Testing the get for the map of tags +TEST_FIXTURE(Identifier, Test_GetTagMap) { + string tag = "unittest"; + AddTag(tag, 1234); + map testmap; + testmap.insert(make_pair(tag, 1234)); + CHECK(GetTagMap() == testmap); +} + +///Testing for when we have a tag. +TEST_FIXTURE(Identifier, Test_HasTag) { + string tag = "unittest"; + AddTag(tag, 12345); + CHECK(HasTag(tag)); +} + +///Testing the case that we have a missing tag +TEST_FIXTURE(Identifier, Test_HasMissingTag) { + string tag = "unittest"; + CHECK(! HasTag(tag)); +} + +//Check the comparison operators +TEST_FIXTURE(Identifier, Test_Comparison) { + string type = "unit"; + string subtype = "test"; + unsigned int loc = 112; + SetSubtype(subtype); + SetType(type); + SetLocation(loc); + + Identifier id(type, subtype, loc); + + CHECK(*this == id); + + SetLocation(123); + CHECK(*this > id); + + SetLocation(4); + CHECK(*this < id); +} + +///Testing that the place name is returning the proper value +TEST_FIXTURE(Identifier, Test_PlaceName) { + string type = "unit"; + string subtype = "test"; + unsigned int loc = 112; + SetSubtype(subtype); + SetType(type); + SetLocation(loc); + CHECK(GetPlaceName() == "unit_test_112"); +} + +///Test that the zero function is performing it's job properly +TEST_FIXTURE(Identifier, Test_Zero){ + Identifier id("unit", "test", 123); + id.Zero(); + CHECK(*this == id); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} diff --git a/Analysis/Utkscan/core/tests/unittest-WalkCorrector.cpp b/Analysis/Utkscan/core/tests/unittest-WalkCorrector.cpp new file mode 100644 index 000000000..5b7623735 --- /dev/null +++ b/Analysis/Utkscan/core/tests/unittest-WalkCorrector.cpp @@ -0,0 +1,105 @@ +///@file unittest-WalkCorrector.cpp +///@brief Program that will test functionality of the WalkCorrector +///@author S. V. Paulauskas +///@date November 25, 2016 +#include + +#include + +#include + +#include "Identifier.hpp" +#include "WalkCorrector.hpp" + +using namespace std; + +TEST_FIXTURE(WalkCorrector, Test_Model_None) { + CHECK(Model_None() == 0.0); +} + +TEST_FIXTURE(WalkCorrector, Test_ModelA) { + vector par = {0.5,2.1,3.7,0.4,0.1}; + double raw = 20.3; + double expected = par[0] + par[1] / (par[2] + raw) + + par[3] * exp(-raw / par[4]); + double result = Model_A(par, raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_B1) { + vector par = {0.5,2.1,3.7,0.4}; + double raw = 20.3; + double expected = par[0] + (par[1] + par[2] / (raw + 1.0)) * + exp(-raw / par[3]); + double result = Model_B1(par, raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_B2) { + vector par = {0.5,2.1,3.7}; + double raw = 20.3; + double expected = par[0] + par[1] * exp(-raw / par[2]); + double result = Model_B2(par, raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_VS_Low) { + vector par = {0.5,2.1,3.7}; + double raw = 20.3; + double expected = 1.09099*log(raw)-7.76641; + double result = Model_VS(par,raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_VS_High) { + vector par = {0.5,2.1,3.7}; + double raw = 4000; + double expected = 0.0; + double result = Model_VS(par,raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_VS) { + vector par = {0.5,2.1,3.7}; + double raw = 300.; + double expected = -(9.13743e-12)*pow(raw,3.) + (1.9485e-7)*pow(raw,2.) + -0.000163286*raw-2.13918; + double result = Model_VS(par,raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_VB) { + vector par = {0.5,2.1,3.7}; + double raw = 300.; + double expected = -(1.07908*log10(raw)-8.27739); + double result = Model_VB(par,raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_Model_VD) { + vector par = {0.5,2.1,3.7}; + double raw = 300.; + double expected = 92.7907602830327 * exp(-raw/186091.225414275) + + 0.59140785215161 * exp(raw/2068.14618331387) - + 95.5388835298589; + double result = Model_VD(par,raw); + CHECK(result == expected); +} + +TEST_FIXTURE(WalkCorrector, Test_GetCorrection) { + ///Initialize an Identifier object + Identifier id("unit", "test", 3); + double min = 0.0; + double max = 1000.; + vector par = {0.5,2.1,3.7,0.4,0.1}; + double raw = 20.3; + string model = "A"; + double expected = par[0] + par[1] / (par[2] + raw) + + par[3] * exp(-raw / par[4]); + AddChannel(id, "A", min, max, par); + CHECK_EQUAL(expected, GetCorrection(id, raw)); +} + +int main(int argv, char* argc[]) { + return(UnitTest::RunAllTests()); +} diff --git a/Scan/utkscan/experiment/CMakeLists.txt b/Analysis/Utkscan/experiment/CMakeLists.txt similarity index 100% rename from Scan/utkscan/experiment/CMakeLists.txt rename to Analysis/Utkscan/experiment/CMakeLists.txt diff --git a/Scan/utkscan/experiment/include/Anl1471Processor.hpp b/Analysis/Utkscan/experiment/include/Anl1471Processor.hpp similarity index 56% rename from Scan/utkscan/experiment/include/Anl1471Processor.hpp rename to Analysis/Utkscan/experiment/include/Anl1471Processor.hpp index b88c8bd6d..a402e9c66 100644 --- a/Scan/utkscan/experiment/include/Anl1471Processor.hpp +++ b/Analysis/Utkscan/experiment/include/Anl1471Processor.hpp @@ -1,40 +1,39 @@ -/** \file Anl1471Processor.hpp - * \brief A class to process data from the LeRIBSS 2012 campaign. - * - *\author S. V. Paulauskas - *\date September 19, 2015 - */ +///@file Anl1471Processor.hpp +///@brief A class to process data from ANL1471 experiment using VANDLE. +///@author S. Z. Taylor and S. V. Paulauskas +///@date July 14, 2015 #ifndef __ANL1471PROCESSOR_HPP_ #define __ANL1471PROCESSOR_HPP_ +#include #include "EventProcessor.hpp" -#include "VandleProcessor.hpp" -/// Class to process VANDLE related events -class Anl1471Processor : public VandleProcessor { +/// Class to process ANL experiment related events +class Anl1471Processor : public EventProcessor { public: /** Default Constructor */ Anl1471Processor(); /** Default Destructor */ - ~Anl1471Processor() {}; + ~Anl1471Processor(); /** Declare the plots used in the analysis */ virtual void DeclarePlots(void); /** Constructor taking a list of detector types as an argument * \param [in] typeList : the list of bar types that are in the analysis * \param [in] res : The resolution of the DAMM histograms - * \param [in] offset : The offset of the DAMM histograms + + * \param [in] offset : The offset of the DAMM histograms * \param [in] numStarts : number of starts in the analysis */ Anl1471Processor(const std::vector &typeList, - const double &res, const double &offset, - const double &numStarts); + const double &res, const double &offset, + const double &numStarts); /** Process the event * \param [in] event : the event to process * \return Returns true if the processing was successful */ virtual bool Process(RawEvent &event); private: - std::string fileName_; //!< name of the his file - std::vector fileNames_; //!< vector of output file names + std::string fileName_; + std::vector fileNames_; }; -#endif +#endif \ No newline at end of file diff --git a/Scan/utkscan/experiment/include/Beta4Hen3Processor.hpp b/Analysis/Utkscan/experiment/include/Beta4Hen3Processor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/Beta4Hen3Processor.hpp rename to Analysis/Utkscan/experiment/include/Beta4Hen3Processor.hpp diff --git a/Scan/utkscan/experiment/include/CrosstalkProcessor.hpp b/Analysis/Utkscan/experiment/include/CrosstalkProcessor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/CrosstalkProcessor.hpp rename to Analysis/Utkscan/experiment/include/CrosstalkProcessor.hpp diff --git a/Scan/utkscan/experiment/include/Dssd4SHEProcessor.hpp b/Analysis/Utkscan/experiment/include/Dssd4SHEProcessor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/Dssd4SHEProcessor.hpp rename to Analysis/Utkscan/experiment/include/Dssd4SHEProcessor.hpp diff --git a/Scan/utkscan/experiment/include/Ge4Hen3Processor.hpp b/Analysis/Utkscan/experiment/include/Ge4Hen3Processor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/Ge4Hen3Processor.hpp rename to Analysis/Utkscan/experiment/include/Ge4Hen3Processor.hpp diff --git a/Scan/utkscan/experiment/include/IS600Processor.hpp b/Analysis/Utkscan/experiment/include/IS600Processor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/IS600Processor.hpp rename to Analysis/Utkscan/experiment/include/IS600Processor.hpp diff --git a/Scan/utkscan/experiment/include/LaBr3TestProcessor.hpp b/Analysis/Utkscan/experiment/include/LaBr3TestProcessor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/LaBr3TestProcessor.hpp rename to Analysis/Utkscan/experiment/include/LaBr3TestProcessor.hpp diff --git a/Scan/utkscan/experiment/include/TemplateExpProcessor.hpp b/Analysis/Utkscan/experiment/include/TemplateExpProcessor.hpp similarity index 91% rename from Scan/utkscan/experiment/include/TemplateExpProcessor.hpp rename to Analysis/Utkscan/experiment/include/TemplateExpProcessor.hpp index 1d668f0b0..29d604b08 100644 --- a/Scan/utkscan/experiment/include/TemplateExpProcessor.hpp +++ b/Analysis/Utkscan/experiment/include/TemplateExpProcessor.hpp @@ -37,14 +37,11 @@ class TemplateExpProcessor : public EventProcessor { * \return Returns true if the processing was successful */ virtual bool Process(RawEvent &event); private: - /** Obtain the name of the histogram file */ - void ObtainHisName(void); /** Sets the detectors that are associated with this processor */ void SetAssociatedTypes(void); /** Sets up the ASCII output file stream */ void SetupAsciiOutput(void); - std::string fileName_; //!< String to hold the file name from command line std::ofstream *poutstream_; //!< Pointer to ouptut ASCII file stream. double gCutoff_; //!< Variable used to set gamma cutoff energy diff --git a/Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp b/Analysis/Utkscan/experiment/include/TwoChanTimingProcessor.hpp similarity index 84% rename from Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp rename to Analysis/Utkscan/experiment/include/TwoChanTimingProcessor.hpp index fd1cb48c7..6e6a0ada8 100644 --- a/Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp +++ b/Analysis/Utkscan/experiment/include/TwoChanTimingProcessor.hpp @@ -14,13 +14,14 @@ class TwoChanTimingProcessor : public EventProcessor { public: /** Default Constructor */ TwoChanTimingProcessor(); + /** Default Destructor */ ~TwoChanTimingProcessor(); - /** Declares the plots for the processor */ - virtual void DeclarePlots(void); + + /** Performs the main processsing, which may depend on other processors * \param [in] event : the event to process * \return true if processing was successful */ - virtual bool Process(RawEvent &event); + bool Process(RawEvent &event); }; #endif // __TWOCHANTIMINGPROCESSOR_HPP_ diff --git a/Analysis/Utkscan/experiment/include/VandleOrnl2012Processor.hpp b/Analysis/Utkscan/experiment/include/VandleOrnl2012Processor.hpp new file mode 100644 index 000000000..d3df2f638 --- /dev/null +++ b/Analysis/Utkscan/experiment/include/VandleOrnl2012Processor.hpp @@ -0,0 +1,28 @@ +///@file VandleOrnl2012Processor.hpp +///@brief A class to process data from the LeRIBSS 2012 campaign. +///@author S. V. Paulauskas +///@date February 5, 2015 +#ifndef __VANDLEORNL2012PROCESSOR_HPP_ +#define __VANDLEORNL2012PROCESSOR_HPP_ + +#include "EventProcessor.hpp" + +/// Class to process VANDLE related events +class VandleOrnl2012Processor : public EventProcessor { +public: + /** Default Constructor */ + VandleOrnl2012Processor(); + /** Default Destructor */ + ~VandleOrnl2012Processor() {}; + /** Declare the plots used in the analysis */ + void DeclarePlots(void); + + /** Process the event + * \param [in] event : the event to process + * \return Returns true if the processing was successful */ + bool Process(RawEvent &event); +private: + std::string fileName_; //!< the name of the his file + std::vector fileNames_; //!< the vector of output file names +}; +#endif diff --git a/Scan/utkscan/experiment/include/WalkVandleBetaProcessor.hpp b/Analysis/Utkscan/experiment/include/WalkVandleBetaProcessor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/WalkVandleBetaProcessor.hpp rename to Analysis/Utkscan/experiment/include/WalkVandleBetaProcessor.hpp diff --git a/Analysis/Utkscan/experiment/source/Anl1471Processor.cpp b/Analysis/Utkscan/experiment/source/Anl1471Processor.cpp new file mode 100644 index 000000000..a2809c0d7 --- /dev/null +++ b/Analysis/Utkscan/experiment/source/Anl1471Processor.cpp @@ -0,0 +1,353 @@ +///@file Anl1471Processor.cpp +///@brief A class to process data from ANL1471 experiment using VANDLE. +///@author S. Z. Taylor and S. V. Paulauskas +///@date July 14, 2015 +#include + +#include +#include +#include +#include + +#include "BarBuilder.hpp" +#include "DoubleBetaProcessor.hpp" +#include "DetectorDriver.hpp" +#include "GeProcessor.hpp" +#include "Anl1471Processor.hpp" +#include "VandleProcessor.hpp" + +TFile *rootfile_; +TTree *roottree1_; +TTree *roottree2_; +TH2D *qdctof_; +TH1D *Vsize; +TH1D *Bsize; +TH1D *Gsize; +TH2D *BETA; +static double qdc_; + +unsigned int barType; + +struct VandleRoot { + double tof; + double qdc; + double snrl; + double snrr; + double pos; + double tdiff; + double ben; + double bqdcl; + double bqdcr; + double bsnrl; + double bsnrr; + double cyc; + double bcyc; + double HPGE; + int vid; + int vtype; + int bid; +}; + +struct TapeInfo { + bool move; + bool beam; +}; + +struct GammaRoot { + double gen; + double gtime; + double gcyc;//might be repetative with gtime? + double gben; + double gbtime; + double gbcyc; + int gid; + int gbid; +}; + +TapeInfo tapeinfo; +VandleRoot vroot; +GammaRoot groot; + +namespace dammIds { + namespace experiment { + const int DD_DEBUGGING0 = 0; + const int DD_DEBUGGING1 = 1; + const int DD_DEBUGGING2 = 2; + const int DD_DEBUGGING3 = 3; + const int DD_DEBUGGING4 = 4; + const int DD_MedCTOFvQDC = 5; + const int DD_MedVetoed = 6; + const int DD_SmCTOFvQDC = 7; + const int DD_SmVetoed = 8; + const int DD_DEBUGGING9 = 9; + const int D_tape = 10; + const int D_beam = 11; + const int DD_grow_decay = 12; + } +}//namespace dammIds + +using namespace std; +using namespace dammIds::experiment; + +void Anl1471Processor::DeclarePlots(void) { + DeclareHistogram2D(DD_DEBUGGING0, SB, SD, "left-MaxValvsTDIFF"); + DeclareHistogram2D(DD_DEBUGGING1, SB, SD, "right-MaxValvsTDIFF"); + DeclareHistogram2D(DD_DEBUGGING2, SB, S6, "TDIFF-vandle"); + DeclareHistogram1D(DD_DEBUGGING3, S7, "Vandle Multiplicity"); + DeclareHistogram1D(DD_DEBUGGING4, S7, "Beta Multiplicity"); + DeclareHistogram2D(DD_MedCTOFvQDC, SC, SD, "ANL-medium--vs-CorTof"); + DeclareHistogram2D(DD_MedVetoed, SC, SD, "ANL-medium-vetoed"); + DeclareHistogram2D(DD_SmCTOFvQDC, SC, SD, "ANL-small--vs-CorTof"); + DeclareHistogram2D(DD_SmVetoed, SC, SD, "ANL-small-vetoed"); + DeclareHistogram2D(DD_DEBUGGING9, SD, S6, "BSNRLvsBQDCL"); + DeclareHistogram1D(D_tape, S1, "tape move"); + DeclareHistogram1D(D_beam, S1, "beam on/off"); + DeclareHistogram2D(DD_grow_decay, SC, SA, "Grow/Decay"); +}//end declare plots + +Anl1471Processor::Anl1471Processor() : EventProcessor(OFFSET, RANGE, + "Anl1471PRocessor") { + associatedTypes.insert("vandle"); + associatedTypes.insert("beta"); + associatedTypes.insert("ge"); + + stringstream name; + name << Globals::get()->outputPath(Globals::get()->outputFile()) + << ".root"; + rootfile_ = new TFile(name.str().c_str(), "RECREATE"); + + roottree1_ = new TTree("V", ""); + roottree2_ = new TTree("G", ""); + + roottree1_->Branch("vandle", &vroot, + "tof/D:qdc/D:snrl/D:snrr/D:pos/D:tdiff/D:ben/D:bqdcl/D:bqdcr/D:bsnrl/D:bsnrr/D:cyc/D:bcyc/D:HPGE/D:vid/I:vtype/I:bid/I"); + roottree1_->Branch("tape", &tapeinfo, "move/b:beam/b"); + + roottree2_->Branch("gamma", &groot, + "gen/D:gtime/D:gcyc/D:gben/D:gbtime/D:gbcyc/D:gid/I:gbid/I"); + roottree2_->Branch("tape", &tapeinfo, "move/b:beam/b"); + + qdctof_ = new TH2D("qdctof", "", 1000, -100, 900, 16000, 0, 16000); + Vsize = new TH1D("Vsize", "", 40, 0, 40); + Bsize = new TH1D("Bsize", "", 40, 0, 40); + Gsize = new TH1D("Gsize", "", 40, 0, 40); + BETA = new TH2D("BETA", "", 8192, 0, 8192, 64, 0, 64); +} + +Anl1471Processor::~Anl1471Processor() { + rootfile_->Write(); + rootfile_->Close(); + delete (rootfile_); +} + +bool Anl1471Processor::Process(RawEvent &event) { + if (!EventProcessor::Process(event)) + return (false); + double plotMult_ = 2; + double plotOffset_ = 1000; + + BarMap vbars, betas; + map > lrtBetas; + + BarMap betaStarts_; + vector geEvts; + vector> geAddback; + + if (event.GetSummary("vandle")->GetList().size() != 0) + vbars = ((VandleProcessor *) DetectorDriver::get()-> + GetProcessor("VandleProcessor"))->GetBars(); + + + static const vector &doubleBetaStarts = + event.GetSummary("beta:double:start")->GetList(); + BarBuilder startBars(doubleBetaStarts); + startBars.BuildBars(); + betaStarts_ = startBars.GetBarMap(); + + if (event.GetSummary("ge")->GetList().size() != 0) { + geEvts = ((GeProcessor *) DetectorDriver::get()-> + GetProcessor("GeProcessor"))->GetGeEvents(); + geAddback = ((GeProcessor *) DetectorDriver::get()-> + GetProcessor("GeProcessor"))->GetAddbackEvents(); + } + + Vsize->Fill(vbars.size()); + Bsize->Fill(betaStarts_.size()); + Gsize->Fill(geEvts.size()); + + + if (TreeCorrelator::get()->place("TapeMove")->status()) { + tapeinfo.move = 1; + } else { + tapeinfo.move = 0; + } + if (TreeCorrelator::get()->place("Beam")->status()) { + tapeinfo.beam = 1; + } else { + tapeinfo.beam = 0; + } + plot(D_tape, tapeinfo.move); + plot(D_beam, tapeinfo.beam); + plot(DD_DEBUGGING3, vbars.size()); + plot(DD_DEBUGGING4, betaStarts_.size()); + + //Begin processing for VANDLE bars + for (BarMap::iterator it = vbars.begin(); it != vbars.end(); it++) { + TimingDefs::TimingIdentifier barId = (*it).first; + BarDetector bar = (*it).second; + + if (!bar.GetHasEvent()) + continue; + + if (bar.GetType() == "small") + barType = 0; + else if (bar.GetType() == "medium") + barType = 1; + + unsigned int barLoc = barId.first; + const TimingCalibration cal = bar.GetCalibration(); + + + for (BarMap::iterator itStart = betaStarts_.begin(); + itStart != betaStarts_.end(); itStart++) { + BarDetector beta_start = (*itStart).second; + unsigned int startLoc = (*itStart).first.first; + if (!beta_start.GetHasEvent()) + continue; + double tofOffset = cal.GetTofOffset(startLoc); + double tof = bar.GetCorTimeAve() - + beta_start.GetCorTimeAve() + tofOffset; + + double corTof = + ((VandleProcessor *) DetectorDriver::get()-> + GetProcessor("VandleProcessor"))-> + CorrectTOF(tof, bar.GetFlightPath(), cal.GetZ0()); + + //tape move veto cut damm + bool tapeMove = TreeCorrelator::get()->place("TapeMove")->status(); + if (tapeMove == 0) { //plot only if tape is NOT moving + if (bar.GetType() == "medium") + plot(DD_MedCTOFvQDC, corTof * 2 + 1000, bar.GetQdc()); + + if (bar.GetType() == "small") + plot(DD_SmCTOFvQDC, corTof * 2 + 1000, bar.GetQdc()); + } + + if (tapeMove == 1) { //plot only if tape is moving + if (bar.GetType() == "medium") + plot(DD_MedVetoed, corTof * 2 + 1000, bar.GetQdc()); + + if (bar.GetType() == "small") + plot(DD_SmVetoed, corTof * 2 + 1000, bar.GetQdc()); + } + + plot(DD_DEBUGGING9, beta_start.GetLeftSide().GetTraceQdc(), + beta_start.GetLeftSide().GetSignalToNoiseRatio()); + + //adding HPGE energy info to vandle tree + double HPGE_energy = -9999.0; + if (geEvts.size() != 0) { + for (vector::const_iterator itHPGE = geEvts.begin(); + itHPGE != geEvts.end(); itHPGE++) { + HPGE_energy = (*itHPGE)->GetCalEnergy(); + } + + } else { + HPGE_energy = -8888.0; + } + + vroot.tof = corTof * 2 + 1000;//to make identicle to damm output + vroot.qdc = bar.GetQdc(); + vroot.snrl = bar.GetLeftSide().GetSignalToNoiseRatio(); + vroot.snrr = bar.GetRightSide().GetSignalToNoiseRatio(); + vroot.pos = bar.GetQdcPosition(); + vroot.tdiff = bar.GetTimeDifference(); + vroot.ben = beta_start.GetQdc(); + vroot.bqdcl = beta_start.GetLeftSide().GetTraceQdc(); + vroot.bqdcr = beta_start.GetRightSide().GetTraceQdc(); + vroot.bsnrl = beta_start.GetLeftSide().GetSignalToNoiseRatio(); + vroot.bsnrr = beta_start.GetRightSide().GetSignalToNoiseRatio(); + vroot.cyc = 0; /////////it.GetEventTime(); + vroot.bcyc = 0; /////////itStart.GetEventTime() + vroot.HPGE = HPGE_energy; + vroot.vid = barLoc; + vroot.vtype = barType; + vroot.bid = startLoc; + + + BETA->Fill(vroot.bqdcl, vroot.bsnrl); + qdctof_->Fill(tof, bar.GetQdc()); + qdc_ = bar.GetQdc(); + tof = tof; + roottree1_->Fill(); + // bar.GetLeftSide().ZeroRootStructure(leftVandle); + // bar.GetRightSide().ZeroRootStructure(rightVandle); + // beta_start.GetLeftSide().ZeroRootStructure(leftBeta); + // beta_start.GetRightSide().ZeroRootStructure(rightBeta); + qdc_ = tof = -9999; + //VID = BID = SNRVL = SNRVR = -9999; + //GamEn = SNRBL = SNRBR = vandle_ = beta_ = ge_ = -9999; + + plot(DD_DEBUGGING1, tof * plotMult_ + plotOffset_, bar.GetQdc()); + + } // for(TimingMap::iterator itStart + } //(BarMap::iterator itBar + //End processing for VANDLE bars + + //Stuff to fill HPGe branch + if (geEvts.size() != 0) { + for (vector::const_iterator itGe = geEvts.begin(); + itGe != geEvts.end(); itGe++) { + double ge_energy, ge_time, gb_time_L, gb_time_R, gb_time, grow_decay_time, gb_en, gcyc_time; + ge_energy = ge_time = gb_time_L = gb_time_R = gb_time = grow_decay_time = gb_en = gcyc_time = -9999.0; + int ge_id = -9999; + int gb_startLoc = -9999; + BarDetector gb_start; + ge_energy = (*itGe)->GetCalEnergy(); + ge_id = (*itGe)->GetChanID().GetLocation(); + ge_time = (*itGe)->GetCorrectedTime(); + ge_time *= (Globals::get()->clockInSeconds() * 1.e9);//in ns now + + if (TreeCorrelator::get()->place("Cycle")->status()) { + gcyc_time = TreeCorrelator::get()->place("Cycle")->last().time; + gcyc_time *= (Globals::get()->clockInSeconds() * + 1.e9);//in ns now + grow_decay_time = + (ge_time - gcyc_time) * 1e-9 * 1e2;//in seconds, then ms + //cout << ge_energy << endl << grow_decay_time << endl << endl; + plot(DD_grow_decay, ge_energy, grow_decay_time); + } + + if (doubleBetaStarts.size() != 0) { + for (BarMap::iterator itGB = betaStarts_.begin(); + itGB != betaStarts_.end(); itGB++) { + gb_start = (*itGB).second; + gb_startLoc = (*itGB).first.first; + gb_en = gb_start.GetQdc(); + gb_time_L = gb_start.GetLeftSide().GetHighResTime();//GetCorrectedTime()?? + gb_time_R = gb_start.GetRightSide().GetHighResTime();//GetTimeAverage()?? + gb_time = (gb_time_L + gb_time_R) / 2; + gb_time *= (Globals::get()->clockInSeconds() * + 1.e9);//in ns now + } + } else { + gb_startLoc = -9999; + gb_en = -9999; + gb_time = -9999; + } + + groot.gen = ge_energy; + groot.gtime = ge_time; + groot.gcyc = ge_time - gcyc_time; + groot.gben = gb_en; + groot.gbtime = gb_time; + groot.gbcyc = gb_time - gcyc_time; + groot.gid = ge_id; + groot.gbid = gb_startLoc; + roottree2_->Fill(); + } + } + + EndProcess(); + return (true); +} \ No newline at end of file diff --git a/Scan/utkscan/experiment/source/Beta4Hen3Processor.cpp b/Analysis/Utkscan/experiment/source/Beta4Hen3Processor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/Beta4Hen3Processor.cpp rename to Analysis/Utkscan/experiment/source/Beta4Hen3Processor.cpp diff --git a/Analysis/Utkscan/experiment/source/CMakeLists.txt b/Analysis/Utkscan/experiment/source/CMakeLists.txt new file mode 100644 index 000000000..1eeac03f9 --- /dev/null +++ b/Analysis/Utkscan/experiment/source/CMakeLists.txt @@ -0,0 +1,13 @@ +set(EXPERIMENT_SOURCES + TemplateExpProcessor.cpp + VandleOrnl2012Processor.cpp +) + +if(USE_ROOT) +list(APPEND EXPERIMENT_SOURCES + Anl1471Processor.cpp + IS600Processor.cpp + TwoChanTimingProcessor.cpp) +endif(USE_ROOT) + +add_library(ExperimentObjects OBJECT ${EXPERIMENT_SOURCES}) diff --git a/Scan/utkscan/experiment/source/CrosstalkProcessor.cpp b/Analysis/Utkscan/experiment/source/CrosstalkProcessor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/CrosstalkProcessor.cpp rename to Analysis/Utkscan/experiment/source/CrosstalkProcessor.cpp diff --git a/Scan/utkscan/experiment/source/Dssd4SHEProcessor.cpp b/Analysis/Utkscan/experiment/source/Dssd4SHEProcessor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/Dssd4SHEProcessor.cpp rename to Analysis/Utkscan/experiment/source/Dssd4SHEProcessor.cpp diff --git a/Scan/utkscan/experiment/source/Ge4Hen3Processor.cpp b/Analysis/Utkscan/experiment/source/Ge4Hen3Processor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/Ge4Hen3Processor.cpp rename to Analysis/Utkscan/experiment/source/Ge4Hen3Processor.cpp diff --git a/Scan/utkscan/experiment/source/IS600Processor.cpp b/Analysis/Utkscan/experiment/source/IS600Processor.cpp similarity index 95% rename from Scan/utkscan/experiment/source/IS600Processor.cpp rename to Analysis/Utkscan/experiment/source/IS600Processor.cpp index e405a61a5..dc0205376 100644 --- a/Scan/utkscan/experiment/source/IS600Processor.cpp +++ b/Analysis/Utkscan/experiment/source/IS600Processor.cpp @@ -1,25 +1,18 @@ -/** \file IS600Processor.cpp - * \brief A class to process data from ISOLDE 599 and 600 experiments using - * VANDLE. - * - *\author S. V. Paulauskas - *\date July 14, 2015 - */ +///@file IS600Processor.cpp +///@brief A class to process data from ISOLDE 599 and 600 experiments using +/// VANDLE. +///@author S. V. Paulauskas +///@date July 14, 2015 #include #include #include #include "BarBuilder.hpp" -#include "DammPlotIds.hpp" #include "DoubleBetaProcessor.hpp" #include "DetectorDriver.hpp" #include "GeProcessor.hpp" -#include "GetArguments.hpp" -#include "Globals.hpp" #include "IS600Processor.hpp" -#include "RawEvent.hpp" -#include "TimingMapBuilder.hpp" #include "VandleProcessor.hpp" #ifdef useroot @@ -71,16 +64,13 @@ IS600Processor::IS600Processor() : EventProcessor(OFFSET, RANGE, "IS600PRocessor associatedTypes.insert("beta"); associatedTypes.insert("ge"); - char hisFileName[32]; - GetArgument(1, hisFileName, 32); - string temp = hisFileName; - temp = temp.substr(0, temp.find_first_of(" ")); stringstream name; - name << temp << ".dat"; + name << Globals::get()->outputPath(Globals::get()->outputFile()) << ".dat"; outstream = new ofstream(name.str().c_str()); #ifdef useroot stringstream rootname; - rootname << temp << ".root"; + rootname << Globals::get()->outputPath(Globals::get()->outputFile()) << ".root"; + cout << rootname.str() << endl; rootfile_ = new TFile(rootname.str().c_str(),"RECREATE"); roottree_ = new TTree("vandle",""); roottree_->Branch("tof",&tof_,"tof/D"); diff --git a/Scan/utkscan/experiment/source/LaBr3TestProcessor.cpp b/Analysis/Utkscan/experiment/source/LaBr3TestProcessor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/LaBr3TestProcessor.cpp rename to Analysis/Utkscan/experiment/source/LaBr3TestProcessor.cpp diff --git a/Scan/utkscan/experiment/source/SheCorrelator.cpp b/Analysis/Utkscan/experiment/source/SheCorrelator.cpp similarity index 100% rename from Scan/utkscan/experiment/source/SheCorrelator.cpp rename to Analysis/Utkscan/experiment/source/SheCorrelator.cpp diff --git a/Scan/utkscan/experiment/source/TemplateExpProcessor.cpp b/Analysis/Utkscan/experiment/source/TemplateExpProcessor.cpp similarity index 89% rename from Scan/utkscan/experiment/source/TemplateExpProcessor.cpp rename to Analysis/Utkscan/experiment/source/TemplateExpProcessor.cpp index c865bab3b..3636772b7 100644 --- a/Scan/utkscan/experiment/source/TemplateExpProcessor.cpp +++ b/Analysis/Utkscan/experiment/source/TemplateExpProcessor.cpp @@ -42,7 +42,6 @@ TemplateExpProcessor::TemplateExpProcessor() : EventProcessor(OFFSET, RANGE, "TemplateExpProcessor") { gCutoff_ = 0.; ///Set the gamma cuttoff energy to a default of 0. SetAssociatedTypes(); - ObtainHisName(); SetupAsciiOutput(); #ifdef useroot SetupRootOutput(); @@ -53,7 +52,6 @@ TemplateExpProcessor::TemplateExpProcessor(const double &gcut) : EventProcessor(OFFSET, RANGE, "TemplateExpProcessor") { gCutoff_ = gcut; SetAssociatedTypes(); - ObtainHisName(); SetupAsciiOutput(); #ifdef useroot SetupRootOutput(); @@ -80,7 +78,7 @@ void TemplateExpProcessor::SetAssociatedTypes(void) { ///Sets up the name of the output ascii data file void TemplateExpProcessor::SetupAsciiOutput(void) { stringstream name; - name << fileName_ << ".dat"; + name << Globals::get()->outputPath(Globals::get()->outputFile()) << ".dat"; poutstream_ = new ofstream(name.str().c_str()); } @@ -88,7 +86,8 @@ void TemplateExpProcessor::SetupAsciiOutput(void) { ///Sets up ROOT output file, tree, branches, histograms. void TemplateExpProcessor::SetupRootOutput(void) { stringstream rootname; - rootname << fileName_ << ".root"; + rootname << Globals::get()->outputPath(Globals::get()->outputFile()) + << ".root"; prootfile_ = new TFile(rootname.str().c_str(),"RECREATE"); proottree_ = new TTree("data",""); proottree_->Branch("tof",&tof_,"tof/D"); @@ -98,14 +97,6 @@ void TemplateExpProcessor::SetupRootOutput(void) { } #endif -///Obtains the name of the histogram file passed via command line -void TemplateExpProcessor::ObtainHisName(void) { - char hisFileName[32]; - // GetArgument(1, hisFileName, 32); - string temp = hisFileName; - fileName_ = temp.substr(0, temp.find_first_of(" ")); -} - ///We do nothing here since we're completely dependent on the resutls of others bool TemplateExpProcessor::PreProcess(RawEvent &event){ if (!EventProcessor::PreProcess(event)) @@ -159,11 +150,15 @@ bool TemplateExpProcessor::Process(RawEvent &event) { double gEnergy = chan->GetCalEnergy(); double gTime = chan->GetCorrectedTime(); - ///Plot the Template Energy vs. Ge Energy - plot(DD_TENVSGEN, gEnergy, (*tit)->GetEnergy()); + ///Plot the Template Energy vs. Ge Energy if tape isn't moving + if(!isTapeMoving) + plot(DD_TENVSGEN, gEnergy, (*tit)->GetEnergy()); - ///Output template and ge energy to text file - *poutstream_ << (*tit)->GetEnergy() << " " << gEnergy << endl; + ///Output template and ge energy to text file if we had a beta + /// along with the runtime in seconds. + if(hasBeta) + *poutstream_ << (*tit)->GetEnergy() << " " << gEnergy << " " + << clockInSeconds << endl; ///Fill ROOT histograms and tree with the information #ifdef useroot ptvsge_->Fill((*tit)->GetEnergy(), gEnergy); diff --git a/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp b/Analysis/Utkscan/experiment/source/TwoChanTimingProcessor.cpp similarity index 90% rename from Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp rename to Analysis/Utkscan/experiment/source/TwoChanTimingProcessor.cpp index f18955fd9..2515bfb3f 100644 --- a/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp +++ b/Analysis/Utkscan/experiment/source/TwoChanTimingProcessor.cpp @@ -37,8 +37,8 @@ namespace dammIds { using namespace std; using namespace dammIds::experiment; -TwoChanTimingProcessor::TwoChanTimingProcessor() : EventProcessor(OFFSET, RANGE, - "TwoChanTimingProcessor") { +TwoChanTimingProcessor::TwoChanTimingProcessor() : + EventProcessor(OFFSET, RANGE, "TwoChanTimingProcessor") { associatedTypes.insert("pulser"); trcfile.open(Globals::get()->outputPath("trace.dat").c_str()); @@ -60,9 +60,6 @@ TwoChanTimingProcessor::~TwoChanTimingProcessor() { trcfile.close(); } -void TwoChanTimingProcessor::DeclarePlots(void) { -} - bool TwoChanTimingProcessor::Process(RawEvent &event) { if (!EventProcessor::Process(event)) return false; @@ -100,8 +97,8 @@ bool TwoChanTimingProcessor::Process(RawEvent &event) { static int trcCounter = 0; int bin; - for(vector::const_iterator it = start.GetTrace()->begin(); it != - start.GetTrace()->end(); it++) { + for(vector::const_iterator it = start.GetTrace()->begin(); + it != start.GetTrace()->end(); it++) { bin = (int)(it-start.GetTrace()->begin()); traces->Fill(bin, trcCounter, *it); //Only output the 500th trace to make sure that we are not at the diff --git a/Analysis/Utkscan/experiment/source/VandleOrnl2012Processor.cpp b/Analysis/Utkscan/experiment/source/VandleOrnl2012Processor.cpp new file mode 100644 index 000000000..968eb8a57 --- /dev/null +++ b/Analysis/Utkscan/experiment/source/VandleOrnl2012Processor.cpp @@ -0,0 +1,221 @@ +///@file VandleOrnl2012Processor.cpp +///@brief A class to process data from the LeRIBSS 2012 campaign. +///@author S. V. Paulauskas +///@date February 5, 2015 +#include + +#include "BarBuilder.hpp" +#include "DetectorDriver.hpp" +#include "GeProcessor.hpp" +#include "VandleProcessor.hpp" +#include "VandleOrnl2012Processor.hpp" + +///@TODO We need to implement some ROOT output for this. + +namespace dammIds { + namespace experiment { + const unsigned int DEBUGGING_OFFSET = 70; + const int DD_DEBUGGING0 = 0 + DEBUGGING_OFFSET; + const int DD_DEBUGGING1 = 1 + DEBUGGING_OFFSET; + const int DD_DEBUGGING2 = 2 + DEBUGGING_OFFSET; + const int DD_DEBUGGING3 = 3 + DEBUGGING_OFFSET; + const int DD_DEBUGGING4 = 4 + DEBUGGING_OFFSET; + const int DD_DEBUGGING5 = 5 + DEBUGGING_OFFSET; + const int DD_DEBUGGING6 = 6 + DEBUGGING_OFFSET; + const int DD_DEBUGGING7 = 7 + DEBUGGING_OFFSET; + const int DD_DEBUGGING8 = 8 + DEBUGGING_OFFSET; + const int DD_DEBUGGING9 = 9 + DEBUGGING_OFFSET; + const int DD_DEBUGGING10 = 10 + DEBUGGING_OFFSET; + const int DD_DEBUGGING11 = 11 + DEBUGGING_OFFSET; + const int DD_DEBUGGING12 = 12 + DEBUGGING_OFFSET; + } +}//namespace dammIds + +using namespace std; +using namespace dammIds::experiment; + +void VandleOrnl2012Processor::DeclarePlots(void) { + DeclareHistogram2D(DD_DEBUGGING0, SC, S7, "General Purpose"); + DeclareHistogram2D(DD_DEBUGGING1, SA, SD, "TOF - banana gated"); + DeclareHistogram2D(DD_DEBUGGING2, SA, SD, "TOF - Lower Bars Banana Gated"); + DeclareHistogram2D(DD_DEBUGGING3, SA, SD, "TOF - Upper Bars Banana Gated"); + DeclareHistogram2D(DD_DEBUGGING4, SA, SD, "TOF - Gated 600 keV"); + DeclareHistogram2D(DD_DEBUGGING5, SA, SD, "TOF - Gated 700 keV"); + DeclareHistogram2D(DD_DEBUGGING6, SA, SC, "TOF - Bar 12 Banana Gated"); + DeclareHistogram2D(DD_DEBUGGING7, SA, SA, "Currently Unused"); + DeclareHistogram2D(DD_DEBUGGING8, SA, SA, "Currently Unused"); + DeclareHistogram2D(DD_DEBUGGING9, SC, S7, "Bar Loc vs. TOF - gated"); + DeclareHistogram2D(DD_DEBUGGING10, SB, SA, "Decay Time vs. ToF"); + DeclareHistogram2D(DD_DEBUGGING11, SC, SA, "Decay Time vs. GEnergy"); + DeclareHistogram2D(DD_DEBUGGING12, SA, SA, "Decay Time vs. ToF - banana"); + + DeclareHistogram2D(DEBUGGING_OFFSET + 20, SA, SA, "QDC TOF - Lower 0"); + DeclareHistogram2D(DEBUGGING_OFFSET + 21, SA, SA, "QDC TOF - Lower 1"); + DeclareHistogram2D(DEBUGGING_OFFSET + 22, SA, SA, "QDC TOF - Upper 0"); + DeclareHistogram2D(DEBUGGING_OFFSET + 23, SA, SA, "QDC TOF - Upper 1"); + DeclareHistogram2D(DEBUGGING_OFFSET + 24, SA, SD, "QDC TOF - Upper "); + DeclareHistogram2D(DEBUGGING_OFFSET + 25, SA, SD, "QDC TOF - Lower"); +} + +VandleOrnl2012Processor::VandleOrnl2012Processor() : + EventProcessor(OFFSET, RANGE, "VandleOrnl2012Processor") { + associatedTypes.insert("vandle"); + + stringstream name; + name << Globals::get()->outputPath(Globals::get()->outputFile()); + fileName_ = name.str(); + fileNames_.push_back(fileName_ + "-tof.dat"); + fileNames_.push_back(fileName_ + "-tof-02Plus.dat"); + fileNames_.push_back(fileName_ + "-tof-04Plus.dat"); +} + +bool VandleOrnl2012Processor::Process(RawEvent &event) { + if (!EventProcessor::Process(event)) + return (false); + double plotMult_ = 2; + double plotOffset_ = 1000; + + BarMap vbars, betas; + ///@TODO Update the BetaProcessor so that it actually generates this map. + TimingMap starts; + vector geEvts; + vector > geAddback; + + if (event.GetSummary("vandle")->GetList().size() != 0) + vbars = ((VandleProcessor *) DetectorDriver::get()-> + GetProcessor("VandleProcessor"))->GetBars(); + if(event.GetSummary("ge")->GetList().size() != 0) { + geEvts = ((GeProcessor*)DetectorDriver::get()-> + GetProcessor("GeProcessor"))->GetGeEvents(); + geAddback = ((GeProcessor*)DetectorDriver::get()-> + GetProcessor("GeProcessor"))->GetAddbackEvents(); + } + + for (BarMap::iterator it = vbars.begin(); it != vbars.end(); it++) { + TimingDefs::TimingIdentifier barId = (*it).first; + BarDetector bar = (*it).second; + if (!bar.GetHasEvent()) + continue; + + unsigned int barLoc = barId.first; + TimingCalibration cal = bar.GetCalibration(); + + bool isLower = barLoc > 6 && barLoc < 16; + bool isUpper = barLoc > 29 && barLoc < 39; + bool isCleared = isLower; + int bananaNum = 1; + + for (TimingMap::iterator itStart = starts.begin(); + itStart != starts.end(); itStart++) { + HighResTimingData start = (*itStart).second; + if (!start.GetIsValid()) + continue; + + unsigned int startLoc = (*itStart).first.first; + + //!--------- CUT On Beta Energy ---------- + if (start.GetFilterEnergy() < 1000) + continue; + + double tofOffset = cal.GetTofOffset(startLoc); + double tof = bar.GetCorTimeAve() - + start.GetCorrectedTime() + tofOffset; + double corTof = + ((VandleProcessor*)DetectorDriver::get()-> + GetProcessor("VandleProcessor"))-> + CorrectTOF(tof, bar.GetFlightPath(), cal.GetZ0()); + + bool inPeel = histo.BananaTest(bananaNum, + corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + if (isLower) { + if (startLoc == 0) + plot(DEBUGGING_OFFSET + 20, + tof * plotMult_ + plotOffset_, bar.GetQdc()); + else + plot(DEBUGGING_OFFSET + 21, + tof * plotMult_ + plotOffset_, bar.GetQdc()); + } + + if (isUpper) { + if (startLoc == 0) + plot(DEBUGGING_OFFSET + 22, + tof * plotMult_ + plotOffset_, bar.GetQdc()); + else + plot(DEBUGGING_OFFSET + 23, + tof * plotMult_ + plotOffset_, bar.GetQdc()); + } + + //All of them are gated using a banana gate + if (inPeel) { + if (isCleared) + plot(DD_DEBUGGING1, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + + if (isLower) { + ofstream data; + data.open(fileNames_[0].c_str(), ios::app); + data << corTof << endl; + data.close(); + + plot(DD_DEBUGGING2, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + } + if (isUpper) + plot(DD_DEBUGGING3, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + + if (barLoc == 12) + plot(DD_DEBUGGING6, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + } + + if (isLower) + plot(DEBUGGING_OFFSET + 24, + corTof * plotMult_ + plotOffset_, bar.GetQdc()); + if (isUpper) + plot(DEBUGGING_OFFSET + 25, + corTof * plotMult_ + plotOffset_, bar.GetQdc()); + + double cycleTime = TreeCorrelator::get()->place( + "Cycle")->last().time; + cycleTime *= (Globals::get()->clockInSeconds() * 1.e9); + + double decayTime = (bar.GetTimeAverage() - cycleTime) / 0.01; + + plot(DD_DEBUGGING10, corTof * plotMult_ + plotOffset_, + decayTime * 1.e-9); + if (inPeel && isCleared) + plot(DD_DEBUGGING12, corTof * plotMult_ + plotOffset_, + decayTime * 1.e-9); + + ofstream gammaGated; + if (!geEvts.empty() && isCleared && inPeel) { + for (vector::const_iterator itGe = geEvts.begin(); + itGe != geEvts.end(); itGe++) { + double calEnergy = (*itGe)->GetCalEnergy(); + plot(DD_DEBUGGING11, calEnergy, decayTime * 1e-9); + if (calEnergy >= 595 && calEnergy <= 603) { + if (isLower) { + gammaGated.open(fileNames_[1].c_str(), ios::app); + gammaGated << corTof << endl; + } + plot(DD_DEBUGGING4, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + } + if (calEnergy >= 692 && calEnergy <= 704) { + if (isLower) { + gammaGated.open(fileNames_[2].c_str(), ios::app); + gammaGated << corTof << endl; + } + plot(DD_DEBUGGING5, corTof * plotMult_ + plotOffset_, + bar.GetQdc()); + } // if(calEnergy >= 692 + }// for(vector::const_iterator + gammaGated.close(); + }//geSummary_->GetMult() > 0 + }//loop over starts + }//loop over bars + EndProcess(); + return (true); +} diff --git a/Scan/utkscan/experiment/source/WalkVandleBetaProcessor.cpp b/Analysis/Utkscan/experiment/source/WalkVandleBetaProcessor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/WalkVandleBetaProcessor.cpp rename to Analysis/Utkscan/experiment/source/WalkVandleBetaProcessor.cpp diff --git a/Scan/utkscan/processors/CMakeLists.txt b/Analysis/Utkscan/processors/CMakeLists.txt similarity index 100% rename from Scan/utkscan/processors/CMakeLists.txt rename to Analysis/Utkscan/processors/CMakeLists.txt diff --git a/Scan/utkscan/processors/include/BetaProcessor.hpp b/Analysis/Utkscan/processors/include/BetaProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/BetaProcessor.hpp rename to Analysis/Utkscan/processors/include/BetaProcessor.hpp diff --git a/Scan/utkscan/processors/include/BetaScintProcessor.hpp b/Analysis/Utkscan/processors/include/BetaScintProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/BetaScintProcessor.hpp rename to Analysis/Utkscan/processors/include/BetaScintProcessor.hpp diff --git a/Scan/utkscan/processors/include/DoubleBetaProcessor.hpp b/Analysis/Utkscan/processors/include/DoubleBetaProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/DoubleBetaProcessor.hpp rename to Analysis/Utkscan/processors/include/DoubleBetaProcessor.hpp diff --git a/Scan/utkscan/processors/include/DssdProcessor.hpp b/Analysis/Utkscan/processors/include/DssdProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/DssdProcessor.hpp rename to Analysis/Utkscan/processors/include/DssdProcessor.hpp diff --git a/Scan/utkscan/processors/include/EventProcessor.hpp b/Analysis/Utkscan/processors/include/EventProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/EventProcessor.hpp rename to Analysis/Utkscan/processors/include/EventProcessor.hpp diff --git a/Scan/utkscan/processors/include/GeCalibProcessor.hpp b/Analysis/Utkscan/processors/include/GeCalibProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/GeCalibProcessor.hpp rename to Analysis/Utkscan/processors/include/GeCalibProcessor.hpp diff --git a/Scan/utkscan/processors/include/GeProcessor.hpp b/Analysis/Utkscan/processors/include/GeProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/GeProcessor.hpp rename to Analysis/Utkscan/processors/include/GeProcessor.hpp diff --git a/Scan/utkscan/processors/include/Hen3Processor.hpp b/Analysis/Utkscan/processors/include/Hen3Processor.hpp similarity index 100% rename from Scan/utkscan/processors/include/Hen3Processor.hpp rename to Analysis/Utkscan/processors/include/Hen3Processor.hpp diff --git a/Scan/utkscan/processors/include/ImplantSsdProcessor.hpp b/Analysis/Utkscan/processors/include/ImplantSsdProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/ImplantSsdProcessor.hpp rename to Analysis/Utkscan/processors/include/ImplantSsdProcessor.hpp diff --git a/Scan/utkscan/processors/include/IonChamberProcessor.hpp b/Analysis/Utkscan/processors/include/IonChamberProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/IonChamberProcessor.hpp rename to Analysis/Utkscan/processors/include/IonChamberProcessor.hpp diff --git a/Scan/utkscan/processors/include/LiquidProcessor.hpp b/Analysis/Utkscan/processors/include/LiquidProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/LiquidProcessor.hpp rename to Analysis/Utkscan/processors/include/LiquidProcessor.hpp diff --git a/Scan/utkscan/processors/include/LiquidScintProcessor.hpp b/Analysis/Utkscan/processors/include/LiquidScintProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/LiquidScintProcessor.hpp rename to Analysis/Utkscan/processors/include/LiquidScintProcessor.hpp diff --git a/Scan/utkscan/processors/include/LitePositionProcessor.hpp b/Analysis/Utkscan/processors/include/LitePositionProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/LitePositionProcessor.hpp rename to Analysis/Utkscan/processors/include/LitePositionProcessor.hpp diff --git a/Scan/utkscan/processors/include/LogicProcessor.hpp b/Analysis/Utkscan/processors/include/LogicProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/LogicProcessor.hpp rename to Analysis/Utkscan/processors/include/LogicProcessor.hpp diff --git a/Scan/utkscan/processors/include/McpProcessor.hpp b/Analysis/Utkscan/processors/include/McpProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/McpProcessor.hpp rename to Analysis/Utkscan/processors/include/McpProcessor.hpp diff --git a/Scan/utkscan/processors/include/NeutronProcessor.hpp b/Analysis/Utkscan/processors/include/NeutronProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/NeutronProcessor.hpp rename to Analysis/Utkscan/processors/include/NeutronProcessor.hpp diff --git a/Scan/utkscan/processors/include/NeutronScintProcessor.hpp b/Analysis/Utkscan/processors/include/NeutronScintProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/NeutronScintProcessor.hpp rename to Analysis/Utkscan/processors/include/NeutronScintProcessor.hpp diff --git a/Scan/utkscan/processors/include/PositionProcessor.hpp b/Analysis/Utkscan/processors/include/PositionProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/PositionProcessor.hpp rename to Analysis/Utkscan/processors/include/PositionProcessor.hpp diff --git a/Scan/utkscan/processors/include/PspmtProcessor.hpp b/Analysis/Utkscan/processors/include/PspmtProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/PspmtProcessor.hpp rename to Analysis/Utkscan/processors/include/PspmtProcessor.hpp diff --git a/Scan/utkscan/processors/include/RootProcessor.hpp b/Analysis/Utkscan/processors/include/RootProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/RootProcessor.hpp rename to Analysis/Utkscan/processors/include/RootProcessor.hpp diff --git a/Scan/utkscan/processors/include/ScintProcessor.hpp b/Analysis/Utkscan/processors/include/ScintProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/ScintProcessor.hpp rename to Analysis/Utkscan/processors/include/ScintProcessor.hpp diff --git a/Scan/utkscan/processors/include/SsdBetaProcessor.hpp b/Analysis/Utkscan/processors/include/SsdBetaProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/SsdBetaProcessor.hpp rename to Analysis/Utkscan/processors/include/SsdBetaProcessor.hpp diff --git a/Scan/utkscan/processors/include/SsdProcessor.hpp b/Analysis/Utkscan/processors/include/SsdProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/SsdProcessor.hpp rename to Analysis/Utkscan/processors/include/SsdProcessor.hpp diff --git a/Scan/utkscan/processors/include/TeenyVandleProcessor.hpp b/Analysis/Utkscan/processors/include/TeenyVandleProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/TeenyVandleProcessor.hpp rename to Analysis/Utkscan/processors/include/TeenyVandleProcessor.hpp diff --git a/Scan/utkscan/processors/include/TemplateProcessor.hpp b/Analysis/Utkscan/processors/include/TemplateProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/TemplateProcessor.hpp rename to Analysis/Utkscan/processors/include/TemplateProcessor.hpp diff --git a/Scan/utkscan/processors/include/ValidProcessor.hpp b/Analysis/Utkscan/processors/include/ValidProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/ValidProcessor.hpp rename to Analysis/Utkscan/processors/include/ValidProcessor.hpp diff --git a/Scan/utkscan/processors/include/VandleProcessor.hpp b/Analysis/Utkscan/processors/include/VandleProcessor.hpp similarity index 100% rename from Scan/utkscan/processors/include/VandleProcessor.hpp rename to Analysis/Utkscan/processors/include/VandleProcessor.hpp diff --git a/Scan/utkscan/processors/source/BetaProcessor.cpp b/Analysis/Utkscan/processors/source/BetaProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/BetaProcessor.cpp rename to Analysis/Utkscan/processors/source/BetaProcessor.cpp diff --git a/Scan/utkscan/processors/source/BetaScintProcessor.cpp b/Analysis/Utkscan/processors/source/BetaScintProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/BetaScintProcessor.cpp rename to Analysis/Utkscan/processors/source/BetaScintProcessor.cpp diff --git a/Scan/utkscan/processors/source/CMakeLists.txt b/Analysis/Utkscan/processors/source/CMakeLists.txt similarity index 100% rename from Scan/utkscan/processors/source/CMakeLists.txt rename to Analysis/Utkscan/processors/source/CMakeLists.txt diff --git a/Scan/utkscan/processors/source/DoubleBetaProcessor.cpp b/Analysis/Utkscan/processors/source/DoubleBetaProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/DoubleBetaProcessor.cpp rename to Analysis/Utkscan/processors/source/DoubleBetaProcessor.cpp diff --git a/Scan/utkscan/processors/source/DssdProcessor.cpp b/Analysis/Utkscan/processors/source/DssdProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/DssdProcessor.cpp rename to Analysis/Utkscan/processors/source/DssdProcessor.cpp diff --git a/Scan/utkscan/processors/source/EventProcessor.cpp b/Analysis/Utkscan/processors/source/EventProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/EventProcessor.cpp rename to Analysis/Utkscan/processors/source/EventProcessor.cpp diff --git a/Scan/utkscan/processors/source/GeCalibProcessor.cpp b/Analysis/Utkscan/processors/source/GeCalibProcessor.cpp similarity index 99% rename from Scan/utkscan/processors/source/GeCalibProcessor.cpp rename to Analysis/Utkscan/processors/source/GeCalibProcessor.cpp index efa54eb4b..4838c936a 100644 --- a/Scan/utkscan/processors/source/GeCalibProcessor.cpp +++ b/Analysis/Utkscan/processors/source/GeCalibProcessor.cpp @@ -200,7 +200,7 @@ bool GeCalibProcessor::PreProcess(RawEvent &event) { for (vector::const_iterator itHigh = highEvents.begin(); itHigh != highEvents.end(); itHigh++) { - int location = (*itHigh)->GetChanID().GetLocation(); + unsigned int location = (*itHigh)->GetChanID().GetLocation(); plot(calib::D_ENERGY_HIGHGAIN, (*itHigh)->GetCalEnergy()); if ( (*itHigh)->IsSaturated() || (*itHigh)->IsPileup() ) diff --git a/Scan/utkscan/processors/source/GeProcessor.cpp b/Analysis/Utkscan/processors/source/GeProcessor.cpp similarity index 96% rename from Scan/utkscan/processors/source/GeProcessor.cpp rename to Analysis/Utkscan/processors/source/GeProcessor.cpp index 0cb5f42fb..5e016e5de 100644 --- a/Scan/utkscan/processors/source/GeProcessor.cpp +++ b/Analysis/Utkscan/processors/source/GeProcessor.cpp @@ -18,6 +18,7 @@ #include "DammPlotIds.hpp" #include "DetectorLibrary.hpp" +#include "Display.h" #include "Exceptions.hpp" #include "GeProcessor.hpp" #include "Messenger.hpp" @@ -164,8 +165,8 @@ void GeProcessor::DeclarePlots(void) { */ DetectorLibrary* modChan = DetectorLibrary::get(); - const set &cloverLocations = modChan->GetLocations("ge", - "clover_high"); + const set &cloverLocations = + modChan->GetLocations("ge", "clover_high"); // could set it now but we'll iterate through the locations to set this unsigned int cloverChans = 0; @@ -401,7 +402,7 @@ bool GeProcessor::PreProcess(RawEvent &event) { */ for (vector::const_iterator itHigh = highEvents.begin(); itHigh != highEvents.end(); itHigh++) { - int location = (*itHigh)->GetChanID().GetLocation(); + unsigned int location = (*itHigh)->GetChanID().GetLocation(); if ( (*itHigh)->IsSaturated() || (*itHigh)->IsPileup() ) continue; @@ -479,11 +480,32 @@ bool GeProcessor::Process(RawEvent &event) { double clockInSeconds = Globals::get()->clockInSeconds(); /** Cycle time is measured from the begining of the last BeamON event */ - double cycleTime = TreeCorrelator::get()->place("Cycle")->last().time; + double cycleTime = 0 ; + try{ + cycleTime = TreeCorrelator::get()->place("Cycle")->last().time; + } catch (exception &ex) { + cout << Display::ErrorStr("GeProcessor::Process - Exception caught " + "while trying to get Cycle time.\n"); + throw; + } // beamOn is true for beam on and false for beam off - bool beamOn = TreeCorrelator::get()->place("Beam")->status(); - bool hasBeta = TreeCorrelator::get()->place("Beta")->status(); + bool beamOn = false; + try{ + beamOn = TreeCorrelator::get()->place("Beam")->status(); + } catch (exception &ex) { + cout << Display::ErrorStr("GeProcessor::Process - Exception caught " + "while trying to get Beam status.\n"); + throw; + } + bool hasBeta = false; + try{ + hasBeta = TreeCorrelator::get()->place("Beta")->status(); + }catch (exception &ex) { + cout << Display::ErrorStr("GeProcessor::Process - Exception caught " + "while trying to get Beta status.\n"); + throw; + } /** Place Cycle is activated by BeamOn event and deactivated by TapeMove * This condition will therefore skip events registered during diff --git a/Scan/utkscan/processors/source/Hen3Processor.cpp b/Analysis/Utkscan/processors/source/Hen3Processor.cpp similarity index 100% rename from Scan/utkscan/processors/source/Hen3Processor.cpp rename to Analysis/Utkscan/processors/source/Hen3Processor.cpp diff --git a/Scan/utkscan/processors/source/ImplantSsdProcessor.cpp b/Analysis/Utkscan/processors/source/ImplantSsdProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/ImplantSsdProcessor.cpp rename to Analysis/Utkscan/processors/source/ImplantSsdProcessor.cpp diff --git a/Scan/utkscan/processors/source/IonChamberProcessor.cpp b/Analysis/Utkscan/processors/source/IonChamberProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/IonChamberProcessor.cpp rename to Analysis/Utkscan/processors/source/IonChamberProcessor.cpp diff --git a/Scan/utkscan/processors/source/LiquidProcessor.cpp b/Analysis/Utkscan/processors/source/LiquidProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/LiquidProcessor.cpp rename to Analysis/Utkscan/processors/source/LiquidProcessor.cpp diff --git a/Scan/utkscan/processors/source/LiquidScintProcessor.cpp b/Analysis/Utkscan/processors/source/LiquidScintProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/LiquidScintProcessor.cpp rename to Analysis/Utkscan/processors/source/LiquidScintProcessor.cpp diff --git a/Scan/utkscan/processors/source/LitePositionProcessor.cpp b/Analysis/Utkscan/processors/source/LitePositionProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/LitePositionProcessor.cpp rename to Analysis/Utkscan/processors/source/LitePositionProcessor.cpp diff --git a/Scan/utkscan/processors/source/LogicProcessor.cpp b/Analysis/Utkscan/processors/source/LogicProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/LogicProcessor.cpp rename to Analysis/Utkscan/processors/source/LogicProcessor.cpp diff --git a/Scan/utkscan/processors/source/McpProcessor.cpp b/Analysis/Utkscan/processors/source/McpProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/McpProcessor.cpp rename to Analysis/Utkscan/processors/source/McpProcessor.cpp diff --git a/Scan/utkscan/processors/source/NeutronProcessor.cpp b/Analysis/Utkscan/processors/source/NeutronProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/NeutronProcessor.cpp rename to Analysis/Utkscan/processors/source/NeutronProcessor.cpp diff --git a/Scan/utkscan/processors/source/NeutronScintProcessor.cpp b/Analysis/Utkscan/processors/source/NeutronScintProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/NeutronScintProcessor.cpp rename to Analysis/Utkscan/processors/source/NeutronScintProcessor.cpp diff --git a/Scan/utkscan/processors/source/PositionProcessor.cpp b/Analysis/Utkscan/processors/source/PositionProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/PositionProcessor.cpp rename to Analysis/Utkscan/processors/source/PositionProcessor.cpp diff --git a/Scan/utkscan/processors/source/PspmtProcessor.cpp b/Analysis/Utkscan/processors/source/PspmtProcessor.cpp similarity index 96% rename from Scan/utkscan/processors/source/PspmtProcessor.cpp rename to Analysis/Utkscan/processors/source/PspmtProcessor.cpp index c5414efcc..452b6ca8d 100644 --- a/Scan/utkscan/processors/source/PspmtProcessor.cpp +++ b/Analysis/Utkscan/processors/source/PspmtProcessor.cpp @@ -145,7 +145,7 @@ bool PspmtProcessor::PreProcess(RawEvent &event){ double xtre_r=0,xtre_l=0,ytre_t=0,ytre_b=0; double qqdc_r=0,qqdc_l=0,qqdc_t=0,qqdc_b=0,qqdc_s=0; - double xqdc_r=0,xqdc_l=0,yqdc_t=0,yqdc_b=0; + //double xqdc_r=0,xqdc_l=0,yqdc_t=0,yqdc_b=0; double pxright=0,pxleft=0,pytop=0,pybottom=0; double pxtre_r=0,pxtre_l=0,pytre_t=0,pytre_b=0; @@ -171,7 +171,7 @@ bool PspmtProcessor::PreProcess(RawEvent &event){ double trace_energy; //double trace_time; - double baseline; + //double baseline; double qdc; //int num = trace.GetValue("numPulses"); @@ -179,7 +179,7 @@ bool PspmtProcessor::PreProcess(RawEvent &event){ traceNum++; //trace_time = trace.GetValue("filterTime"); trace_energy = trace.GetValue("filterEnergy"); - baseline = trace.GetValue("baseline"); + //baseline = trace.GetValue("baseline"); qdc = trace.GetValue("qdc"); if(ch==0){ @@ -275,10 +275,10 @@ bool PspmtProcessor::PreProcess(RawEvent &event){ qqdc_r=(qdc4+qdc1)/2; qqdc_s=(qqdc_t+qqdc_l+qqdc_b+qqdc_r)/2; - xqdc_r=(qqdc_r/qqdc_s)*512+100; - xqdc_l=(qqdc_l/qqdc_s)*512+100; - yqdc_t=(qqdc_t/qqdc_s)*512+100; - yqdc_b=(qqdc_b/qqdc_s)*512+100; +// xqdc_r=(qqdc_r/qqdc_s)*512+100; +// xqdc_l=(qqdc_l/qqdc_s)*512+100; +// yqdc_t=(qqdc_t/qqdc_s)*512+100; +// yqdc_b=(qqdc_b/qqdc_s)*512+100; plot(D_ENERGY_TRACESUM,qqdc_s); } @@ -302,7 +302,8 @@ bool PspmtProcessor::PreProcess(RawEvent &event){ plot(D_TEMP4,f*qd); } - for(vector::iterator ittr = trace.begin();ittr != trace.end();ittr++) + for(vector::iterator ittr = trace.begin(); + ittr != trace.end();ittr++) plot(DD_SINGLE_TRACE,ittr-trace.begin(),traceNum,*ittr); } } // end of channel event diff --git a/Scan/utkscan/processors/source/RootProcessor.cpp b/Analysis/Utkscan/processors/source/RootProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/RootProcessor.cpp rename to Analysis/Utkscan/processors/source/RootProcessor.cpp diff --git a/Scan/utkscan/processors/source/ScintProcessor.cpp b/Analysis/Utkscan/processors/source/ScintProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/ScintProcessor.cpp rename to Analysis/Utkscan/processors/source/ScintProcessor.cpp diff --git a/Scan/utkscan/processors/source/SsdBetaProcessor.cpp b/Analysis/Utkscan/processors/source/SsdBetaProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/SsdBetaProcessor.cpp rename to Analysis/Utkscan/processors/source/SsdBetaProcessor.cpp diff --git a/Scan/utkscan/processors/source/SsdProcessor.cpp b/Analysis/Utkscan/processors/source/SsdProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/SsdProcessor.cpp rename to Analysis/Utkscan/processors/source/SsdProcessor.cpp diff --git a/Scan/utkscan/processors/source/TeenyVandleProcessor.cpp b/Analysis/Utkscan/processors/source/TeenyVandleProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/TeenyVandleProcessor.cpp rename to Analysis/Utkscan/processors/source/TeenyVandleProcessor.cpp diff --git a/Scan/utkscan/processors/source/TemplateProcessor.cpp b/Analysis/Utkscan/processors/source/TemplateProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/TemplateProcessor.cpp rename to Analysis/Utkscan/processors/source/TemplateProcessor.cpp diff --git a/Scan/utkscan/processors/source/ValidProcessor.cpp b/Analysis/Utkscan/processors/source/ValidProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/ValidProcessor.cpp rename to Analysis/Utkscan/processors/source/ValidProcessor.cpp diff --git a/Scan/utkscan/processors/source/VandleProcessor.cpp b/Analysis/Utkscan/processors/source/VandleProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/VandleProcessor.cpp rename to Analysis/Utkscan/processors/source/VandleProcessor.cpp diff --git a/Scan/utkscan/share/utkscan/bananas/077cu.ban b/Analysis/Utkscan/share/utkscan/bananas/077cu.ban similarity index 100% rename from Scan/utkscan/share/utkscan/bananas/077cu.ban rename to Analysis/Utkscan/share/utkscan/bananas/077cu.ban diff --git a/Scan/utkscan/share/utkscan/bananas/test.ban b/Analysis/Utkscan/share/utkscan/bananas/test.ban similarity index 100% rename from Scan/utkscan/share/utkscan/bananas/test.ban rename to Analysis/Utkscan/share/utkscan/bananas/test.ban diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_01.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_01.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_01.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_01.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_03.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_03.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_03.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_03.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_06.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_06.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_06.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_06.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_07.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_07.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_07.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_07.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_08.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_08.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_08.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_08.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_10.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_10.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_10.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_10.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_11.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_11.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_11.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_11.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_12.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_12.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_12.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/85As/as85_apr_12.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/1471/anl2015.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/1471/anl2015.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/1471/anl2015.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/1471/anl2015.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/anl/2013/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/anl/2013/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/anl/2013/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/anl/2013/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/examples/cal.xml b/Analysis/Utkscan/share/utkscan/cfgs/examples/cal.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/examples/cal.xml rename to Analysis/Utkscan/share/utkscan/cfgs/examples/cal.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/examples/example.xml b/Analysis/Utkscan/share/utkscan/cfgs/examples/example.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/examples/example.xml rename to Analysis/Utkscan/share/utkscan/cfgs/examples/example.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/examples/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/examples/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/examples/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/examples/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/gcal.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/gcal.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/gcal.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/gcal.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/051k/is599_51k_01.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/051k/is599_51k_01.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/051k/is599_51k_01.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/051k/is599_51k_01.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_00.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_00.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_00.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_00.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_01.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_01.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_01.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_01.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_02.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_02.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_02.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_02.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_04.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_04.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_04.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_04.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-alt.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-alt.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-alt.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-alt.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-mod.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-mod.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-mod.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-mod.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_00.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_00.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_00.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_00.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_01.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_01.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_01.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_01.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_02.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_02.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_02.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_02.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_03.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_03.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_03.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_03.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_04.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_04.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_04.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_04.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_08.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_08.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_08.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_08.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_09.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_09.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_09.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_09.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_10.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_10.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_10.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_10.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_12.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_12.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_12.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_12.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/054k/is599_54k_01.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/054k/is599_54k_01.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/054k/is599_54k_01.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/054k/is599_54k_01.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/cf05.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/cf05.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/cf05.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/cf05.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/is599_07232015-1219am.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/is599_07232015-1219am.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/is599_07232015-1219am.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/aug/is599_07232015-1219am.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_02.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_02.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_02.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_02.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_03.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_03.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_03.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_03.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_04.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_04.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_04.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_04.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_05.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_05.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_05.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_05.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_06.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_06.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_06.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_06.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_08.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_08.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_08.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_08.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a130_00.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a130_00.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a130_00.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a130_00.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_03.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_03.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_03.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_03.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_07.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_07.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_07.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_07.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_08.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_08.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_08.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_08.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_09.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_09.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_09.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_09.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_10.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_10.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_10.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_10.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_11.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_11.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_11.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_11.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_12.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_12.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_12.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_12.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_13.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_13.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_13.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_13.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_14.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_14.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_14.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_14.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_15.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_15.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_15.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_15.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_cf03.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_cf03.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_cf03.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/is600/is600_cf03.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/master.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/master.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/master.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/master.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/vcal.xml b/Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/vcal.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/isolde/is599-600/vcal.xml rename to Analysis/Utkscan/share/utkscan/cfgs/isolde/is599-600/vcal.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/01-2013/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/05-2013/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/gainmatching/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/nscl/e11027/toftest/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/leribss2011/73cu.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/leribss2011/73cu.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/leribss2011/73cu.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/leribss2011/73cu.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/leribss2011/93br.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/leribss2011/93br.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/leribss2011/93br.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/leribss2011/93br.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/Globals.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/Globals.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/Globals.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/Globals.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/cal.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/cal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/cal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/cal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/filter.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/filter.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/filter.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/filter.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/map2.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/map2.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/map2.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/map2.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/qdc.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/qdc.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/qdc.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/qdc.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingConstants.txt b/Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingConstants.txt similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingConstants.txt rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/monaOrnl/timingConstants.txt diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-01-4.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-01-4.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-01-4.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-01-4.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-105-7.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-105-7.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-105-7.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-105-7.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-test.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-test.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-test.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-test.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/084ga/084ga-001-3.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/084ga/084ga-001-3.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/084ga/084ga-001-3.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/084ga/084ga-001-3.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/085as/85as-test.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/085as/85as-test.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/085as/85as-test.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/085as/85as-test.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/83ga.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/83ga.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/83ga.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/83ga.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/85ga.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/85ga.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/85ga.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/85ga.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/86ga.xml b/Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/86ga.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/ornl/vandle2012/86ga.xml rename to Analysis/Utkscan/share/utkscan/cfgs/ornl/vandle2012/86ga.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/she/Config.xml.she b/Analysis/Utkscan/share/utkscan/cfgs/she/Config.xml.she similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/she/Config.xml.she rename to Analysis/Utkscan/share/utkscan/cfgs/she/Config.xml.she diff --git a/Scan/utkscan/share/utkscan/cfgs/she/Config.xml.she2010 b/Analysis/Utkscan/share/utkscan/cfgs/she/Config.xml.she2010 similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/she/Config.xml.she2010 rename to Analysis/Utkscan/share/utkscan/cfgs/she/Config.xml.she2010 diff --git a/Scan/utkscan/share/utkscan/cfgs/svp/newhist.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/newhist.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/newhist.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/newhist.xml diff --git a/Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml new file mode 100644 index 000000000..36f53986d --- /dev/null +++ b/Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml @@ -0,0 +1,172 @@ + + + + + S. V. Paulauskas + spaulaus AT utk DOT edu + August 29, 2016 + + + + + A timing setup to measure time difference between two pulser signals + using CFDs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/svp/pulsertst.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/pulsertst.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/pulsertst.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/pulsertst.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/svp/skutek.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/skutek.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/skutek.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/skutek.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/svp/testing.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/testing.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/testing.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/testing.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/utk/labr3tst.xml b/Analysis/Utkscan/share/utkscan/cfgs/utk/labr3tst.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/utk/labr3tst.xml rename to Analysis/Utkscan/share/utkscan/cfgs/utk/labr3tst.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/utk/pulser.xml b/Analysis/Utkscan/share/utkscan/cfgs/utk/pulser.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/utk/pulser.xml rename to Analysis/Utkscan/share/utkscan/cfgs/utk/pulser.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml b/Analysis/Utkscan/share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml rename to Analysis/Utkscan/share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/utk/sipm/sienergytst.xml b/Analysis/Utkscan/share/utkscan/cfgs/utk/sipm/sienergytst.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/utk/sipm/sienergytst.xml rename to Analysis/Utkscan/share/utkscan/cfgs/utk/sipm/sienergytst.xml diff --git a/Scan/utkscan/share/utkscan/cfgs/utk/tvandleWalk.xml b/Analysis/Utkscan/share/utkscan/cfgs/utk/tvandleWalk.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/utk/tvandleWalk.xml rename to Analysis/Utkscan/share/utkscan/cfgs/utk/tvandleWalk.xml diff --git a/Scan/utkscan/share/utkscan/scripts/analyze.bash b/Analysis/Utkscan/share/utkscan/scripts/analyze.bash similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/analyze.bash rename to Analysis/Utkscan/share/utkscan/scripts/analyze.bash diff --git a/Scan/utkscan/share/utkscan/scripts/cmapbill.dat b/Analysis/Utkscan/share/utkscan/scripts/cmapbill.dat similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/cmapbill.dat rename to Analysis/Utkscan/share/utkscan/scripts/cmapbill.dat diff --git a/Scan/utkscan/share/utkscan/scripts/makedist.bash b/Analysis/Utkscan/share/utkscan/scripts/makedist.bash similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/makedist.bash rename to Analysis/Utkscan/share/utkscan/scripts/makedist.bash diff --git a/Scan/utkscan/share/utkscan/scripts/map_to_config.py b/Analysis/Utkscan/share/utkscan/scripts/map_to_config.py similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/map_to_config.py rename to Analysis/Utkscan/share/utkscan/scripts/map_to_config.py diff --git a/Scan/utkscan/share/utkscan/scripts/multianalyze.bash b/Analysis/Utkscan/share/utkscan/scripts/multianalyze.bash similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/multianalyze.bash rename to Analysis/Utkscan/share/utkscan/scripts/multianalyze.bash diff --git a/Scan/utkscan/share/utkscan/scripts/online.bash b/Analysis/Utkscan/share/utkscan/scripts/online.bash similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/online.bash rename to Analysis/Utkscan/share/utkscan/scripts/online.bash diff --git a/Scan/utkscan/share/utkscan/scripts/qrun.bash b/Analysis/Utkscan/share/utkscan/scripts/qrun.bash similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/qrun.bash rename to Analysis/Utkscan/share/utkscan/scripts/qrun.bash diff --git a/Scan/utkscan/share/utkscan/scripts/start.cmd b/Analysis/Utkscan/share/utkscan/scripts/start.cmd similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/start.cmd rename to Analysis/Utkscan/share/utkscan/scripts/start.cmd diff --git a/Scan/utkscan/share/utkscan/scripts/tcaltoxml.awk b/Analysis/Utkscan/share/utkscan/scripts/tcaltoxml.awk similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/tcaltoxml.awk rename to Analysis/Utkscan/share/utkscan/scripts/tcaltoxml.awk diff --git a/Scan/utkscan/share/utkscan/scripts/test.cmd b/Analysis/Utkscan/share/utkscan/scripts/test.cmd similarity index 100% rename from Scan/utkscan/share/utkscan/scripts/test.cmd rename to Analysis/Utkscan/share/utkscan/scripts/test.cmd diff --git a/CMakeLists.txt b/CMakeLists.txt index c235523aa..c599ec899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,11 +22,15 @@ if (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC") endif() -#if user does not specify prefix we assign it to the exec directory +#if user does not specify prefix we assign it to the install directory +#@TODO I do not like the fact that it makes the install directory before I'm +#ready for it. There are cases where I do not want to actually install just +#build. This configuration adds additional junk to my directory that I may +#not actually want or need. if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) message(STATUS "Install Prefix not specified.") file(MAKE_DIRECTORY install) - get_filename_component(INSTALL_DIR ${CMAKE_SOURCE_DIR}/install REALPATH) + get_filename_component(INSTALL_DIR ${CMAKE_BINARY_DIR}/../install REALPATH) set(CMAKE_INSTALL_PREFIX ${INSTALL_DIR} CACHE PATH "Install Prefix" FORCE) endif() message(STATUS "Installing to ${CMAKE_INSTALL_PREFIX}") @@ -48,12 +52,13 @@ endif(CMAKE_BUILD_TYPE MATCHES "Debug") #------------------------------------------------------------------------------ #Install options +option(BUILD_ACQ "Build and install Acquisition software" ON) option(BUILD_SCOPE "Build and install the scope program." ON) option(BUILD_SETUP "Include the older setup programs in installation" OFF) option(BUILD_SHARED_LIBS "Install only scan libraries" ON) option(BUILD_SKELETON "Build and install the skeleton scan" OFF) -option(BUILD_SUITE "Build and install PixieSuite" ON) option(BUILD_TESTS "Builds programs designed to test the package." OFF) +option(BUILD_UNITTESTS "Bulid Unit Tests using UnitTest++ Framework" OFF) option(BUILD_UTKSCAN "Build utkscan" OFF) option(USE_DAMM "Use DAMM for MCA" ON) @@ -63,23 +68,16 @@ option(USE_ROOT "Use ROOT" ON) #------------------------------------------------------------------------------ -#Definitions without options - -#Adds the install prefix for referencing in the source code -add_definitions(-D INSTALL_PREFIX="\\"${CMAKE_INSTALL_PREFIX}\\"") - -#Definitions with options - +#Definitions with compiler options #The MCA will write DAMM histograms as output if(USE_DAMM) add_definitions("-D USE_DAMM") endif() #------------------------------------------------------------------------------ - -#Find packages needed for poll2 +#Find packages needed for the software. #Load additional find_package scripts. -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/Cmake/modules/") #Find thread library for poll2 and scanLib find_package (Threads REQUIRED) @@ -102,15 +100,21 @@ else() set(USE_NCURSES OFF) endif() - -if (BUILD_SUITE) - if(NOT BUILD_SUITE_ATTEMPTED AND NOT PLX_FOUND AND NOT PXI_FOUND) - set (BUILD_SUITE OFF CACHE BOOL "Build and install PixieSuite" FORCE) +#Find the UnitTest++ Package. This package can be obtained from +#https://github.com/unittest-cpp/unittest-cpp.git +if(BUILD_UNITTESTS) + find_package(UnitTest++ REQUIRED) + link_directories(${UNITTEST++_LIBRARY_DIR}) + include_directories(${UNITTEST++_INCLUDE_DIR}) +endif(BUILD_UNITTESTS) + +if (BUILD_ACQ) + if(NOT BUILD_ACQ_ATTEMPTED AND NOT PLX_FOUND AND NOT PXI_FOUND) + set (BUILD_ACQ OFF CACHE BOOL "Build and install PixieSuite" FORCE) else (PLX_FOUND OR PXI_FOUND) #Find the PLX Library find_package(PLX REQUIRED) - link_directories(${PLX_LIBRARY_DIR}) - #add_definitions("-DPLX_LINUX -DPCI_CODE -DPLX_LITTLE_ENDIAN") + link_directories(${PLX_LIBRARY_DIR}) #Find the Pixie Firmware find_package(PXI REQUIRED) @@ -123,8 +127,8 @@ if (BUILD_SUITE) #created when make cfg is typed add_custom_target(config ${CMAKE_COMMAND} -P pixie_cfg.cmake) endif() - set (BUILD_SUITE_ATTEMPTED ON CACHE INTERNAL "Build Suite Attempted") -endif(BUILD_SUITE) + set (BUILD_ACQ_ATTEMPTED ON CACHE INTERNAL "Build Suite Attempted") +endif(BUILD_ACQ) #Find ROOT if USE_ROOT was set. if (USE_ROOT) @@ -138,35 +142,28 @@ if (USE_ROOT) endif() #------------------------------------------------------------------------------ -#Build the Core library +#Include and build the Resources that everybody should have access to. +include_directories(Resources/include) +add_subdirectory(Resources) + +#Build the PaassCoreLibrary. include_directories(Core/include) add_subdirectory(Core) -#Build the scan library -add_subdirectory(Scan) - -#Building polling tools -if (BUILD_SUITE) - #Build the pixie interface - include_directories(Interface/include) - add_subdirectory(Interface/source) - - #Build the MCA objects - include_directories(MCA/include) - add_subdirectory(MCA) - - #Build the setup tools - if (BUILD_SETUP) - include_directories(Setup/include) - add_subdirectory(Setup) - endif() +#Next we are going to build any of the ThirdParty software that we've included. +include_directories(ThirdParty/include) +#We'll go straight to the source directory since for now we don't need any +#fancy logic in the base directory. +add_subdirectory(ThirdParty) - #Build poll - add_subdirectory(Poll) +#Build Acquisition software, we don't have this broken into as fine of a +#granularity as the Analysis software, so we just wrap the whole thing in an if. +if (BUILD_ACQ) + add_subdirectory(Acquisition) endif() -#Build PxiDump -add_subdirectory(PxiDump) +#Build any of the analysis related things that we need to build. +add_subdirectory(Analysis) #Build/install the miscellaneous stuff -add_subdirectory(share) +add_subdirectory(Share) diff --git a/cmake/modules/FindGSL.cmake b/Cmake/modules/FindGSL.cmake similarity index 100% rename from cmake/modules/FindGSL.cmake rename to Cmake/modules/FindGSL.cmake diff --git a/cmake/modules/FindHRIBF.cmake b/Cmake/modules/FindHRIBF.cmake similarity index 100% rename from cmake/modules/FindHRIBF.cmake rename to Cmake/modules/FindHRIBF.cmake diff --git a/cmake/modules/FindPLX.cmake b/Cmake/modules/FindPLX.cmake similarity index 100% rename from cmake/modules/FindPLX.cmake rename to Cmake/modules/FindPLX.cmake diff --git a/Cmake/modules/FindPXI.cmake b/Cmake/modules/FindPXI.cmake new file mode 100644 index 000000000..d196fa62f --- /dev/null +++ b/Cmake/modules/FindPXI.cmake @@ -0,0 +1,258 @@ +# Find the PXI Library +# +# Sets the usual variables expected for find_package scripts: +# +# PXI_LIBRARY_DIR +# PXI_FOUND - true if PXI was found. +# + +#Unset any cached value to ensure a fresh search is performed. +#This permits the user to change the PXI_ROOT_DIR and have subsequent paths updated. +unset(PXI_LIBRARY_DIR CACHE) + +#Find the library path by looking for the library. +find_path(PXI_LIBRARY_DIR + NAMES libPixie16App.a libPixie16Sys.a + HINTS ${PXI_ROOT_DIR} + PATHS /opt/xia/current /opt/xia/software + PATH_SUFFIXES software + DOC "Path to pixie library.") + +get_filename_component(PXI_LIBRARY_DIR "${PXI_LIBRARY_DIR}" REALPATH) + +if(NOT PXI_FIRMWARE_DIR) + get_filename_component(PXI_FIRMWARE_DIR "${PXI_LIBRARY_DIR}/../.." REALPATH) +endif(NOT PXI_FIRMWARE_DIR) +set(PXI_FIRMWARE_DIR ${PXI_FIRMWARE_DIR} CACHE PATH "Path to folder containing XIA firmware.") + +#The order is strange here as we are really interested in the libraries first +# then we determine the root directory from there. + +# Support the REQUIRED and QUIET arguments, and set PXI_FOUND if found. +include (FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (PXI DEFAULT_MSG PXI_LIBRARY_DIR) + +if (PXI_FOUND) + set (PXI_INCLUDE_DIR ${PXI_LIBRARY_DIR}/inc ${PXI_LIBRARY_DIR}/sys ${PXI_LIBRARY_DIR}/app) + set(PXI_LIBRARIES -lPixie16App -lPixie16Sys) +endif() + +function(PXI_CONFIG) + message(STATUS "Creating Pixie configuration.") + + get_filename_component(PXI_ROOT_DIR "${PXI_LIBRARY_DIR}/.." REALPATH) + + #create an installer that can be invoked by + #add_custom_target(config ${CMAKE_COMMAND} -P pixie_cfg.cmake) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake + "file(INSTALL pixie.cfg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n" + ) + + #Write some useful info. + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#Pixie Configuration\n" + "#\n" + "#The following lines provide the configuration for a XIA Pixie16 data acquistion \n" + "#system. The configuration file is broken into two sections a global section for \n" + "#tags that affect the entire system and a module specific section. The global tags\n" + "#include: PixieBaseDir, CrateConfig, SlotFile, DspSetFileFile, and \n" + "#DspWorkingSetFile. The module tags include: ModuleType, ModuleBaseDir, \n" + "#SpFpgaFile, ComFpgaFile, DspConfFile, and DspVarFile. The module tags are \n" + "#associated with the type specified prior to the tag. If no type is specified the \n" + "#type 'default' is used. \n" + "#\n" + "#The tag values are prepended with a base directory unless the first character in \n" + "#the value is forward slash, '/', or a period '.', permiting the use of absolute \n" + "#and relative paths. The global tags are prepended with the PixieBaseDir. Module \n" + "#tags are prepended with the ModuleBaseDir if specified otherwise the PixieBaseDir\n" + "#is used. If no base directory is determined the path is assumed to be local to \n" + "#the running directory.\n" + "\n" + ) + + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "# Global Tags\n\n") + + #Write the base directory + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "PixieBaseDir\t\t${PXI_ROOT_DIR}\n") + + #Following are lists of keys and the glob expr to find the files + set(CONFIG_NAME CrateConfig SlotFile DspSetFile) + set(CONFIG_EXPR + test/pxisys*.ini #CrateConfig + configuration/slot_def.set #SlotFile + configuration/default.set #DspSetFile + ) + + foreach(CONFIG_STEP RANGE 0 2) + #Get key name and expression form the list + list(GET CONFIG_NAME ${CONFIG_STEP} KEY) + list(GET CONFIG_EXPR ${CONFIG_STEP} GLOB_EXPR) + + #Find all files matching the expression + # Returns the path of the file relative to the base directory. + file(GLOB FILE_MATCHES RELATIVE ${PXI_ROOT_DIR} ${PXI_ROOT_DIR}/${GLOB_EXPR}) + + #Check that a unique match was found + list(LENGTH FILE_MATCHES NUM_MATCHES) + if (NOT NUM_MATCHES EQUAL 1) + message(STATUS "WARNING: Unable to autocomplete global configuration!\n\tUnique ${KEY} file (${GLOB_EXPR}) not found!") + if (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: No ${KEY} found! Please specify and remove this comment.\n") + else (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: Multiple ${KEY}s found! Please choose one and remove this comment.\n") + endif (NUM_MATCHES EQUAL 0) + endif() + + if (${KEY} MATCHES "SlotFile") + if (NUM_MATCHES EQUAL 1) + configure_file(${PXI_ROOT_DIR}/${FILE_MATCHES} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake + "file(INSTALL slot_def.set DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") + set(FILE_MATCHES "./slot_def.set") + endif() + elseif (${KEY} MATCHES "DspSetFile") + if (NUM_MATCHES EQUAL 1) + configure_file(${PXI_ROOT_DIR}/${FILE_MATCHES} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake + "file(INSTALL default.set + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") + #Rename set file to current.set to maintain default.set for backup + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake + "file(INSTALL default.set + RENAME current.set + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") + set(FILE_MATCHES ./current.set) + endif() + endif () + + #Append the config file + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "${KEY}\t\t${FILE_MATCHES}\n") + endforeach(CONFIG_STEP RANGE 0 2) + + #Added the working set file name + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "DspWorkingSetFile\t./current.set\n") + + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "\n# Module Tags\n") + + #Look in the root directory for the XIA library + if(NOT EXISTS ${PXI_FIRMWARE_DIR}) + message(WARNING "Configuration Error - Invalid Pixie firmware directory: ${PXI_FIRMWARE_DIR}") + return() + endif(NOT EXISTS ${PXI_FIRMWARE_DIR}) + subdirlist(PXI_FIRMWARE_DIRS ${PXI_FIRMWARE_DIR}) + + #remove directories without subdirectories firmware and dsp. + foreach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + if (NOT (EXISTS ${FIRMWARE_DIR}/firmware OR EXISTS ${FIRMWARE_FIR}/dsp)) + list(REMOVE_ITEM PXI_FIRMWARE_DIRS ${FIRMWARE_DIR}) + endif (NOT (EXISTS ${FIRMWARE_DIR}/firmware OR EXISTS ${FIRMWARE_FIR}/dsp)) + endforeach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + + #Following are lists of keys and the glob expr to find the files + set(CONFIG_NAME SpFpgaFile ComFpgaFile DspConfFile DspVarFile) + set(CONFIG_EXPR + firmware/fippixie16*.bin #SpFpgaFile + firmware/syspixie16*.bin #ComFpgaFile + dsp/Pixie16DSP*.ldr #DspConfFile + dsp/Pixie16DSP*.var #DspVarFile + ) + + foreach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + #determine the module type from the fippi SpFpga File + unset(MODULE_TYPE) + file(GLOB FILE_MATCHES RELATIVE ${FIRMWARE_DIR} ${FIRMWARE_DIR}/firmware/fippixie16*.bin) + foreach(FILENAME ${FILE_MATCHES}) + string(REGEX MATCH "[01234567890]+b[0123456789]+m" TYPE ${FILENAME}) + string(REGEX MATCH "rev[abcdf]" REVISION ${FILENAME}) + #If type is missing we set it to "unknown" + if ("${TYPE}" STREQUAL "") + set(TYPE "unknown") + endif() + + #If revision is missing we set it to "revUnknown" + if ("${REVISION}" STREQUAL "") + set(REVISION "revUnknown") + endif() + + #Only add the module type if it is not in the list. + if(NOT MODULE_TYPE MATCHES "${TYPE}-${REVISION}") + list(APPEND MODULE_TYPE "${TYPE}-${REVISION}") + endif(NOT MODULE_TYPE MATCHES "${TYPE}-${REVISION}") + endforeach(FILENAME ${FILE_MATCHES}) + + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "\n") + + message(STATUS "Autoconfiguring module type: ${MODULE_TYPE}.") + + list(LENGTH MODULE_TYPE NUM_MATCHES) + if (NUM_MATCHES EQUAL 1) + if (${MODULE_TYPE} MATCHES "unknown") + message(STATUS "WARNING: Incomplete module type (${MODULE_TYPE}) found in:") + message(STATUS " ${FIRMWARE_DIR}") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: Incomplete ModuleType found! Please correct and remove this comment.\n") + endif (${MODULE_TYPE} MATCHES "unknown") + else (NUM_MATCHES EQUAL 1) + message(STATUS "WARNING: Multiple module types (${MODULE_TYPE}) found in:") + message(STATUS " ${FIRMWARE_DIR}") + if (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: No ModuleType found! Please specify and remove this comment.\n") + else (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: Multiple ModuleTypes found! Please choose one and remove this comment.\n") + endif (NUM_MATCHES EQUAL 0) + endif (NUM_MATCHES EQUAL 1) + + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "ModuleType\t\t${MODULE_TYPE}\n") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "ModuleBaseDir\t\t${FIRMWARE_DIR}\n") + + #We loop over each item in the list and search for a matching file + foreach(CONFIG_STEP RANGE 0 3) + #Get key name and expression form the list + list(GET CONFIG_NAME ${CONFIG_STEP} KEY) + list(GET CONFIG_EXPR ${CONFIG_STEP} GLOB_EXPR) + + #Find all files matching the expression + # Returns the path of the file relative to the base directory. + file(GLOB FILE_MATCHES RELATIVE ${FIRMWARE_DIR} ${FIRMWARE_DIR}/${GLOB_EXPR}) + + #Check that a unique match was found + list(LENGTH FILE_MATCHES NUM_MATCHES) + if (NOT NUM_MATCHES EQUAL 1) + if (NOT ERROR) + set(ERROR TRUE) + message(STATUS "WARNING: Unable to autocomplete ${MODULE_TYPE} configuration!") + endif (NOT ERROR) + message(STATUS " Unique ${KEY} file (${GLOB_EXPR}) not found!") + if (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: No ${KEY} found! Please specify and remove this comment.\n") + else (NUM_MATCHES EQUAL 0) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "#ERROR: Multiple ${KEY}s found! Please choose one and remove this comment.\n") + endif (NUM_MATCHES EQUAL 0) + endif() + + #Append the config file + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "${KEY}\t\t${FILE_MATCHES}\n") + endforeach(CONFIG_STEP RANGE 0 3) + endforeach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + +endfunction() + +macro(SUBDIRLIST result curdir) + FILE(GLOB children RELATIVE ${curdir} "${curdir}/*") + FOREACH(child ${children}) + IF(IS_DIRECTORY ${curdir}/${child}) + GET_FILENAME_COMPONENT(child ${curdir}/${child} REALPATH) + LIST(APPEND dirlist ${child}) + ENDIF() + ENDFOREACH() + LIST(REMOVE_DUPLICATES dirlist) + SET(${result} ${dirlist}) +endmacro(SUBDIRLIST) + diff --git a/cmake/modules/FindROOT.cmake b/Cmake/modules/FindROOT.cmake similarity index 100% rename from cmake/modules/FindROOT.cmake rename to Cmake/modules/FindROOT.cmake diff --git a/Cmake/modules/FindUnitTest++.cmake b/Cmake/modules/FindUnitTest++.cmake new file mode 100644 index 000000000..e619f273e --- /dev/null +++ b/Cmake/modules/FindUnitTest++.cmake @@ -0,0 +1,21 @@ +# - Finds UnitTestCpp instalation +# It defines: +# UNITTEST++_INCLUDE_DIR - The Directory containing the headers +# UNITTEST++_LIBRARY_DIR - The directory containing the libraries. +#Last updated by S. V. Paulauskas (spaulaus AT utk DOT edu) on November 22, 2016 + +#Locate the Include directory +find_path(UNITTEST++_INCLUDE_DIR + NAMES UnitTest++.h + PATHS /opt/UnitTest++/include /usr/local/include + PATH_SUFFIXES UnitTest++) +#Locate the library +find_path(UNITTEST++_LIBRARY_DIR + NAMES libUnitTest++.a + PATHS /opt/UnitTest++ /usr/lib/ + PATH_SUFFIXES lib) + +include (FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (UnitTest++ DEFAULT_MSG + UNITTEST++_INCLUDE_DIR) +mark_as_advanced (UNITTEST++_INCLUDE_DIR UNITTEST++_LIBRARY_DIR) diff --git a/Core/include/CTerminal.h b/Core/include/CTerminal.h index 6b9c282cd..5df437fe2 100644 --- a/Core/include/CTerminal.h +++ b/Core/include/CTerminal.h @@ -186,6 +186,10 @@ class Terminal{ /// Split a string into multiple commands separated by a ';'. void split_commands(const std::string &input_, std::deque &cmds); + + /// Print the command prompt to the screen. + void PrintPrompt(); + public: Terminal(); diff --git a/Core/include/hribf_buffers.h b/Core/include/hribf_buffers.h index 9bfb62d68..3bc6b300a 100644 --- a/Core/include/hribf_buffers.h +++ b/Core/include/hribf_buffers.h @@ -78,6 +78,9 @@ class PLD_header : public BufferType{ char end_date[25]; // Wed Feb 13 16:06:10 2013 (24 bytes) char *run_title; // Unlimited length + time_t runStartTime; + time_t runStopTime; + public: PLD_header(); ~PLD_header(); @@ -405,7 +408,7 @@ class PollOutputFile{ std::string GetNextFileName(unsigned int &run_num_, std::string prefix, std::string output_dir, bool continueRun = false); - unsigned int GetRunNumber() {return dirBuff.GetRunNumber();} + unsigned int GetRunNumber(); /// Write the footer and close the file void CloseFile(float total_run_time_=0.0); diff --git a/Core/source/CMakeLists.txt b/Core/source/CMakeLists.txt index 4a098255d..ecaf237d6 100644 --- a/Core/source/CMakeLists.txt +++ b/Core/source/CMakeLists.txt @@ -1,24 +1,21 @@ -set(PixieCore_SOURCES - Display.cpp - hribf_buffers.cpp - poll2_socket.cpp ) +set(PaassCoreSources Display.cpp hribf_buffers.cpp poll2_socket.cpp ) if (${CURSES_FOUND}) - list(APPEND PixieCore_SOURCES CTerminal.cpp) + list(APPEND PaassCoreSources CTerminal.cpp) endif() -add_library(PixieCoreObjects OBJECT ${PixieCore_SOURCES}) +add_library(PaassCoreObjects OBJECT ${PaassCoreSources}) -add_library(PixieCoreStatic STATIC $) +add_library(PaassCoreStatic STATIC $) if (${CURSES_FOUND}) - target_link_libraries(PixieCoreStatic ${CURSES_LIBRARIES}) + target_link_libraries(PaassCoreStatic ${CURSES_LIBRARIES}) endif() if(BUILD_SHARED_LIBS) - add_library(PixieCore SHARED $) + add_library(PaassCore SHARED $) if (${CURSES_FOUND}) - target_link_libraries(PixieCore ${CURSES_LIBRARIES}) + target_link_libraries(PaassCore ${CURSES_LIBRARIES}) endif() - install(TARGETS PixieCore DESTINATION lib) + install(TARGETS PaassCore DESTINATION lib) endif(BUILD_SHARED_LIBS) \ No newline at end of file diff --git a/Core/source/CTerminal.cpp b/Core/source/CTerminal.cpp index 1b53bb771..6f97308f1 100644 --- a/Core/source/CTerminal.cpp +++ b/Core/source/CTerminal.cpp @@ -290,12 +290,12 @@ void Terminal::update_cursor_(){ } void Terminal::clear_(){ - for(int start = cmd.length() + offset; start >= offset; start--){ + for(int start = cmd.length() + offset; start >= 0; start--){ wmove(input_window, 0, start); wdelch(input_window); } cmd.clear(); - cursX = offset; + cursX = 0; update_cursor_(); refresh_(); } @@ -639,12 +639,15 @@ void Terminal::SetPrompt(const char *input_){ } } } - print(input_window,prompt.c_str()); - offset += prompt.length() - lastPos; + + PrintPrompt(); +} + +void Terminal::PrintPrompt() { + print(input_window,prompt.c_str()); cursX = offset; update_cursor_(); - refresh_(); } @@ -820,6 +823,9 @@ void Terminal::PrintCommand(const std::string &cmd_){ } std::string Terminal::GetCommand(std::string &args, const int &prev_cmd_return_/*=0*/){ + if (cursX == 0) { + PrintPrompt(); + } std::string output = ""; sclock::time_point commandRequestTime = sclock::now(); @@ -941,6 +947,7 @@ std::string Terminal::GetCommand(std::string &args, const int &prev_cmd_return_/ std::string temp_cmd = commands.GetPrev(); if(temp_cmd != "NULL"){ clear_(); + PrintPrompt(); cmd.assign(temp_cmd); in_print_(cmd.c_str()); } @@ -949,6 +956,7 @@ std::string Terminal::GetCommand(std::string &args, const int &prev_cmd_return_/ std::string temp_cmd = commands.GetNext(); if(temp_cmd != "NULL"){ clear_(); + PrintPrompt(); cmd.assign(temp_cmd); in_print_(cmd.c_str()); } @@ -961,14 +969,14 @@ std::string Terminal::GetCommand(std::string &args, const int &prev_cmd_return_/ else if(keypress == KEY_NPAGE){ //Page down key scroll_(_winSizeY-2); } - else if(keypress == KEY_BACKSPACE){ // 263 + else if(keypress == KEY_BACKSPACE || keypress == 8){ // ncurses.h backspace character (KEY_BACKSPACE=263), ASCII code BS =8 if (cursX - offset > 0 ) { wmove(input_window, 0, --cursX); wdelch(input_window); cmd.erase(cursX - offset,1); } } - else if(keypress == KEY_DC){ // Delete character (330) + else if(keypress == KEY_DC || keypress == 127){ // ncurses.h Delete character (KEY_DC=330), ASCII code DEL=127 //Remove character from terminal wdelch(input_window); //Remove character from cmd string diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 392446ea8..3f698db57 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -96,12 +96,11 @@ bool BufferType::ReadHeader(std::ifstream *file_){ /// Default constructor. PLD_header::PLD_header() : BufferType(HEAD, 0){ // 0x44414548 "HEAD" - PLD_header::Reset(); + this->Reset(); } /// Destructor. PLD_header::~PLD_header(){ - if(run_title){ delete[] run_title; } } /// Get the length of the header buffer. @@ -114,19 +113,20 @@ unsigned int PLD_header::GetBufferLength(){ /// Set the date and tiem of when the file is opened. void PLD_header::SetStartDateTime(){ - time_t rawtime; - time (&rawtime); + time (&runStartTime); - char *date_holder = ctime(&rawtime); + char *date_holder = ctime(&runStartTime); set_char_array(std::string(date_holder), start_date, 24); // Strip the trailing newline character } /// Set the date and time of when the file is closed. void PLD_header::SetEndDateTime(){ - time_t rawtime; - time (&rawtime); + time (&runStopTime); + + // Calculate the time difference between stop and start. + run_time = (float)difftime(runStopTime, runStartTime); - char *date_holder = ctime(&rawtime); + char *date_holder = ctime(&runStopTime); set_char_array(std::string(date_holder), end_date, 24); // Strip the trailing newline character } @@ -255,6 +255,7 @@ void PLD_header::PrintDelimited(const char &delimiter_/*='\t'*/){ /// Default constructor. PLD_data::PLD_data() : BufferType(DATA, 0){ // 0x41544144 "DATA" + this->Reset(); } /// Write a pld style data buffer to file. @@ -319,6 +320,7 @@ bool PLD_data::Read(std::ifstream *file_, char *data_, unsigned int &nBytes, uns /// Default constructor. DIR_buffer::DIR_buffer() : BufferType(DIR, NO_HEADER_SIZE){ // 0x20524944 "DIR " + this->Reset(); } /** DIR buffer (1 word buffer type, 1 word buffer size, 1 word for total buffer length, @@ -392,6 +394,7 @@ void DIR_buffer::PrintDelimited(const char &delimiter_/*='\t'*/){ /// Default constructor. HEAD_buffer::HEAD_buffer() : BufferType(HEAD, 64){ // 0x44414548 "HEAD" + this->Reset(); } /// Set the date and time of the ldf file. @@ -590,6 +593,7 @@ DATA_buffer::DATA_buffer() : BufferType(DATA, NO_HEADER_SIZE){ // 0x41544144 "DA good_chunks = 0; missing_chunks = 0; buff_pos = 0; + this->Reset(); } /// Close a ldf data buffer by padding with 0xFFFFFFFF. @@ -700,9 +704,10 @@ bool DATA_buffer::Write(std::ofstream *file_, char *data_, unsigned int nWords_, if(buff_pos > LDF_DATA_LENGTH) std::cout << "WARNING: Final ldf buffer overfilled by " << buff_pos - LDF_DATA_LENGTH << " words!\n"; - // Write the spill footer. - if(buff_pos + 6 > LDF_DATA_LENGTH){ + // Check if we can fit the spill footer into the current buffer. + if(buff_pos + 6 > LDF_DATA_LENGTH){ // Close the current buffer and open a new one. buffs_written++; + Close(file_); open_(file_); } @@ -1029,7 +1034,7 @@ bool PollOutputFile::overwrite_dir(int total_buffers_/*=-1*/){ /// Initialize the output file with initial parameters void PollOutputFile::initialize(){ - max_spill_size = -9999; + max_spill_size = 0; current_file_num = 0; output_format = 0; number_spills = 0; @@ -1264,6 +1269,13 @@ std::string PollOutputFile::GetNextFileName(unsigned int &run_num_, std::string return filename.str(); } +unsigned int PollOutputFile::GetRunNumber() { + if(output_format == 0) return dirBuff.GetRunNumber(); + else if(output_format == 1) return pldHead.GetRunNumber(); + else if(debug_mode) std::cout << "debug: invalid output format for PollOutputFile::GetRunNumber!\n"; + return 0; +} + /// Write the footer and close the file. void PollOutputFile::CloseFile(float total_run_time_/*=0.0*/){ if(!output_file.is_open() || !output_file.good()){ return; } @@ -1286,7 +1298,6 @@ void PollOutputFile::CloseFile(float total_run_time_/*=0.0*/){ // Overwrite the blank pld header at the beginning of the file and close it output_file.seekp(0); pldHead.SetEndDateTime(); - pldHead.SetRunTime(total_run_time_); pldHead.SetMaxSpillSize(max_spill_size); pldHead.Write(&output_file); output_file.close(); diff --git a/Core/tests/CMakeLists.txt b/Core/tests/CMakeLists.txt index 60b5258cc..4eaaa360d 100644 --- a/Core/tests/CMakeLists.txt +++ b/Core/tests/CMakeLists.txt @@ -1,3 +1,3 @@ add_executable(CTerminalTest CTerminalTest.cpp) -target_link_libraries(CTerminalTest PixieCore) +target_link_libraries(CTerminalTest PaassCoreStatic) install (TARGETS CTerminalTest DESTINATION bin) diff --git a/Core/tests/CTerminalTest.cpp b/Core/tests/CTerminalTest.cpp index cb854c56b..41e1db796 100644 --- a/Core/tests/CTerminalTest.cpp +++ b/Core/tests/CTerminalTest.cpp @@ -16,6 +16,7 @@ int main(int argc, char *argv[]){ Terminal term; term.Initialize(); std::cout << "This is test terminal.\n" ; + std::cout << "$TERM: " << std::getenv("TERM") << "\n"; term.SetCommandHistory("CTerminalTest.cmd"); term.SetPrompt("Test> "); diff --git a/doc/doxyfile b/Doc/doxyfile similarity index 99% rename from doc/doxyfile rename to Doc/doxyfile index 261d73dcc..d50202d14 100644 --- a/doc/doxyfile +++ b/Doc/doxyfile @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doc/ +OUTPUT_DIRECTORY = Doc/ # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -759,7 +759,7 @@ WARN_FORMAT = "$file:$line: $text" # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = doxywarning.txt +WARN_LOGFILE = /tmp/paass-doxywarning.txt #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -771,7 +771,8 @@ WARN_LOGFILE = doxywarning.txt # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ./ +INPUT = Acquisition Analysis Core Cmake Doc/pages/ \ + Resources # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -811,12 +812,8 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = Scan/utkscan/include/pugiconfig.hpp \ - Scan/utkscan/include/pugixml.hpp \ - Scan/utkscan/include/MersenneTwister.hpp \ - Scan/utkscan/src/core/pugixml.cpp \ - README.md \ - Scan/utkscan/README.md +EXCLUDE = Analysis/Utkscan/core/include/MersenneTwister.hpp \ + README.md # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -832,7 +829,7 @@ EXCLUDE_SYMLINKS = YES # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = */EventDict/* +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -869,7 +866,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = doc/pics +IMAGE_PATH = Doc/pics # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/doc/pages/mainPage.dox b/Doc/pages/mainPage.dox similarity index 100% rename from doc/pages/mainPage.dox rename to Doc/pages/mainPage.dox diff --git a/doc/pics/analysisflow.eps b/Doc/pics/analysisflow.eps similarity index 100% rename from doc/pics/analysisflow.eps rename to Doc/pics/analysisflow.eps diff --git a/doc/pics/analysisflow.jpg b/Doc/pics/analysisflow.jpg similarity index 100% rename from doc/pics/analysisflow.jpg rename to Doc/pics/analysisflow.jpg diff --git a/doc/pics/timingCorrection.eps b/Doc/pics/timingCorrection.eps similarity index 100% rename from doc/pics/timingCorrection.eps rename to Doc/pics/timingCorrection.eps diff --git a/doc/pics/timingCorrection.jpg b/Doc/pics/timingCorrection.jpg similarity index 100% rename from doc/pics/timingCorrection.jpg rename to Doc/pics/timingCorrection.jpg diff --git a/Resources/CMakeLists.txt b/Resources/CMakeLists.txt new file mode 100644 index 000000000..e4f7ac6e1 --- /dev/null +++ b/Resources/CMakeLists.txt @@ -0,0 +1,3 @@ +if(BUILD_TESTS OR BUILD_UNITTESTS) + add_subdirectory(tests) +endif(BUILD_TESTS OR BUILD_UNITTESTS) \ No newline at end of file diff --git a/Resources/include/HelperEnumerations.hpp b/Resources/include/HelperEnumerations.hpp new file mode 100644 index 000000000..a0ecc0be9 --- /dev/null +++ b/Resources/include/HelperEnumerations.hpp @@ -0,0 +1,52 @@ +///@file HelperEnumerations.hpp +///@brief Header containing namespaced enumerations that are useful to +/// different parts of the software. +///@author S. V. Paulauskas +///@date December 6, 2016 +#ifndef PIXIESUITE_HELPERENUMERATIONS_HPP +#define PIXIESUITE_HELPERENUMERATIONS_HPP + +namespace Timing { + /// An enum listing the known CFD analysis types + enum CFD_TYPE { + POLY, XIA, BASIC + }; + /// An enum listing the known Fitter types + enum FITTER_TYPE { + GSL, UNKNOWN + }; +} + +namespace DataProcessing { + ///An enum for the different firmware revisions for the Pixie-16 modules. + /// * R17562 is valid from 12/15/2010 to 09/26/2011 (this is primarily a + /// Rev D firmware, i.e. 100 MS/s) + /// * R20466 is valid from 09/26/2011 to 06/11/2013 + /// * R27361 is valid from 06/11/2013 to 02/15/2014 + /// * R29432 is valid from 02/15/2014 to 07/28/2014 + /// * R30474, R30980, R30981 is valid from 07/28/2014 to 03/08/2016 + /// * R29432 is valid from 03/08/2016 + /// * UNKNOWN is used for unspecified firmware revisions. + ///These dates do not imply that the particular data set being analyzed was + /// taken with the expected firmware. These dates are meant only to help + /// guide the user if they do not know the particular firmware that was used + /// to obtain their data set. + enum FIRMWARE { + R17562, R20466, R27361, R29432, R30474, R30980, R30981, R34688, UNKNOWN + }; + + ///An enumeration that tells how long headers from the XIA List mode data + /// are depending on the different options that are enabled. The order + /// that the components are listed is the order that they appear in the + /// header. For example, HEADER_W_ESUM_ETS is the length of the header + /// when we have the default 4 words, plus the Energy Sums (4 words) and + /// the External Time Stamps (2 words). + enum HEADER_CODES { + STATS_BLOCK = 1, HEADER = 4, HEADER_W_ETS = 6, HEADER_W_ESUM = 8, + HEADER_W_ESUM_ETS = 10, HEADER_W_QDC = 12, HEADER_W_QDC_ETS = 14, + HEADER_W_ESUM_QDC = 16, HEADER_W_ESUM_QDC_ETS = 18 + }; +} + + +#endif //PIXIESUITE_HELPERENUMERATIONS_HPP diff --git a/Resources/include/HelperFunctions.hpp b/Resources/include/HelperFunctions.hpp new file mode 100644 index 000000000..5ae145bf8 --- /dev/null +++ b/Resources/include/HelperFunctions.hpp @@ -0,0 +1,462 @@ +///@file HelperFunctions.hpp +///@brief A file containing stand-alone functions (only depend on standard +/// C++ headers) that are used in the software. +///@author S. V. Paulauskas +///@date December 6, 2016 +#ifndef PIXIESUITE_HELPERFUNCTIONS_HPP +#define PIXIESUITE_HELPERFUNCTIONS_HPP + +#include +#include +#include +#include +#include + +#include + +using namespace std; + +namespace Polynomial { + template + static const pair > CalculatePoly2( + const vector &data, const unsigned int &startBin) { + if (data.size() < 3) + throw range_error("Polynomial::CalculatePoly2 - The data vector " + "had the wrong size : " + data.size()); + + double x1[3], x2[3]; + for (size_t i = 0; i < 3; i++) { + x1[i] = (startBin + i); + x2[i] = std::pow(startBin + i, 2); + } + + double denom = + (x1[1] * x2[2] - x2[1] * x1[2]) - x1[0] * (x2[2] - x2[1] * 1) + + x2[0] * (x1[2] - x1[1] * 1); + + double p0 = ((data[x1[0]] * (x1[1] * x2[2] - x2[1] * x1[2]) - + x1[0] * + (data[x1[1]] * x2[2] - x2[1] * data[x1[2]]) + + x2[0] * + (data[x1[1]] * x1[2] - x1[1] * data[x1[2]])) / denom); + double p1 = (((data[x1[1]] * x2[2] - x2[1] * data[x1[2]]) - + data[x1[0]] * (x2[2] - x2[1] * 1) + + x2[0] * (data[x1[2]] - data[x1[1]] * 1)) / denom); + double p2 = (((x1[1] * data[x1[2]] - data[x1[1]] * x1[2]) - + x1[0] * (data[x1[2]] - data[x1[1]] * 1) + + data[x1[0]] * (x1[2] - x1[1] * 1)) / denom); + + //Put the coefficients into a vector in ascending power order + vector coeffs = {p0, p1, p2}; + + return make_pair(p0 - ((p1 * p1) / (4 * p2)), coeffs); + } + + template + static const pair > CalculatePoly3( + const vector &data, const unsigned int &startBin) { + if (data.size() < 4) + throw range_error("Polynomial::CalculatePoly3 - The data vector " + "had the wrong size : " + data.size()); + + double x1[4], x2[4], x3[4]; + for (size_t i = 0; i < 4; i++) { + x1[i] = (startBin + i); + x2[i] = std::pow(startBin + i, 2); + x3[i] = std::pow(startBin + i, 3); + } + + double denom = (x1[1] * (x2[2] * x3[3] - x2[3] * x3[2]) - + x1[2] * (x2[1] * x3[3] - x2[3] * x3[1]) + + x1[3] * (x2[1] * x3[2] - x2[2] * x3[1])) - + (x1[0] * (x2[2] * x3[3] - x2[3] * x3[2]) - + x1[2] * (x2[0] * x3[3] - x2[3] * x3[0]) + + x1[3] * (x2[0] * x3[2] - x2[2] * x3[0])) + + (x1[0] * (x2[1] * x3[3] - x2[3] * x3[1]) - + x1[1] * (x2[0] * x3[3] - x2[3] * x3[0]) + + x1[3] * (x2[0] * x3[1] - x2[1] * x3[0])) - + (x1[0] * (x2[1] * x3[2] - x2[2] * x3[1]) - + x1[1] * (x2[0] * x3[2] - x2[2] * x3[0]) + + x1[2] * (x2[0] * x3[1] - x2[1] * x3[0])); + + double p0 = (double) ( + (data[x1[0]] * (x1[1] * (x2[2] * x3[3] - x2[3] * x3[2]) - + x1[2] * (x2[1] * x3[3] - x2[3] * x3[1]) + + x1[3] * (x2[1] * x3[2] - x2[2] * x3[1])) - + data[x1[1]] * (x1[0] * (x2[2] * x3[3] - x2[3] * x3[2]) - + x1[2] * (x2[0] * x3[3] - x2[3] * x3[0]) + + x1[3] * (x2[0] * x3[2] - x2[2] * x3[0])) + + data[x1[2]] * (x1[0] * (x2[1] * x3[3] - x2[3] * x3[1]) - + x1[1] * (x2[0] * x3[3] - x2[3] * x3[0]) + + x1[3] * (x2[0] * x3[1] - x2[1] * x3[0])) - + data[x1[3]] * (x1[0] * (x2[1] * x3[2] - x2[2] * x3[1]) - + x1[1] * (x2[0] * x3[2] - x2[2] * x3[0]) + + x1[2] * (x2[0] * x3[1] - x2[1] * x3[0]))) / + denom); + + double p1 = (double) (((data[x1[1]] * (x2[2] * x3[3] - x2[3] * x3[2]) - + data[x1[2]] * (x2[1] * x3[3] - x2[3] * x3[1]) + + data[x1[3]] * (x2[1] * x3[2] - x2[2] * x3[1])) - + (data[x1[0]] * (x2[2] * x3[3] - x2[3] * x3[2]) - + data[x1[2]] * (x2[0] * x3[3] - x2[3] * x3[0]) + + data[x1[3]] * (x2[0] * x3[2] - x2[2] * x3[0])) + + (data[x1[0]] * (x2[1] * x3[3] - x2[3] * x3[1]) - + data[x1[1]] * (x2[0] * x3[3] - x2[3] * x3[0]) + + data[x1[3]] * (x2[0] * x3[1] - x2[1] * x3[0])) - + (data[x1[0]] * (x2[1] * x3[2] - x2[2] * x3[1]) - + data[x1[1]] * (x2[0] * x3[2] - x2[2] * x3[0]) + + data[x1[2]] * + (x2[0] * x3[1] - x2[1] * x3[0]))) / + denom); + + double p2 = (double) ( + ((x1[1] * (data[x1[2]] * x3[3] - data[x1[3]] * x3[2]) - + x1[2] * (data[x1[1]] * x3[3] - data[x1[3]] * x3[1]) + + x1[3] * (data[x1[1]] * x3[2] - data[x1[2]] * x3[1])) - + (x1[0] * (data[x1[2]] * x3[3] - data[x1[3]] * x3[2]) - + x1[2] * (data[x1[0]] * x3[3] - data[x1[3]] * x3[0]) + + x1[3] * (data[x1[0]] * x3[2] - data[x1[2]] * x3[0])) + + (x1[0] * (data[x1[1]] * x3[3] - data[x1[3]] * x3[1]) - + x1[1] * (data[x1[0]] * x3[3] - data[x1[3]] * x3[0]) + + x1[3] * (data[x1[0]] * x3[1] - data[x1[1]] * x3[0])) - + (x1[0] * (data[x1[1]] * x3[2] - data[x1[2]] * x3[1]) - + x1[1] * (data[x1[0]] * x3[2] - data[x1[2]] * x3[0]) + + x1[2] * (data[x1[0]] * x3[1] - data[x1[1]] * x3[0]))) / + denom); + + double p3 = (double) ( + ((x1[1] * (x2[2] * data[x1[3]] - x2[3] * data[x1[2]]) - + x1[2] * (x2[1] * data[x1[3]] - x2[3] * data[x1[1]]) + + x1[3] * (x2[1] * data[x1[2]] - x2[2] * data[x1[1]])) - + (x1[0] * (x2[2] * data[x1[3]] - x2[3] * data[x1[2]]) - + x1[2] * (x2[0] * data[x1[3]] - x2[3] * data[x1[0]]) + + x1[3] * (x2[0] * data[x1[2]] - x2[2] * data[x1[0]])) + + (x1[0] * (x2[1] * data[x1[3]] - x2[3] * data[x1[1]]) - + x1[1] * (x2[0] * data[x1[3]] - x2[3] * data[x1[0]]) + + x1[3] * (x2[0] * data[x1[1]] - x2[1] * data[x1[0]])) - + (x1[0] * (x2[1] * data[x1[2]] - x2[2] * data[x1[1]]) - + x1[1] * (x2[0] * data[x1[2]] - x2[2] * data[x1[0]]) + + x1[2] * (x2[0] * data[x1[1]] - x2[1] * data[x1[0]]))) / + denom); + + //Put the coefficients into a vector in ascending power order + vector coeffs = {p0, p1, p2, p3}; + + // Calculate the maximum of the polynomial. + double xmax; + double node1 = + (-2 * p2 + std::sqrt(4 * p2 * p2 - 12 * p3 * p1)) / (6 * p3); + double node2 = + (-2 * p2 - std::sqrt(4 * p2 * p2 - 12 * p3 * p1)) / (6 * p3); + + //Check if the curvature at node1 is positive or negative. If it is + // negative then we have the maximum. If not then node2 is the + // maximum. + if ((2 * p2 + 6 * p3 * node1) < 0) + xmax = node1; + else + xmax = node2; + + return make_pair(p0 + p1 * xmax + p2 * xmax * xmax + + p3 * xmax * xmax * xmax, coeffs); + } +}//Polynomial namespace + +namespace Statistics { + template + inline double CalculateAverage(const vector &data) { + double sum = 0.0; + for (typename vector::const_iterator i = data.begin(); + i != data.end(); i++) + sum += *i; + sum /= data.size(); + return sum; + } + + //This calculation for the standard deviation assumes that we are + // analyzing the full population, which we are in this case. + template + inline double CalculateStandardDeviation(const vector &data, + const double &mean) { + double stddev = 0.0; + for (typename vector::const_iterator it = data.begin(); + it != data.end(); it++) + stddev += pow(*it - mean, 2); + stddev = sqrt(stddev / (double) data.size()); + return stddev; + } + + ///@brief Do a quick and simple integration of the provided data using the + /// trapezoidal rule. We will not be subtracting the baseline or anything + /// like that to keep things general. + ///@param[in] data : The data that we want to integrate. + ///@return The integrated value + template + inline double CalculateIntegral(const vector &data) { + if (data.size() < 2) + throw range_error("Statistical::CalculateIntegral - The data " + "vector was too small to integrate. We " + "need at least a size of 2."); + double integral = 0.0; + for (unsigned int i = 1; i < data.size(); i++) + integral += 0.5 * (double(data[i - 1] + data[i])); + return integral; + } +} + +namespace TraceFunctions { + ///The minimum length that is necessary for a good baseline calculation. + static const unsigned int minimum_baseline_length = 10; + + ///@brief Compute the trace baseline and its standard deviation. This + /// function takes a data range in the event that someone wants to + /// specify a range that is not at the beginning of the trace, or specify + /// some other range. The range given must have a minimum given by the + /// minimum_baseline_length variable. + ///@param[in] data : The vector of data containing only the baseline. + ///@param[in] range : the low and high range that we are going to use for + /// the baseline + ///@return A pair with the first element being the average of the + /// baseline and the second element being the standard deviation of the + /// baseline. + template + inline pair CalculateBaseline( + const vector &data, + const pair &range) { + if (data.size() == 0) + throw range_error("TraceFunctions::ComputeBaseline - Data vector " + "sized 0"); + + if (range.second < range.first) + throw range_error("TraceFunctions::ComputeBaseline - Bad range : " + "High > Low"); + + if (data.size() < (range.second - range.first)) + throw range_error("TraceFunctions::ComputeBaseline - Data vector " + "size is smaller than requested range."); + + if (range.second - range.first < minimum_baseline_length) + throw range_error("TraceFunctions::ComputeBaseline - The range " + "specified is smaller than the minimum" + " necessary range."); + double baseline = + Statistics::CalculateAverage( + vector(data.begin(), data.begin() + + range.second)); + double stddev = + Statistics::CalculateStandardDeviation( + vector(data.begin(), data.begin() + + range.second), + baseline); + return make_pair(baseline, stddev); + } + + ///@brief This function uses a third order polynomial to calculate the + /// true position of the maximum for the given data. We look at the + /// points on either side of the maximum value to determine which side + /// the true maximum lies on. We then pass the data vector and the bin + /// that we want to start the fit on to the fitting class. + /// @param[in] data : The data that we would like to find the true + /// maximum of + /// @param[in] maxInfo : The low resolution maximum information that we + /// need to determine where to start the fit. + /// @return An STL pair containing the maximum that we found and the + template + inline pair > ExtrapolateMaximum( + const vector &data, + const pair &maxInfo) { + if (data.size() < 4) + throw range_error("TraceFunctions::ExtrapolateMaximum - " + "The data vector has less than 4 " + "elements, we need at least four " + "elements to determine the desired " + "information."); + unsigned int fitStartBin; + + if (data[maxInfo.first - 1] >= data[maxInfo.first + 1]) + fitStartBin = maxInfo.first - 2; + else + fitStartBin = maxInfo.first - 1; + + // Find the true maximum by fitting with a third order polynomial. + return Polynomial::CalculatePoly3(data, fitStartBin); + } + + + ///@brief This function finds the maximum bin and the value of the + /// maximum bin + /// for the provided vector. The search is targeted by using the trace + /// delay that was set for the traces. At this point we are not going to + /// be calculating the high resolution maximum. We need additional + /// information about the bit resolution of the module to check for a + /// saturated trace. Since that would remove the generality of this + /// function we do not perform this check here. It's up to the user to + /// verify the results of this function for saturations. + /// NOTE: We do not subtract the baseline at this stage. + /// @param[in] data : The vector of data that we will be using to find + /// the maximum + /// @param[in] traceDelayInBins : The value of the trace delay that was + /// set for this particular trace. + /// @return A STL pair containing the bin and value of the maximum found + /// in the trace. + template + inline pair FindMaximum( + const vector &data, + const unsigned int &traceDelayInBins) { + stringstream msg; + if (data.size() == 0) + throw range_error("TraceFunctions::FindMaximum - The data was of " + "size 0."); + + //if high bound is outside the trace then we throw a range error. + if (traceDelayInBins > data.size()) { + msg << "TraceFunctions::FindMaxiumum - The requested trace delay (" + << traceDelayInBins << ") was larger than the size of the data " + << "vector(" << data.size() << "."; + throw range_error(msg.str()); + } + + //If the trace delay is smaller than the minimum_baseline_length then + // we will throw an error. + if (traceDelayInBins < minimum_baseline_length) { + msg << "TraceFunctions::FindMaximum - The provided traceDelayInBins" + << "(" << traceDelayInBins << ") was too small it must" + << " be greater than " << minimum_baseline_length; + throw range_error(msg.str()); + } + + //We need to target our search so that we do not get traces that are + // too close to beginning of the trace. The lower bound for the + // search will be the beginning of the trace plus the + // minimum_baseline_length. + typename vector::const_iterator itPos = + max_element(data.begin() + minimum_baseline_length, + data.begin() + traceDelayInBins); + + + if (itPos == data.end()) { + msg << "TraceFunctions::FindMaximum - No maximum could" + << " be found in the range : [" << minimum_baseline_length + << "," << traceDelayInBins << "]."; + throw range_error(msg.str()); + } + return make_pair((unsigned int) (itPos - data.begin()), *itPos); + } + + ///@TODO Fix this method so that it works properly. + template + inline unsigned int FindLeadingEdge(const vector &data, + const double &fraction, + const pair &maxInfo) { + if (fraction <= 0) + throw range_error("TraceFunctions::FindLeadingEdge - The " + "threshold was below zero."); + if (data.size() < minimum_baseline_length) + throw range_error("TraceFunctions::FindLeadingEdge - The data " + "vector did not contain enough " + "information to find the leading edge."); + if (data.size() < maxInfo.first) + throw range_error("TraceFunctions::FindLeadingEdge - The " + "position of the maximum is outside of " + "the size of the data vector."); + + double threshold = fraction * maxInfo.second; + unsigned int idx = 9999; + for (size_t index = maxInfo.first; + index > minimum_baseline_length; index--) + if (data[index - 1] < threshold && data[index] >= threshold) + idx = index - 1; + return idx; + } + + ///This is an exclusive calculation, meaning that the value at the low + /// and high end of the calculation will not be used to calculate the + /// integral. + template + inline double CalculateQdc(const vector &data, + const pair &range) { + stringstream msg; + if (data.size() == 0) + throw range_error("TraceFunctions::CalculateQdc - The size of " + "the data vector was zero."); + if (data.size() < range.second) { + msg << "TraceFunctions::CalculateQdc - The specified " + << "range was larger than the range : [" << range.first + << "," << range.second << "]."; + throw range_error(msg.str()); + } + + if(range.first > range.second) { + msg << "TraceFunctions::CalculateQdc - The specified " + << "range was inverted."; + throw range_error(msg.str()); + } + return Statistics::CalculateIntegral( + vector(data.begin() + range.first, + data.begin() + range.second)); + } + + template + inline double CalculateTailRatio(const vector &data, + const pair &range, + const double &qdc) { + stringstream msg; + if (data.size() == 0) + throw range_error( + "TraceFunctions::CalculateTailRatio - The size of " + "the data vector was zero."); + if (data.size() < range.second) { + msg << "TraceFunctions::CalculateTailRatio - The specified " + << "range was larger than the range : [" << range.first + << "," << range.second << "]."; + throw range_error(msg.str()); + } + + if (qdc == 0) + throw range_error("TraceFunctions::CalculateTailRatio - The QDC " + "had a value of zero. This will cause " + "issues."); + + return Statistics::CalculateIntegral( + vector(data.begin() + range.first, + data.begin() + range.second)) / qdc; + + } + + ///@brief This namespace holds functions that are used to validate the + /// functions. + ///@TODO Impelement the validation functions for the functions in the + /// TraceFunctions namespace. Necessary to simplify the codebase. + namespace Validation { + + + } +} + +namespace IeeeStandards { + ///This function converts an IEEE Floating Point number into a standard + /// decimal format. This function was stolen almost verbatim from + /// utilities.c provided by XIA. This data format is used by XIA to store + /// both TAU and the Baseline. Magic numbers abound since we're + /// literally following a prescription on how this information is + /// stored. + ///https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008 + ///@param[in] IeeeFloatingNumber : The IEEE Floating point number that we + /// want to convert to decimal + ///@return The decimal number that's been decoded from the input. + inline double IeeeFloatingToDecimal( + const unsigned int &IeeeFloatingNumber) { + double result; + short signbit = (short)(IeeeFloatingNumber >> 31); + short exponent = (short)((IeeeFloatingNumber & 0x7F800000) >> 23) - 127; + double mantissa = + 1.0 + (double)(IeeeFloatingNumber & 0x7FFFFF) / pow(2.0, 23.0); + if(signbit == 0) + result = mantissa * pow(2.0, (double)exponent); + else + result = - mantissa * pow(2.0, (double)exponent); + return result; + } +} + +#endif //PIXIESUITE_HELPERFUNCTIONS_HPP diff --git a/Resources/include/UnitTestSampleData.hpp b/Resources/include/UnitTestSampleData.hpp new file mode 100644 index 000000000..facfd2c2b --- /dev/null +++ b/Resources/include/UnitTestSampleData.hpp @@ -0,0 +1,287 @@ +///@file UnitTestSampleData.hpp +///@brief This header provides sample data that can be used by Unit Tests to +/// ensure proper functionality. +///@author S. V. Paulauskas +///@date December 18, 2016 + +#ifndef PIXIESUITE_UNITTESTSAMPLEDATA_HPP +#define PIXIESUITE_UNITTESTSAMPLEDATA_HPP + +#include +#include + +///This namespace contains the raw channel information that was used to +/// construct the headers in the unittest_encoded_data namespace. These values +/// are also used when testing the data encoding. +namespace unittest_decoded_data { + //Here is all of the expected data for the above header. + static const unsigned int channelNumber = 13; + static const unsigned int crateId = 0; + static const unsigned int expected_size = 1; + static const unsigned int ts_high = 26001; + static const unsigned int ts_low = 123456789; + static const unsigned int cfd_fractional_time = 1234; + static const unsigned int slotId = 2; + static const unsigned int energy = 2345; + static const unsigned int ex_ts_high = 26001; + static const unsigned int ex_ts_low = 987654321; + static const bool cfd_forced_trigger = true; + static const bool cfd_source_trigger_bit = true; + static const bool pileup_bit = true; + static const bool trace_out_of_range = true; + static const bool virtual_channel = true; + + static const std::vector energy_sums = {12, 13, 14}; + + static const std::vector qdc = {123, 456, 789, 987, 654, + 321, 135, 791}; + + //Need to figure out where to put these as they are Firmware / Frequency + // specific values. They are for R30747, 250 MS/s. + static const double ts = 111673568120085; + static const double ts_w_cfd = 223347136240170.075317; +} + +///This namespace contains Firmware / Frequency specific headers that are +/// used to test the decoding of data. The headers that we have here include +/// the 2 words that are inserted by poll2 so that the +/// XiaListModeDataDecoder::DecodeBuffer method will function properly. +namespace unittest_encoded_data { + //A buffer with zero length + unsigned int empty_buffer[2] = {0, 0}; + + //A buffer that for an empty module + unsigned int empty_module_buffer[2] = {2, 0}; + + ///A header with a header length 20 instead of the true header length 4 + unsigned int header_w_bad_headerlen[6] = {4, 0, 3887149, 123456789, 26001, + 2345}; + + ///A header where the event length doesn't match what it should be. + unsigned int header_w_bad_eventlen[6] = {59, 0, 7749677, 123456789, 26001, + 8128809}; + + namespace R30474_250 { + //Standard header without anything fancy includes the two additional + // words we add in poll for the length and the module number + unsigned int header[6] = {4, 0, 540717, 123456789, 26001, 2345}; + + //The header is the standard 4 words. The trace is 62 words, which gives + // a trace length of 124. This gives us an event length of 66. + // We have 2 words for the Pixie Module Data Header. + unsigned int header_N_trace[68] = { + 66, 0, 8667181, 123456789, 26001, 8128809, + 28574133, 28443058, 28639669, 28508598, 28705202, 28639671, + 28443062, 28770739, 28443062, 28508594, 28836277, 28508599, + 28770741, 28508598, 28574132, 28770741, 28377523, 28574130, + 28901815, 28639668, 28705207, 28508598, 28443058, 28705206, + 28443058, 28836277, 28705207, 28574130, 28770743, 28574133, + 28574130, 28639670, 28639668, 28836280, 28574135, 28639667, + 73531893, 229968182, 227217128, 155716457, 100796282, 68355300, + 49152877, 40567451, 36897359, 30016014, 26411403, 31326660, + 32637420, 31261166, 30081484, 30212558, 29884876, 29622724, + 29688263, 28901822, 29098424, 30081480, 29491651, 29163967, + 29884865, 29819336 + }; + + //A header that also contains a QDC + unsigned int header_N_qdc[14] = { + 12, 0, 1622061, 123456789, 26001, 2345, + 123, 456, 789, 987, 654, 321, 135, 791 + }; + + //This header has the CFD fractional time set to 1234. + unsigned int header_N_Cfd[6]{4, 0, 540717, 123456789, 80897425, 2345}; + + std::vector header_vec = + {540717, 123456789, 26001, 2345}; + + std::vector header_vec_w_trc = { + 8667181, 123456789, 26001, 8128809, + 28574133, 28443058, 28639669, 28508598, 28705202, 28639671, + 28443062, 28770739, 28443062, 28508594, 28836277, 28508599, + 28770741, 28508598, 28574132, 28770741, 28377523, 28574130, + 28901815, 28639668, 28705207, 28508598, 28443058, 28705206, + 28443058, 28836277, 28705207, 28574130, 28770743, 28574133, + 28574130, 28639670, 28639668, 28836280, 28574135, 28639667, + 73531893, 229968182, 227217128, 155716457, 100796282, 68355300, + 49152877, 40567451, 36897359, 30016014, 26411403, 31326660, + 32637420, 31261166, 30081484, 30212558, 29884876, 29622724, + 29688263, 28901822, 29098424, 30081480, 29491651, 29163967, + 29884865, 29819336 + }; + + std::vector header_vec_w_qdc = { + 1622061, 123456789, 26001, 2345, + 123, 456, 789, 987, 654, 321, 135, 791 + }; + + std::vector header_vec_w_qdc_n_trc = { + 9748525, 123456789, 26001, 8128809, + 123, 456, 789, 987, 654, 321, 135, 791, + 28574133, 28443058, 28639669, 28508598, 28705202, 28639671, + 28443062, 28770739, 28443062, 28508594, 28836277, 28508599, + 28770741, 28508598, 28574132, 28770741, 28377523, 28574130, + 28901815, 28639668, 28705207, 28508598, 28443058, 28705206, + 28443058, 28836277, 28705207, 28574130, 28770743, 28574133, + 28574130, 28639670, 28639668, 28836280, 28574135, 28639667, + 73531893, 229968182, 227217128, 155716457, 100796282, 68355300, + 49152877, 40567451, 36897359, 30016014, 26411403, 31326660, + 32637420, 31261166, 30081484, 30212558, 29884876, 29622724, + 29688263, 28901822, 29098424, 30081480, 29491651, 29163967, + 29884865, 29819336 + }; + } +} + +namespace unittest_cfd_variables { + //Pair containing the fraction and the shift + static const std::pair cfd_test_pars(0.5, 2.); +} + +namespace unittest_fit_variables { + //Set the for the fitting from the results of a gnuplot script + static const std::pair fitting_parameters(0.2659404170, + 0.2080547991796); +} + +namespace unittest_trace_variables { + //This is a trace taken using a 12-bit 250 MS/s module from a medium VANDLE + // module. + static const std::vector trace = { + 437, 436, 434, 434, 437, 437, 438, 435, 434, 438, 439, 437, 438, + 434, 435, 439, 438, 434, 434, 435, 437, 440, 439, 435, 437, 439, + 438, 435, 436, 436, 437, 439, 435, 433, 434, 436, 439, 441, 436, + 437, 439, 438, 438, 435, 434, 434, 438, 438, 434, 434, 437, 440, + 439, 438, 434, 436, 439, 439, 437, 436, 434, 436, 438, 437, 436, + 437, 440, 440, 439, 436, 435, 437, 501, 1122, 2358, 3509, 3816, + 3467, 2921, 2376, 1914, 1538, 1252, 1043, 877, 750, 667, 619, + 591, 563, 526, 458, 395, 403, 452, 478, 492, 498, 494, 477, 460, + 459, 462, 461, 460, 456, 452, 452, 455, 453, 446, 441, 440, 444, + 456, 459, 451, 450, 447, 445, 449, 456, 456, 455 + }; + + static const std::vector trace_sans_baseline = { + 0.257143, -0.742857, -2.74286, -2.74286, 0.257143, 0.257143, + 1.25714, -1.74286, -2.74286, 1.25714, 2.25714, 0.257143, 1.25714, + -2.74286, -1.74286, 2.25714, 1.25714, -2.74286, -2.74286, -1.74286, + 0.257143, 3.25714, 2.25714, -1.74286, 0.257143, 2.25714, 1.25714, + -1.74286, -0.742857, -0.742857, 0.257143, 2.25714, -1.74286, + -3.74286, -2.74286, -0.742857, 2.25714, 4.25714, -0.742857, + 0.257143, 2.25714, 1.25714, 1.25714, -1.74286, -2.74286, -2.74286, + 1.25714, 1.25714, -2.74286, -2.74286, 0.257143, 3.25714, 2.25714, + 1.25714, -2.74286, -0.742857, 2.25714, 2.25714, 0.257143, -0.742857, + -2.74286, -0.742857, 1.25714, 0.257143, -0.742857, 0.257143, + 3.25714, 3.25714, 2.25714, -0.742857, -1.74286, 0.257143, 64.2571, + 685.257, 1921.26, 3072.26, 3379.26, 3030.26, 2484.26, 1939.26, + 1477.26, 1101.26, 815.257, 606.257, 440.257, 313.257, 230.257, + 182.257, 154.257, 126.257, 89.2571, 21.2571, -41.7429, -33.7429, + 15.2571, 41.2571, 55.2571, 61.2571, 57.2571, 40.2571, 23.2571, + 22.2571, 25.2571, 24.2571, 23.2571, 19.2571, 15.2571, 15.2571, + 18.2571, 16.2571, 9.25714, 4.25714, 3.25714, 7.25714, 19.2571, + 22.2571, 14.2571, 13.2571, 10.2571, 8.25714, 12.2571, 19.2571, + 19.2571, 18.2571 + }; + + //This is the region that should be defined as the waveform for the above + // trace + static const std::vector waveform( + trace_sans_baseline.begin() + 71, + trace_sans_baseline.begin() + 86); + + //An empty data vector to test error checking. + static const std::vector empty_vector_uint; + static const std::vector empty_vector_double; + + //A data vector that contains constant data. + static const std::vector const_vector_uint = {1000, 4}; + + /// This is the expected value of the maximum + static const double maximum_value = 3816; + + /// This is the expected position of the maximum + static const unsigned int max_position = 76; + + /// This is the pair made from the expected maximum information + static const std::pair max_pair( + max_position, maximum_value); + + //These two values were obtained using the first 70 values of the above trace. + //The expected baseline value was obtained using the AVERAGE function in + // Google Sheets. + static const double baseline = 436.7428571; + + //The expected standard deviation was obtained using the STDEVP function in + // Google Sheets. + static const double standard_deviation = 1.976184739; + + //Pair of these results to test with and use in other places + static const std::pair baseline_pair(baseline, + standard_deviation); + + ///The trace delay in bins for the signal above. + static const unsigned int trace_delay = 80; + + // Variables related to calculation of the tail ratio + static const double tail_ratio = 0.2960894762; + + // Variables related to the calculation of the extrapolated maximum + static const std::vector extrapolated_max_coeffs = + {-15641316.0007084, 592747.666694852, -7472.00000037373, + 31.3333333349849}; + + //Value of the extrapolated maximum for the above trace + static const double extrapolated_maximum = 3818.0718412264; + //Pair of the maximum position and extrapolated maximum + static const std::pair extrapolated_maximum_pair( + max_position, extrapolated_maximum); +} + +namespace unittest_helper_functions { + //-------------------------------------------------------------------------- + //A data vector to test the integration + static const std::vector integration_data = + {0, 1, 2, 3, 4, 5}; + //The expected value from the CalculateIntegral function + static const double integral = 12.5; + static const std::pair qdc_pair(2, 5); + //Expected QDC result of the integral for the above pair + static const double integration_qdc = 6; + + //-------------------------------------------------------------------------- + //A data vector that contains only the four points for the Poly3 Fitting. + static const std::vector poly3_data + (unittest_trace_variables::trace.begin() + 74, + unittest_trace_variables::trace.begin() + 78); + + //The expected maximum from the poly3 fitting + static const double poly3_maximum = + unittest_trace_variables::extrapolated_maximum; + + //A vector containing the coefficients obtained from gnuplot using the data + // from pol3_data with an x value starting at 0 + static const std::vector poly3_coeffs = + {2358.0, 1635.66666666667, -516.0, 31.3333333333333}; + + //-------------------------------------------------------------------------- + //A data vector containing only the three points for the Poly2 fitting + static const std::vector poly2_data( + unittest_trace_variables::trace.begin() + 73, + unittest_trace_variables::trace.begin() + 76); + + // Variables related to Polynomial::CalculatePoly2 + //The expected maximum from the pol2 fitting + static const double poly2_val = 10737.0720588236; + + //Vector containing the expected coefficients from the poly 2 fit + static const std::vector poly2_coeffs = + {1122.0, 1278.5, -42.4999999999999}; + + //-------------------------------------------------------------------------- + //This is the expected position of the leading edge of signal. + static const unsigned int leading_edge_position = 73; + static const double leading_edge_fraction = 0.5; + static const double bad_fraction = -0.5; +} + +#endif //PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP diff --git a/Resources/source/CMakeLists.txt b/Resources/source/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/Resources/tests/CMakeLists.txt b/Resources/tests/CMakeLists.txt new file mode 100644 index 000000000..0bd8201f8 --- /dev/null +++ b/Resources/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) +target_link_libraries(unittest-HelperFunctions UnitTest++) +install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) \ No newline at end of file diff --git a/Resources/tests/unittest-HelperFunctions.cpp b/Resources/tests/unittest-HelperFunctions.cpp new file mode 100644 index 000000000..5b06b7d53 --- /dev/null +++ b/Resources/tests/unittest-HelperFunctions.cpp @@ -0,0 +1,189 @@ +///@file unittest-HelperFunctions.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include + +#include "HelperFunctions.hpp" +#include "UnitTestSampleData.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_helper_functions; + +///This tests that the TraceFunctions::CalculateBaseline function works as +/// expected. This also verifies the Statistics functions CalculateAverage +/// and CalculateStandardDeviation +TEST(TestCalculateBaseline) { + //Checking that we throw a range_error when the range is too small + CHECK_THROW(TraceFunctions::CalculateBaseline(trace, make_pair(0, 1)), + range_error); + + //Checking that we throw a range_error when the data vector is sized 0 + CHECK_THROW(TraceFunctions::CalculateBaseline(empty_vector_uint, + make_pair(0, 16)), + range_error); + + //Checking that we throw a range_error when the range is inverted + CHECK_THROW(TraceFunctions::CalculateBaseline(trace, make_pair(17, 1)), + range_error); + + //Checking that we throw a range_error when the range is larger than the + // data vector + CHECK_THROW(TraceFunctions::CalculateBaseline( + trace, make_pair(0, trace.size() + 100)), range_error); + + //Check that we are actually calculating the parameters properly + pair result = + TraceFunctions::CalculateBaseline(trace, make_pair(0, 70)); + CHECK_CLOSE(baseline, result.first, 1e-7); + CHECK_CLOSE(standard_deviation, result.second, 1e-9); +} + +TEST(TestFindMaxiumum) { + //Checking that we throw a range_error when the data vector is sized 0 + CHECK_THROW(TraceFunctions::FindMaximum(empty_vector_uint, trace_delay), + range_error); + + //Checking that we are throwing a range_error when delay is larger than + // the size of the data vector + CHECK_THROW(TraceFunctions::FindMaximum(trace, trace.size() + 100), + range_error); + + //Checking that when the trace delay is smaller than the minimum number of + // samples for the baseline we throw an error + CHECK_THROW(TraceFunctions::FindMaximum(trace, 5), range_error); + + //Checking that we throw a range error if we could not find a maximum in + // the specified range. + CHECK_THROW(TraceFunctions::FindMaximum(const_vector_uint, trace_delay), + range_error); + + pair result = + TraceFunctions::FindMaximum(trace, trace_delay); + CHECK_EQUAL(max_position, result.first); + CHECK_EQUAL(maximum_value, result.second); +} + + +TEST(TestFindLeadingEdge) { + //Check that if we define a threshold that is 0 or less we throw a range + // error + CHECK_THROW(TraceFunctions::FindLeadingEdge(trace, bad_fraction, max_pair), + range_error); + //Check that we throw an error if if we have a vector that isn't big + // enough to do proper analysis. + CHECK_THROW(TraceFunctions::FindLeadingEdge(empty_vector_uint, + leading_edge_fraction, + max_pair), range_error); + //Check that if we have a maximum position that is larger than the size + // of the data vector we throw a range error. + CHECK_THROW(TraceFunctions::FindLeadingEdge( + trace, leading_edge_fraction, make_pair(trace.size() + 10, 3.)), + range_error); + + //Check that we are getting what we expect for the leading edge + ///@TODO We still need to fix this function so that it works properly + CHECK_EQUAL(leading_edge_position, + TraceFunctions::FindLeadingEdge(trace, leading_edge_fraction, + max_pair)); +} + +TEST(TestCalculatePoly3) { + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(Polynomial::CalculatePoly3(empty_vector_uint, 0), range_error); + + //A pair containing the data and the starting position of the fit + pair > result = + Polynomial::CalculatePoly3(poly3_data, 0); + + //Check that we are returning the correct coefficients for the data being + // passed. + CHECK_ARRAY_CLOSE(poly3_coeffs, result.second, poly3_coeffs.size(), 1e-6); + + //Check that the calculated maximum value is accurate + CHECK_CLOSE(extrapolated_maximum, result.first, 1e-6); +} + +//For determination of the extrapolated maximum value of the trace. This trace +// favors the left side since f(max+1) is less than f(max - 1). +TEST(TestExtrapolateMaximum) { + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(TraceFunctions::ExtrapolateMaximum(empty_vector_uint, + max_pair), range_error); + + pair > result = + TraceFunctions::ExtrapolateMaximum(trace, max_pair); + + //Check that the calculated maximum value is accurate + CHECK_CLOSE(extrapolated_maximum, result.first, 1e-6); + + //Check that we are returning the correct coefficients for the data being + // passed. + CHECK_ARRAY_CLOSE(extrapolated_max_coeffs, result.second, + extrapolated_max_coeffs.size(), 1e-3); +} + +TEST(TestCalculatePoly2) { + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(Polynomial::CalculatePoly2(empty_vector_uint, 0), range_error); + + pair > result = + Polynomial::CalculatePoly2(poly2_data, 0); + + //Check that we are returning the correct coefficients for the data being + // passed. + CHECK_ARRAY_CLOSE(poly2_coeffs, result.second, + poly2_coeffs.size(), 1e-3); + + CHECK_CLOSE(poly2_val, result.first, 1e-4); +} + +TEST(TestCalculateIntegral) { + //Check that we throw an error if the data vector is too small. + CHECK_THROW(Statistics::CalculateIntegral(empty_vector_uint), range_error); + CHECK_EQUAL(integral, Statistics::CalculateIntegral(integration_data)); +} + +TEST(TestCalculateQdc) { + //Check that we are throwing an error when the data is empty + CHECK_THROW(TraceFunctions::CalculateQdc(empty_vector_uint, make_pair(0, 4)), + range_error); + //Check that we are throwing an error when the range is too large + CHECK_THROW(TraceFunctions::CalculateQdc(trace, + make_pair(0, trace.size() + 10)), + range_error); + //Check for range error when the range is inverted + CHECK_THROW(TraceFunctions::CalculateQdc(trace, make_pair(1000, 0)), + range_error); + //Check that we get the expected result + CHECK_EQUAL(integration_qdc, + TraceFunctions::CalculateQdc(integration_data, qdc_pair)); +} + +TEST(TestCalculateTailRatio) { + //Check that we are throwing an error when the data is empty + CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_vector_uint, + make_pair(0, 4), 100.0), + range_error); + //Check that the upper bound of the range is not bigger than the data size + CHECK_THROW(TraceFunctions::CalculateTailRatio(trace, + make_pair(0, trace.size() + 10), 100.0), + range_error); + //Check that the QDC is not zero + CHECK_THROW(TraceFunctions::CalculateTailRatio(trace, make_pair(0, 4), + 0.0), range_error); + double qdc = TraceFunctions::CalculateQdc(trace, make_pair(70, 91)); + pair range(80, 91); + double result = TraceFunctions::CalculateTailRatio(trace, range, qdc); + CHECK_CLOSE(tail_ratio, result, 1e-6); +} + +TEST(TestIeeeFloatingToDecimal) { + unsigned int input = 1164725159; + double expected = 3780.7283; + CHECK_CLOSE(expected, IeeeStandards::IeeeFloatingToDecimal(input), 1e-4); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/CMakeLists.txt b/Scan/CMakeLists.txt deleted file mode 100644 index 2c4398393..000000000 --- a/Scan/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -option(USE_HRIBF "Use HRIBF library for scan base." OFF) - -#Everything below is dependent on ScanLib, so we include the headers. -include_directories(ScanLib/include) - -if(USE_HRIBF) - #Find HRIBF Libraries - find_package(HRIBF REQUIRED) - add_definitions("-D USE_HRIBF") - - #If we are using HRIBF interface we need to include the ScanorInterface header - # for the following code. - include_directories(scanor/include) - add_subdirectory(scanor) -endif(USE_HRIBF) - -#We will always build this since it includes a static lib for the rest -include_directories(ScanLib/include) -add_subdirectory(ScanLib) - -#Build utilities. -add_subdirectory(util) - -if(BUILD_UTKSCAN) - add_subdirectory(utkscan) -endif(BUILD_UTKSCAN) \ No newline at end of file diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp deleted file mode 100644 index 9158240c3..000000000 --- a/Scan/ScanLib/include/XiaData.hpp +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef XIADATA_HPP -#define XIADATA_HPP - -#include -#include -#include -#include -#include - -/*! \brief A pixie16 channel event - * - * All data is grouped together into channels. For each pixie16 channel that - * fires the energy, time (both trigger time and event time), and trace (if - * applicable) are obtained. Additional information includes the channels - * identifier, calibrated energies, trace analysis information. - * Note that this currently stores raw values internally through pixie word types - * but returns data values through native C types. This is potentially non-portable. - */ -class XiaData{ -public: - double energy; /// Raw pixie energy. - double time; /// Raw pixie event time. Measured in filter clock ticks (8E-9 Hz for RevF). - - std::vector adcTrace; /// ADC trace capture. - - static const int numQdcs = 8; /// Number of QDCs onboard. - unsigned int qdcValue[numQdcs]; /// QDCs from onboard. - - unsigned int slotNum; ///Slot number - unsigned int modNum; /// Module number. - unsigned int chanNum; /// Channel number. - unsigned int trigTime; /// The channel trigger time, trigger time and the lower 32 bits of the event time are not necessarily the same but could be separated by a constant value. - unsigned int cfdTime; /// CFD trigger time in units of 1/256 pixie clock ticks. - unsigned int eventTimeLo; /// Lower 32 bits of pixie16 event time. - unsigned int eventTimeHi; /// Upper 32 bits of pixie16 event time. - double eventTime; /// The event time recorded by Pixie. - - bool virtualChannel; /// Flagged if generated virtually in Pixie DSP. - bool pileupBit; /// Pile-up flag from Pixie. - bool saturatedBit; /// Saturation flag from Pixie. - bool cfdForceTrig; /// CFD was forced to trigger. - bool cfdTrigSource; /// The ADC that the CFD/FPGA synched with. - - /// Default constructor. - XiaData(); - - /// Constructor from a pointer to another XiaData. - XiaData(XiaData *other_); - - /// Virtual destructor. - virtual ~XiaData(); - - /// Get the event ID number (mod * chan). - unsigned int getID(){ return(modNum*16+chanNum); } - - /// Reserve specified number of bins for the channel trace. - void reserve(const size_t &size_); - - /// Fill the trace vector with a specified value. - void assign(const size_t &size_, const int &input_); - - /// Push back the trace vector with a value. - void push_back(const int &input_); - - /// Return true if the time of arrival for rhs is later than that of lhs. - static bool compareTime(XiaData *lhs, XiaData *rhs){ return (lhs->time < rhs->time); } - - /// Return true if lhs has a lower event id (mod * chan) than rhs. - static bool compareChannel(XiaData *lhs, XiaData *rhs){ return ((lhs->modNum*lhs->chanNum) < (rhs->modNum*rhs->chanNum)); } - - /// Return one of the onboard qdc values. - unsigned int getQdcValue(int id){ return (id < 0 || id >= numQdcs ? -1 : qdcValue[id]); } - - /// Clear all variables. - void clear(); -}; - -class ChannelEvent{ -public: - bool valid_chan; /// True if the high resolution energy and time are valid. - - double hires_energy; /// High resolution energy from the integration of pulse fits. - double hires_time; /// High resolution time taken from pulse fits (in ns). - - float *xvals; /// x values used for fitting. - float *yvals; /// y values used for fitting (baseline corrected trace). - float *cfdvals; /// y values for the cfd analyzed waveform. - size_t size; /// Size of xvals and yvals arrays and of trace vector. - - float phase; /// Phase (leading edge) of trace (in ADC clock ticks (4E-9 Hz for 250 MHz digitizer)). - float baseline; /// The baseline of the trace. - float stddev; /// Standard deviation of the baseline. - float maximum; /// The baseline corrected maximum value of the trace. - float qdc; /// The calculated (baseline corrected) qdc. - float cfdCrossing; /// The zero-crossing point of the cfd waveform. - size_t max_index; /// The index of the maximum trace bin (in ADC clock ticks). - - bool baseline_corrected; /// True if the trace has been baseline corrected. - bool ignore; /// Ignore this event. - - XiaData *event; /// The low level pixie event. - - /// Default constructor. - ChannelEvent(); - - /// Constructor from a XiaData. ChannelEvent will take ownership of the XiaData. - ChannelEvent(XiaData *event_); - - /// Destructor. - ~ChannelEvent(); - - /// Correct the trace baseline, baseline standard deviation, and find the pulse maximum. - float CorrectBaseline(); - - /// Find the leading edge of the pulse at a given percentage of pulse maximum. - float FindLeadingEdge(const float &thresh_=0.05); - - /// Integrate the baseline corrected trace in the range [start_, stop_] and return the result. - float IntegratePulse(const size_t &start_=0, const size_t &stop_=0); - - /// Integrate the baseline corrected trace in the range [start_, stop_] and return the result. - float FindQDC(const size_t &start_=0, const size_t &stop_=0); - - /// Perform CFD analysis on the waveform. - float AnalyzeCFD(const float &F_=0.5, const size_t &D_=1, const size_t &L_=1); - - /// Clear all variables and clear the trace vector and arrays. - void Clear(); -}; - -#endif diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt deleted file mode 100644 index 7b75349b2..000000000 --- a/Scan/ScanLib/source/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -#Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp) - -#Add the sources to the library -add_library(ScanObjects OBJECT ${ScanSources}) - -if(BUILD_SHARED_LIBS) - message(STATUS "Building Scan Shared Objects") - add_library(Scan SHARED $) - target_link_libraries(Scan PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) - if (${CURSES_FOUND}) - target_link_libraries(Scan ${CURSES_LIBRARIES}) - endif() - install(TARGETS Scan DESTINATION lib) -endif(BUILD_SHARED_LIBS) - -#Create PixieScan static library and add ncurses if we have it -add_library(ScanStatic STATIC $) -target_link_libraries(ScanStatic PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) -if (${CURSES_FOUND}) - target_link_libraries(ScanStatic ${CURSES_LIBRARIES}) -endif() diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp deleted file mode 100644 index c3f79323f..000000000 --- a/Scan/ScanLib/source/XiaData.cpp +++ /dev/null @@ -1,260 +0,0 @@ -#include - -#include "XiaData.hpp" - -///////////////////////////////////////////////////////////////////// -// XiaData -///////////////////////////////////////////////////////////////////// - -/// Default constructor. -XiaData::XiaData(){ - clear(); -} - -/// Constructor from a pointer to another XiaData. -XiaData::XiaData(XiaData *other_){ - adcTrace = other_->adcTrace; - - energy = other_->energy; - time = other_->time; - - for(int i = 0; i < numQdcs; i++){ - qdcValue[i] = other_->qdcValue[i]; - } - - modNum = other_->modNum; - chanNum = other_->chanNum; - trigTime = other_->trigTime; - cfdTime = other_->cfdTime; - eventTimeLo = other_->eventTimeLo; - eventTimeHi = other_->eventTimeHi; - eventTime = other_->eventTime; - - virtualChannel = other_->virtualChannel; - pileupBit = other_->pileupBit; - saturatedBit = other_->saturatedBit; - cfdForceTrig = other_->cfdForceTrig; - cfdTrigSource = other_->cfdTrigSource; -} - -XiaData::~XiaData(){ -} - -void XiaData::reserve(const size_t &size_){ - if(size_ == 0){ return; } - adcTrace.reserve(size_); -} - -void XiaData::assign(const size_t &size_, const int &input_){ - adcTrace.assign(size_, input_); -} - -void XiaData::push_back(const int &input_){ - adcTrace.push_back(input_); -} - -void XiaData::clear(){ - adcTrace.clear(); - - energy = 0.0; - time = 0.0; - - for(int i = 0; i < numQdcs; i++){ - qdcValue[i] = 0; - } - - modNum = 0; - chanNum = 0; - trigTime = 0; - cfdTime = 0; - eventTimeLo = 0; - eventTimeHi = 0; - eventTime = 0.0; - - virtualChannel = false; - pileupBit = false; - saturatedBit = false; - cfdForceTrig = false; - cfdTrigSource = false; -} - -///////////////////////////////////////////////////////////////////// -// ChannelEvent -///////////////////////////////////////////////////////////////////// - -/// Default constructor. -ChannelEvent::ChannelEvent(){ - event = NULL; - xvals = NULL; - yvals = NULL; - cfdvals = NULL; - Clear(); -} - -/// Constructor from a XiaData. ChannelEvent will take ownership of the XiaData. -ChannelEvent::ChannelEvent(XiaData *event_){ - event = NULL; - xvals = NULL; - yvals = NULL; - cfdvals = NULL; - Clear(); - event = event_; - size = event->adcTrace.size(); - if(size != 0){ - xvals = new float[size]; - yvals = new float[size]; - } -} - -ChannelEvent::~ChannelEvent(){ - if(event){ delete event; } - if(xvals){ delete[] xvals; } - if(yvals){ delete[] yvals; } -} - -float ChannelEvent::CorrectBaseline(){ - if(!event || size == 0){ return -9999; } - else if(baseline_corrected){ return maximum; } - - // Find the baseline - baseline = 0.0; - size_t sample_size = (10 <= size ? 10:size); - for(size_t i = 0; i < sample_size; i++){ - baseline += (float)event->adcTrace[i]; - } - baseline = baseline/sample_size; - - // Calculate the standard deviation - stddev = 0.0; - for(size_t i = 0; i < sample_size; i++){ - stddev += ((float)event->adcTrace[i] - baseline)*((float)event->adcTrace[i] - baseline); - } - stddev = std::sqrt((1.0/sample_size) * stddev); - - // Find the maximum value, the maximum bin, and correct the baseline - maximum = -9999.0; - for(size_t i = 0; i < event->adcTrace.size(); i++){ - xvals[i] = i; - yvals[i] = event->adcTrace[i]-baseline; - if(yvals[i] > maximum){ - maximum = yvals[i]; - max_index = i; - } - } - - baseline_corrected = true; - - return maximum; -} - -float ChannelEvent::FindLeadingEdge(const float &thresh_/*=0.05*/){ - if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } - else if(phase >= 0.0){ return phase; } - - // Check if this is a valid pulse - if(maximum <= 0 || max_index == 0){ return -9999; } - - for(size_t index = max_index; index > 0; index--){ - if(yvals[index] <= thresh_ * maximum){ - // Interpolate and return the value - // y = thresh_ * maximum - // x = (x1 + (y-y1)/(y2-y1)) - // x1 = index, x2 = index+1 - // y1 = yvals[index], y2 = yvals[index+1] - if(yvals[index+1] == yvals[index]){ return index+1; } - else{ return (phase = (index + (thresh_ * maximum - yvals[index])/(yvals[index+1] - yvals[index]))); } - } - } - - return -9999; -} - -float ChannelEvent::IntegratePulse(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ - if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } - - size_t stop = (stop_ == 0?size:stop_); - - qdc = 0.0; - for(size_t i = start_+1; i < stop; i++){ // Integrate using trapezoidal rule. - qdc += 0.5*(yvals[i-1] + yvals[i]); - } - - return qdc; -} - -float ChannelEvent::FindQDC(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ - if(qdc >= 0.0){ return qdc; } - - qdc = IntegratePulse(start_, stop_); - - return qdc; -} - -/// Perform CFD analysis on the waveform. -float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/, const size_t &D_/*=1*/, const size_t &L_/*=1*/){ - if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } - if(!cfdvals){ - if(size == 0) - return -9999; - cfdvals = new float[size]; - } - - float cfdMinimum = 9999; - size_t cfdMinIndex = 0; - - cfdCrossing = -9999; - - // Compute the cfd waveform. - for(size_t cfdIndex = 0; cfdIndex < size; ++cfdIndex){ - cfdvals[cfdIndex] = 0.0; - if(cfdIndex >= L_ + D_ - 1){ - for(size_t i = 0; i < L_; i++) - cfdvals[cfdIndex] += F_ * yvals[cfdIndex - i] - yvals[cfdIndex - i - D_]; - } - if(cfdvals[cfdIndex] < cfdMinimum){ - cfdMinimum = cfdvals[cfdIndex]; - cfdMinIndex = cfdIndex; - } - } - - // Find the zero-crossing. - if(cfdMinIndex > 0){ - // Find the zero-crossing. - for(size_t cfdIndex = cfdMinIndex-1; cfdIndex >= 0; cfdIndex--){ - if(cfdvals[cfdIndex] >= 0.0 && cfdvals[cfdIndex+1] < 0.0){ - cfdCrossing = xvals[cfdIndex] - cfdvals[cfdIndex]*(xvals[cfdIndex+1]-xvals[cfdIndex])/(cfdvals[cfdIndex+1]-cfdvals[cfdIndex]); - break; - } - } - } - - return cfdCrossing; -} - -void ChannelEvent::Clear(){ - phase = -9999; - maximum = -9999; - baseline = -9999; - stddev = -9999; - qdc = -9999; - cfdCrossing = -9999; - max_index = 0; - - hires_energy = -9999; - hires_time = -9999; - - valid_chan = false; - baseline_corrected = false; - ignore = false; - - size = 0; - if(xvals){ delete[] xvals; } - if(yvals){ delete[] yvals; } - if(cfdvals){ delete[] cfdvals; } - if(event){ event->clear(); } - - event = NULL; - xvals = NULL; - yvals = NULL; - cfdvals = NULL; -} diff --git a/Scan/utkscan/analyzers/CMakeLists.txt b/Scan/utkscan/analyzers/CMakeLists.txt deleted file mode 100644 index 26e716984..000000000 --- a/Scan/utkscan/analyzers/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_subdirectory(source) - -if(BUILD_UTKSCAN_TESTS) - add_subdirectory(tests) -endif(BUILD_UTKSCAN_TESTS) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/include/FitDriver.hpp b/Scan/utkscan/analyzers/include/FitDriver.hpp deleted file mode 100644 index 229193bc6..000000000 --- a/Scan/utkscan/analyzers/include/FitDriver.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/// \file FitDriver.hpp -/// \brief An abstract class that will provide the base for fitting -/// \author S. V. Paulauskas -/// \date August 8, 2016 - -#ifndef PIXIESUITE_FITDRIVER_HPP -#define PIXIESUITE_FITDRIVER_HPP -#include -#include - -/// A base class that will be used to handle fitting. We currently only support -/// the VANDLE fitting function in this version, which has only two free -/// parameters. -class FitDriver { -public: - ///Default Constructor - FitDriver() {}; - ///Default destructor - virtual ~FitDriver(){}; - - /// Gets the amplitude found by the fit. Does nothing by default. We assume - /// that the children will overload this with their specific implementation. - ///\return The Amplitude found by the fit - virtual double GetAmplitude(void) {return 0.;} - /// Gets the Chi^2 of the fit. Does nothing by default. We assume - /// that the children will overload this with their specific implementation. - ///\return The Chi^2 from the fit - virtual double GetChiSq(void){return 0.;} - /// Gets the Chi^2/dof of the fit. Does nothing by default. We assume - /// that the children will overload this with their specific implementation. - ///\return The Chi^2/dof from the fit - virtual double GetChiSqPerDof(void){return 0.;} - /// Gets the phase found by the fit. Does nothing by default. We assume - /// that the children will overload this with their specific implementation. - ///\return The phase found by the fit - virtual double GetPhase(void) {return 0.;} - ///The main driver of the fitting program. Does nothing by default. We assume - /// that the children will overload this with their specific implementation. - /// \param[in] data The data that we would like to try and fit - /// \param[in] pars The parameters for the fit - /// \param[in] weight The weight for the fit - virtual void PerformFit(const std::vector &data, - const std::pair &pars, - const double &weight = 1., - const double &area = 1.) {}; - /// Sets the data that we are going to fit - /// \param[in] a Vector containing data to fit - void SetData(const std::vector &a) {data_ = a;} - /// Sets the parameters for the fitting functions - /// \param[in] a pair containing the constants for the fit - void SetParameters(const std::pair &a) {pars_ = a;} - /// Sets the QDC that's used in the fit - /// \param[in] a the qdc of the waveform for the fit - void SetQdc(const double &a) {qdc_ = a;} - /// Sets the weight for the fit. We will assume for now that the - /// weight is identical for all points in the fit - /// \param[in] a weight of the points for the fit - void SetWeight(const double &a) {weight_ = a;} - - //! Structure necessary for the GSL fitting routines - struct FitData { - size_t n;//!< size of the fitting parameters - double *y;//!< ydata to fit - double *sigma;//!< weights used for the fit - double beta; //!< the beta parameter for the fit - double gamma; //!< the gamma parameter for the fit - double qdc;//!< the QDC for the fit - }; - - /// An enum listing the known Fitter types for use with the FittingAnalyzer - enum FITTER_TYPE{GSL, UNKNOWN}; -protected: - std::vector data_;//!< Vector of data to fit - std::pair pars_;//!< parameters for the fit function - double weight_;//!< weight for the fit, assumed constant for all pts - double qdc_;//!< qdc of the waveform being fitted -}; -#endif //PIXIESUITE_FITDRIVER_HPP diff --git a/Scan/utkscan/analyzers/include/GslFitter.hpp b/Scan/utkscan/analyzers/include/GslFitter.hpp deleted file mode 100644 index d9d38b4b2..000000000 --- a/Scan/utkscan/analyzers/include/GslFitter.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/// \file GslFitter.hpp -/// \brief Implementation of the GSL fitting routine for GSL v2+ -/// \author S. V. Paulauskas -/// \date August 8, 2016 - -#ifndef PIXIESUITE_GSLFITTER_HPP -#define PIXIESUITE_GSLFITTER_HPP - -#include "FitDriver.hpp" - -class GslFitter : public FitDriver{ -public: - ///Default Constructor - GslFitter(const bool &isFastSipm) : FitDriver() {isFastSipm_ = isFastSipm;} - ///Default Destructor - virtual ~GslFitter(){}; - - ///\return the phase from the GSL fit - virtual double GetPhase(void){return phase_;} - ///\return the amplitude from the GSL fit - virtual double GetAmplitude(void) {return amp_;} - ///\return the chi^2 from the GSL fit - virtual double GetChiSq(void) {return chi_*chi_;} - ///\return the chi^2dof from the GSL fit - virtual double GetChiSqPerDof(void) {return GetChiSq()/dof_;} - ///The main driver for the fitting - /// \param[in] data The data that we would like to try and fit - /// \param[in] pars The parameters for the fit - /// \param[in] weight The weight for the fit - virtual void PerformFit(const std::vector &data, - const std::pair &pars, - const double &weight = 1., - const double &area = 1.); -private: - bool isFastSipm_; - - double amp_; - double chi_; - double dof_; - double phase_; -}; - - -#endif //PIXIESUITE_GSLFITTER_HPP diff --git a/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp b/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp deleted file mode 100644 index 60061b16d..000000000 --- a/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/** \file WaveformAnalyzer.hpp - * \brief Class to analyze traces. - * \author S. V. Paulauskas - */ -#ifndef __WAVEFORMANALYZER_HPP_ -#define __WAVEFORMANALYZER_HPP_ - -#include "Globals.hpp" -#include "Messenger.hpp" -#include "Trace.hpp" -#include "TraceAnalyzer.hpp" - -//! Class to waveform analysis -class WaveformAnalyzer : public TraceAnalyzer { -public: - /** Default Constructor */ - WaveformAnalyzer(); - - /** Default destructor */ - ~WaveformAnalyzer() {} - - /** Declare the plots */ - virtual void DeclarePlots(void) const {} - - /** Do the analysis on traces - * \param [in] trace : the trace to analyze - * \param [in] type : the detector type - * \param [in] subtype : detector subtype - * \param [in] tags : the map of the tags for the channel */ - virtual void Analyze(Trace &trace, const std::string &type, - const std::string &subtype, - const std::map &tags); - -private: - - double mean_; //!< The mean of the baseline - unsigned int mval_; //!< the maximum value in the trace - Messenger *messenger_;//!< A pointer for the messenger class - Globals *g_; //!< A pointer to the globals class for the class - std::pair waverng_; //!< the waveform -//!< range - Trace::iterator bhi_; //!< high value for baseline calculation - Trace *trc_; //!< A pointer to the trace for the class - - - /** Performs the baseline calculation - * \param [in] lo : the low range for the baseline calculation - * \param [in] numBins : The number of bins for the baseline calculation - * \return The average value of the baseline in the region */ - void CalculateSums(); - - /** Performs the neutron-gamma discrimination on the traces - * \param [in] lo : The low range for the discrimination (referenced from max) - * \param [in] numBins : the number of bins to calculate the baseline over - * \return The discrimination value */ - void CalculateDiscrimination(const unsigned int &lo); - - /** Calculate information for the maximum value of the trace - * \param [in] lo : the low side of the waveform - * \param [in] hi : the high side of the waveform - * \param [in] numBins : the number of bins to look for the max in - * \return The position of the maximum value in the trace */ - bool FindWaveform(const unsigned int &lo, const unsigned int &hi); -}; - -#endif // __WAVEFORMANALYZER_HPP_ diff --git a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp deleted file mode 100644 index 0f928bb32..000000000 --- a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** \file CfdAnalyzer.cpp - * \brief Uses a Digital CFD to obtain waveform phases - * - * This code will obtain the phase of a waveform using a digital CFD. - * Currently the only method is a polynomial fit to the crossing point. - * For 100-250 MHz systems, this is not going to produce good timing. - * This code was originally written by S. Padgett. - * - * \author S. V. Paulauskas - * \date 22 July 2011 - */ -#include -#include -#include -#include -#include - -#include "CfdAnalyzer.hpp" - -using namespace std; - -CfdAnalyzer::CfdAnalyzer() : TraceAnalyzer() { - name = "CfdAnalyzer"; -} - -void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, - const std::string &detSubtype, - const std::map & tagMap) { - TraceAnalyzer::Analyze(trace, detType, detSubtype, tagMap); - Globals *globals = Globals::get(); - unsigned int saturation = (unsigned int)trace.GetValue("saturation"); - if(saturation > 0) { - EndAnalyze(); - return; - } - double aveBaseline = trace.GetValue("baseline"); - unsigned int maxPos = (unsigned int)trace.GetValue("maxpos"); - pair range = globals->waveformRange("default"); - unsigned int waveformLow = range.first; - unsigned int waveformHigh = range.second; - unsigned int delay = 2; - double fraction = 0.25; - vector cfd; - Trace::iterator cfdStart = trace.begin(); - advance(cfdStart, (int)(maxPos - waveformLow - 2)); - Trace::iterator cfdStop = trace.begin(); - advance(cfdStop, (int)(maxPos + waveformHigh)); - for(Trace::iterator it = cfdStart; it != cfdStop; it++) { - Trace::iterator it0 = it; - advance(it0, delay); - double origVal = *it; - double transVal = *it0; - cfd.insert(cfd.end(), fraction * - (origVal - transVal - aveBaseline)); - } - vector::iterator cfdMax = - max_element(cfd.begin(), cfd.end()); - vector fitY; - fitY.insert(fitY.end(), cfd.begin(), cfdMax); - fitY.insert(fitY.end(), *cfdMax); - vectorfitX; - for(unsigned int i = 0; i < fitY.size(); i++) - fitX.insert(fitX.end(), i); - double num = fitY.size(); - double sumXSq = 0, sumX = 0, sumXY = 0, sumY = 0; - for(unsigned int i = 0; i < num; i++) { - sumXSq += fitX.at(i)*fitX.at(i); - sumX += fitX.at(i); - sumY += fitY.at(i); - sumXY += fitX.at(i)*fitY.at(i); - } - double deltaPrime = num*sumXSq - sumX*sumX; - double intercept = - (1/deltaPrime)*(sumXSq*sumY - sumX*sumXY); - double slope = - (1/deltaPrime)*(num*sumXY - sumX*sumY); - trace.InsertValue("phase", (-intercept/slope)+maxPos); - EndAnalyze(); -} diff --git a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp deleted file mode 100644 index e0a5857d1..000000000 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** \file FittingAnalyzer.cpp - * \brief Uses a chi^2 minimization to fit waveforms - * - * Obtains the phase of a waveform using a Chi^2 fitting algorithm - * implemented through the GSL libraries. We have now set up two different - * functions for this processor. One of them handles the fast SiPMT signals, - * which tend to be more Gaussian in shape than the standard PMT signals. - * - * \author S. V. Paulauskas - * \date 22 July 2011 - */ -#include -#include -#include - -#include - -#include "Globals.hpp" -#include "DammPlotIds.hpp" -#include "FitDriver.hpp" -#include "FittingAnalyzer.hpp" -#include "GslFitter.hpp" - -using namespace std; -using namespace dammIds::trace::waveformanalyzer; - -void FittingAnalyzer::DeclarePlots(void) { - Trace sample_trace = Trace(); - sample_trace.DeclareHistogram2D(DD_TRACES, S7, S5, "traces data FitAnalyzer"); - sample_trace.DeclareHistogram2D(DD_AMP, SE, SC, "Fit Amplitude"); - sample_trace.DeclareHistogram1D(D_PHASE, SE, "Fit X0"); - sample_trace.DeclareHistogram1D(D_CHISQPERDOF, SE, "Chi^2/dof"); - sample_trace.DeclareHistogram1D(D_SIGMA, SE, "Std Dev Baseline"); -} - -FittingAnalyzer::FittingAnalyzer(const std::string &s) { - name = "FittingAnalyzer"; - if(s == "GSL" || s == "gsl") { - fitterType_ = FitDriver::GSL; - } else { - fitterType_ = FitDriver::UNKNOWN; - } -} - -void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, - const std::string &detSubtype, - const std::map & tagMap) { - TraceAnalyzer::Analyze(trace, detType, detSubtype, tagMap); - - if(trace.HasValue("saturation") || trace.empty() || - trace.GetWaveform().size() == 0) { - EndAnalyze(); - return; - } - - Globals *globals = Globals::get(); - - const double sigmaBaseline = trace.GetValue("sigmaBaseline"); - const double maxVal = trace.GetValue("maxval"); - const double qdc = trace.GetValue("qdc"); - const double maxPos = trace.GetValue("maxpos"); - const vector waveform = trace.GetWaveform(); - bool isDblBeta = detType == "beta" && detSubtype == "double"; - bool isDblBetaT = isDblBeta && tagMap.find("timing") != tagMap.end(); - - trace.plot(D_SIGMA, sigmaBaseline*100); - - if(!isDblBetaT) { - if(sigmaBaseline > globals->sigmaBaselineThresh()) { - EndAnalyze(); - return; - } - } else { - if(sigmaBaseline > globals->siPmtSigmaBaselineThresh()) { - EndAnalyze(); - return; - } - } - - pair pars = globals->fitPars(detType+":"+detSubtype); - if(isDblBetaT) - pars = globals->fitPars(detType+":"+detSubtype+":timing"); - - FitDriver *driver; - switch(fitterType_) { - case FitDriver::GSL: - driver = new GslFitter(isDblBetaT); - break; - case FitDriver::UNKNOWN: - default: - EndAnalyze(); - return; - } - - driver->PerformFit(waveform, pars, sigmaBaseline, qdc); - trace.InsertValue("phase", driver->GetPhase()+maxPos); - - trace.plot(DD_AMP, driver->GetAmplitude(), maxVal); - trace.plot(D_PHASE, driver->GetPhase()*1000+100); - trace.plot(D_CHISQPERDOF, driver->GetChiSqPerDof()); - - delete(driver); - EndAnalyze(); -} \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp b/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp deleted file mode 100644 index 5923743e7..000000000 --- a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/// \file Gsl2Fitter.cpp -/// \brief Implementation of the GSL fitting routine for GSL v2+ -/// \author S. V. Paulauskas -/// \date August 8, 2016 -#include -#include - -#include -#include -#include - -#include "GslFitter.hpp" - -/** Defines the GSL fitting function for standard PMTs - * \param [in] x : the vector of gsl starting parameters - * \param [in] FitData : The data to use for the fit - * \param [in] f : pointer to the function - * \return an integer that GSL does something magical with */ -int PmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f); -/** Defines the GSL fitting function for standard PMTs - * \param [in] x : the vector of gsl starting parameters - * \param [in] FitData : The data to use for the fit - * \param [in] J : pointer to the Jacobian of the function - * \return an integer that GSL does something magical with */ -int CalcPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J); -/** Defines the GSL fitting function for the fast output of SiPMTs - * \param [in] x : the vector of gsl starting parameters - * \param [in] FitData : The data to use for the fit - * \param [in] f : pointer to the function - * \return an integer that GSL does something magical with */ -int SiPmtFunction(const gsl_vector *x, void *FitData, gsl_vector *f); -/** Defines the GSL fitting function for the fast output SiPMTs - * \param [in] x : the vector of gsl starting parameters - * \param [in] FitData : The data to use for the fit - * \param [in] J : pointer to the Jacobian of the function - * \return an integer that GSL does something magical with */ -int CalcSiPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J); - -using namespace std; - -void GslFitter::PerformFit(const std::vector &data, - const std::pair &pars, - const double &weight/* = 1.*/, - const double &area/* = 1.*/) { - gsl_multifit_function_fdf f; - int info; - const size_t n = data.size(); - size_t p; - double xInit[3]; - - if(!isFastSipm_) { - p = 2; - xInit[0] = 0.0; - xInit[1] = 2.5; - - f.f = &PmtFunction; - f.df = &CalcPmtJacobian; - } else { - p = 1; - xInit[0] = (double)data.size()*0.5; - - f.f = &SiPmtFunction; - f.df = &CalcSiPmtJacobian; - } - - dof_ = n - p; - - const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; - gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, p); - gsl_matrix *jac=gsl_matrix_alloc(n,p); - gsl_matrix *covar = gsl_matrix_alloc (p,p); - double y[n], weights[n]; - struct FitDriver::FitData fitData = {n, y, weights, pars.first, - pars.second, area}; - gsl_vector_view x = gsl_vector_view_array (xInit,p); - gsl_vector_view w = gsl_vector_view_array (weights,n); - - double xtol = 1e-10; - double gtol = 1e-10; - double ftol = 0.0; - - f.n = n; - f.p = p; - f.params = &fitData; - - for(unsigned int i = 0; i < n; i++) { - weights[i] = weight; - y[i] = data[i]; - } - - gsl_multifit_fdfsolver_wset (s, &f, &x.vector, &w.vector); - gsl_multifit_fdfsolver_driver(s, 1000, xtol, gtol, ftol, &info); - gsl_multifit_fdfsolver_jac(s,jac); - gsl_multifit_covar (jac, 0.0, covar); - - gsl_vector *res_f = gsl_multifit_fdfsolver_residual(s); - chi_ = gsl_blas_dnrm2(res_f); - - if(!isFastSipm_) { - phase_ = gsl_vector_get(s->x,0); - amp_ = gsl_vector_get(s->x,1); - } else { - phase_ = gsl_vector_get(s->x,0); - amp_ = 0.0; - } - - gsl_multifit_fdfsolver_free (s); - gsl_matrix_free (covar); - gsl_matrix_free(jac); -} - -int PmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *y = ((struct FitDriver::FitData *)FitData)->y; - double beta = ((struct FitDriver::FitData *)FitData)->beta; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; - - double phi = gsl_vector_get (x, 0); - double alpha = gsl_vector_get (x, 1); - - for(size_t i = 0; i < n; i++) { - double t = i; - double diff = t-phi; - double Yi = 0; - - if(t < phi) - Yi = 0; - else - Yi = qdc * alpha * exp(-beta*diff) * (1-exp(-pow(gamma*diff,4.))); - - gsl_vector_set (f, i, Yi - y[i]); - } - return(GSL_SUCCESS); -} - -int CalcPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double beta = ((struct FitDriver::FitData *)FitData)->beta; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; - - double phi = gsl_vector_get (x, 0); - double alpha = gsl_vector_get (x, 1); - - double dphi, dalpha; - - for(size_t i = 0; i < n; i++) { - double t = i; - double diff = t-phi; - double gaussSq = exp(-pow(gamma*diff,4.)); - if(t < phi) { - dphi = 0; - dalpha = 0; - } else { - dphi = alpha*beta*qdc*exp(-beta*diff)*(1-gaussSq) - - 4*alpha*qdc*pow(diff,3.)*exp(-beta*diff)*pow(gamma,4.)*gaussSq; - dalpha = qdc * exp(-beta*diff) * (1-gaussSq); - } - gsl_matrix_set(J,i,0, dphi); - gsl_matrix_set(J,i,1, dalpha); - } - return(GSL_SUCCESS); -} - -int SiPmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double *y = ((struct FitDriver::FitData *)FitData)->y; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; - - double phi = gsl_vector_get (x, 0); - - for(size_t i = 0; i < n; i++) { - double t = i; - double diff = t-phi; - double Yi = (qdc/(gamma*sqrt(2*M_PI)))*exp(-diff*diff/(2*gamma*gamma)); - gsl_vector_set (f, i, Yi - y[i]); - } - return(GSL_SUCCESS); -} - -int CalcSiPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct FitDriver::FitData *)FitData)->n; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; - - double phi = gsl_vector_get (x, 0); - double dphi; - - for (size_t i = 0; i < n; i++) { - double t = i; - double diff = t-phi; - - dphi = (qdc*diff/(pow(gamma,3)*sqrt(2*M_PI))) * - exp(-diff*diff/(2*gamma*gamma)); - - gsl_matrix_set (J,i,0, dphi); - } - return(GSL_SUCCESS); -} - diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp deleted file mode 100644 index 0f0f584b1..000000000 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/** \file WaveformAnalyzer.cpp - *\brief Preliminary waveform analysis - * - *Does preliminary waveform analysis on traces. The parameters set here - *will be used for the high resolution timing algorithms to do their thing. - * - *\author S. V. Paulauskas - *\date July 16, 2009 -*/ -#include -#include - -#include - -#include "WaveformAnalyzer.hpp" - -using namespace std; - -enum WAVEFORMANALYZER_ERROR_CODES{ - TOO_LOW, - MAX_END, - LOW_GREATER_HIGH -}; - -WaveformAnalyzer::WaveformAnalyzer() : TraceAnalyzer() { - name = "WaveformAnalyzer"; - messenger_ = new Messenger(); -} - -void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, - const std::string &subtype, - const std::map &tags) { - TraceAnalyzer::Analyze(trace, type, subtype, tags); - trc_ = &trace; - - if (trace.HasValue("saturation") || trace.size() == 0) { - EndAnalyze(); - return; - } - - mean_ = mval_ = 0; - - g_ = Globals::get(); - - pair range = - g_->waveformRange(type + ":" + subtype); - - if (type == "beta" && subtype == "double" && - tags.find("timing") != tags.end()) - range = g_->waveformRange(type + ":" + subtype + ":timing"); - - try { - //First we find the waveform in the trace - FindWaveform(range.first, range.second); - //Calculate the baseline, need to know where waveform is before this point - CalculateSums(); - //If we had something tagged for additional trace analysis. - if (tags.find("psd") != tags.end()) - CalculateDiscrimination(g_->discriminationStart()); - } catch(WAVEFORMANALYZER_ERROR_CODES errorCode) { - switch(errorCode) { - case TOO_LOW: - messenger_->warning("The low bound for the search was before " - "the beginning of the trace. This" - " is a bad thing, no trace " - "analysis possible.", 0); - break; - case MAX_END: - messenger_->warning("The maximum value of the trace was found" - " at a point where your current " - "waveform range will be outside " - "of the trace. you should " - "reevaluate the waveform range to" - " make sure that you have set " - "something reasonable. I suggest " - "taking a look at the scope " - "program to view the traces. ", 0); - break; - case LOW_GREATER_HIGH: - messenger_->warning("The high bound for the waveform search " - "was lower than the low bound. " - "This should never have happened " - "and I have no idea why it did.", - 0); - break; - default: - stringstream ss; - ss << "There was an unidentified error with an error code of " - << errorCode << ". Please review your settings for the " - "trace analysis."; - messenger_->warning(ss.str(),0); - break; - } - EndAnalyze(); - } - EndAnalyze(); -} - -void WaveformAnalyzer::CalculateSums() { - if (trc_->HasValue("baseline")) - return; - - double sum = 0, qdc = 0; - vector w; - double numBins = (double) (bhi_ - trc_->begin()); - mean_ = 0; - for (Trace::iterator it = trc_->begin(); it != trc_->end(); it++) { - sum += (*it); - if (it < bhi_) - mean_ += (*it) / numBins; - - if (it > waverng_.first && it < waverng_.second) { - qdc += (*it) - mean_; - w.push_back((*it) - mean_); - } - } - - //We need to perform one separate loop in order to calculate the standard - // deviation of the baseline - double accum = 0.0; - for (Trace::iterator it = trc_->begin(); it != bhi_; it++) - accum += (*it - mean_) * (*it - mean_); - double stdev = sqrt(accum / (numBins)); - - //Subtract the baseline from the full trace qdc - sum -= mean_ * trc_->size(); - - trc_->SetWaveform(w); - trc_->InsertValue("tqdc", sum); - trc_->InsertValue("qdc", qdc); - trc_->SetValue("baseline", mean_); - trc_->SetValue("sigmaBaseline", stdev); - trc_->SetValue("maxval", mval_ - mean_); -} - -void WaveformAnalyzer::CalculateDiscrimination(const unsigned int &lo) { - int discrim = 0; - for (Trace::iterator i = waverng_.first + lo; i <= waverng_.second; i++) - discrim += (*i) - mean_; - trc_->InsertValue("discrim", discrim); -} - -bool WaveformAnalyzer::FindWaveform(const unsigned int &lo, - const unsigned int &hi) { - //high bound will be the trace delay - Trace::iterator high = trc_->begin() + g_->traceDelay() / - (g_->adcClockInSeconds() * 1e9); - - //if high bound is outside the trace then stop at the end of the trace - if (trc_->end() < high) - high = trc_->end(); - - //low bound will be 15 + lo, we need at least 15 bins to calculate the - //baseline, plus the requested risetime of the signal. - Trace::iterator low = trc_->begin() + 15 + lo; - - //If low is less than 0 then we have some serious issues - if (low < trc_->begin()) - throw(TOO_LOW); - - //Check that the low bound is less than the high bound. Not sure how this - // could happen but it has in the past. - if(high < low) - throw(LOW_GREATER_HIGH); - - //Find the maximum value of the waveform in the range of low to high - Trace::iterator tmp = max_element(low, high); - - //Calculate the position of the maximum of the waveform in trace - int mpos = (int) (tmp - trc_->begin()); - - //Set the value of the maximum of the waveform and insert the value into - // the trace. - mval_ = *tmp; - trc_->InsertValue("maxpos", mpos); - - //Comparisons will be < to handle .end(), +1 here makes comparison <= - //when we do not have the end(). - waverng_ = make_pair(tmp - lo, tmp + hi + 1); - - //Set the high range for the baseline calculation here. - bhi_ = tmp - lo; - - //Tell the user that the requested waveform size was actually too long. - // Set the end of the waveform to be the end of the trace. - if (mpos + hi > trc_->size()) - throw(MAX_END); - - //If the maximum value was greater than the bit resolution of the ADC then - // we had a saturation and we need to set the saturation flag. - if (mval_ >= g_->bitResolution()) - trc_->InsertValue("saturation", 1); - - return (true); -} diff --git a/Scan/utkscan/analyzers/tests/CMakeLists.txt b/Scan/utkscan/analyzers/tests/CMakeLists.txt deleted file mode 100644 index 9568d1ef8..000000000 --- a/Scan/utkscan/analyzers/tests/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -if(USE_GSL) - if(${GSL_VERSION} GREATER 1.9) - set(GSL_FITTER_SOURCES ../source/Gsl2Fitter.cpp) - else(${GSL_VERSION} LESS 2.0) - set(GSL_FITTER_SOURCES ../source/Gsl1Fitter.cpp) - endif(${GSL_VERSION} GREATER 1.9) - - #Build the test to see if the GSL fitting algorithm is behaving. - set(GSL_FITTER_SOURCES ${GSL_FITTER_SOURCES} test_gslfitter.cpp) - add_executable(test_gslfitter ${GSL_FITTER_SOURCES}) - target_link_libraries(test_gslfitter ${GSL_LIBRARIES}) -endif(USE_GSL) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp b/Scan/utkscan/analyzers/tests/test_gslfitter.cpp deleted file mode 100644 index 1c3767cde..000000000 --- a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp +++ /dev/null @@ -1,55 +0,0 @@ -///\file test_gslfitter.cpp -///\brief A small code to test the functionality of the FitDriver -///\author S. V. Paulauskas -///\date August 8, 2016 -#include - -#include "GslFitter.hpp" - -using namespace std; - -int main(int argc, char* argv[]){ - cout << "Testing functionality of FitDriver and GslFitter" << endl; - - //Baseline for the trace we're going to fit - double baseline = 436.742857142857; - - //Raw data that we want to fit - This is a VANDLE trace - vector data { - 437, 501, 1122, 2358, 3509, 3816, 3467, 2921, 2376, - 1914, 1538, 1252, 1043, 877, 750, 667 - }; - - //Subtract the baseline from the data - for(vector::iterator it = data.begin(); it != data.end(); it++ ) - (*it) -= baseline; - - //Set the for the fitting - pair pars = make_pair(0.2659404170, 0.208054799179688); - - //Standard deviation of the baseline provides weight - double weight = 1.9761847389475; - - //Qdc of the trace is necessary to initialization of the fit - double area = 21329.85714285; - - //We are not fitting a SiPm Fast signal (basically a Gaussian) - bool isSiPmTiming = false; - - //Instance the fitter and pass in the flag for the SiPm - GslFitter fitter(isSiPmTiming); - - //Actually perform the fitting - try { - fitter.PerformFit(data, pars, weight, area); - } catch(...) { - cerr << "Something went wrong with the fit" << endl; - } - - //Output the fit results and compare to what we get with gnuplot - cout << "Amplitude = " << fitter.GetAmplitude() << endl - << "Amplitude from Gnuplot = 0.8565802" << endl - << "Chi^2 = " << fitter.GetChiSq() << endl - << "Phase = " << fitter.GetPhase() << endl - << "Phase from Gnuplot = -0.0826487" << endl; -} \ No newline at end of file diff --git a/Scan/utkscan/core/include/pixie16app_defs.h b/Scan/utkscan/core/include/pixie16app_defs.h deleted file mode 100644 index 5e4f721a3..000000000 --- a/Scan/utkscan/core/include/pixie16app_defs.h +++ /dev/null @@ -1,329 +0,0 @@ -#ifndef __PIXIE16APP_DEFS_H -#define __PIXIE16APP_DEFS_H - -/*---------------------------------------------------------------------- - * Copyright (c) 2005 - 2009, XIA LLC - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * * Neither the name of XIA LLC nor the names of its - * contributors may be used to endorse or promote products - * derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - *----------------------------------------------------------------------*/ - -/****************************************************************************** - * - * File Name: - * - * pixie16app_defs.h - * - * Description: - * - * Constant definitions. - * - * $Rev: 13856 $ - * $Id: pixie16app_defs.h 13856 2009-11-20 23:03:35Z htan $ - ******************************************************************************/ - -/* If this is compiled by a C++ compiler, make it */ -/* clear that these are C routines. */ -#ifdef __cplusplus -extern "C" { -#endif - - -/*------------------------------------- - Pixie16 hardware revisions - -------------------------------------*/ -#define PIXIE16_REVA 0 -#define PIXIE16_REVB 1 -#define PIXIE16_REVC_MSU 2 -#define PIXIE16_REVC_GENERAL 3 -#define PIXIE16_REVD_ITHEMBA 4 -#define PIXIE16_REVD_GENERAL 5 -// Changing PIXIE16_REVISION here affects the code globally -#define PIXIE16_REVISION PIXIE16_REVD_GENERAL - - -/*------------------------------------- - Define special operation modes - (normally requires a special firmware) - -------------------------------------*/ -#ifdef CAPTURE_SLOW_TRACE - #undef CAPTURE_SLOW_TRACE -#endif -#ifdef MSU_SEGA_MODE - #undef MSU_SEGA_MODE -#endif -#ifdef EXTENDED_FASTFILTER_LEN - #undef EXTENDED_FASTFILTER_LEN -#endif -#ifdef ORNL_PSD - #undef ORNL_PSD -#endif - - -/*------------------------------------- - At which platform to compile this code - - Windows or Linux? - -------------------------------------*/ -#define PIXIE16_WINDOWS_APPAPI 0 -#define PIXIE16_LINUX_APPAPI 1 -// Changing PIXIE16_APPAPI_VER here affects the code globally -#define PIXIE16_APPAPI_VER PIXIE16_LINUX_APPAPI - - -/*------------------------------------- - Define EXPORT macro - -------------------------------------*/ -#if PIXIE16_APPAPI_VER == PIXIE16_WINDOWS_APPAPI - #define PIXIE16APP_EXPORT __declspec(dllexport) - #define PIXIE16APP_API _stdcall -#elif PIXIE16_APPAPI_VER == PIXIE16_LINUX_APPAPI - #define PIXIE16APP_EXPORT - #define PIXIE16APP_API -#endif - - -/*------------------------------------- - Define math constants - -------------------------------------*/ - -#ifndef PI - #define PI 3.14159265358979 -#endif - -#ifndef PI2 - #define PI2 6.28318530717959 -#endif - - -/*----------------------------------------------------------------- - size of system FPGA, trigger FPGA, Fippi, DSP parameters files - -----------------------------------------------------------------*/ - -#if PIXIE16_REVISION == PIXIE16_REVA -#define N_COM_FPGA_CONF 58614 // size of communications FPGA configuration (32-bit word) -#define N_TRIG_FPGA_CONF 58614 // size of trigger FPGA configuration (32-bit word) -#define N_SP_FPGA_CONF 127581 // size of signal processing FPGA configuration (32-bit word) -#elif PIXIE16_REVISION == PIXIE16_REVB || PIXIE16_REVISION == PIXIE16_REVC_MSU || PIXIE16_REVISION == PIXIE16_REVC_GENERAL -#define N_COM_FPGA_CONF 162962 // size of communications FPGA configuration (32-bit word) -#define N_SP_FPGA_CONF 162962 // size of signal processing FPGA configuration (32-bit word) -#endif -#define N_DSP_PAR 1280 // number of DSP parameters (32-bit word) -#define DSP_IO_BORDER 832 // number of DSP I/O variables - - -/*----------------------------------------------------------------- - module specifications - -----------------------------------------------------------------*/ - -#define PRESET_MAX_MODULES 24 // Preset maximum number of Pixie modules -#define NUMBER_OF_CHANNELS 16 - -#define SYSTEM_CLOCK_MHZ 100 // system (ADC and FPGA) clock frequency in MHz - -#if PIXIE16_REVISION == PIXIE16_REVA -#define DSP_CLOCK_MHZ 80 // DSP clock frequency in MHz -#elif PIXIE16_REVISION == PIXIE16_REVB || PIXIE16_REVISION == PIXIE16_REVC_MSU || PIXIE16_REVISION == PIXIE16_REVC_GENERAL || PIXIE16_REVISION == PIXIE16_REVD_ITHEMBA || PIXIE16_REVISION == PIXIE16_REVD_GENERAL -#define DSP_CLOCK_MHZ 100 // DSP clock frequency in MHz -#endif - -#define DAC_VOLTAGE_RANGE 3.0 // Pixie-16 DAC range is -1.5 V to +1.5 V - -#define MAX_ADC_TRACE_LEN 8192 // Maximum ADC trace length for a channel - -/*----------------------------------------------------------------- - run type - -----------------------------------------------------------------*/ - -#define NEW_RUN 1 // New data run -#define RESUME_RUN 0 // Resume run - -#define LIST_MODE_RUN0 0x100 // List mode run (chl=9, with traces) -#define LIST_MODE_RUN1 0x101 // List mode run (chl=9, no traces) -#define LIST_MODE_RUN2 0x102 // List mode run (chl=4, no traces) -#define LIST_MODE_RUN3 0x103 // List mode run (chl=2, no traces) -#define HISTOGRAM_RUN 0x301 // Histogram run - - -/*----------------------------------------------------------------- - I/O mode - -----------------------------------------------------------------*/ - -#define MOD_READ 1 // Host read from modules -#define MOD_WRITE 0 // Host write to modules - - -/*----------------------------------------------------------------- - Data memory, buffer, histogram, and list mode data structure - -----------------------------------------------------------------*/ - -#define DSP_IMBUFFER_START_ADDR 0x40000 // 32-bit wide -#define DSP_IMBUFFER_END_ADDR 0x5FFFF // 32-bit wide - -#define DSP_EMBUFFER_START_ADDR 0x0 // 32-bit wide -#if PIXIE16_REVISION == PIXIE16_REVA -#define DSP_EMBUFFER_END_ADDR 0xFFFFF // 32-bit wide -#else -#define DSP_EMBUFFER_END_ADDR 0x7FFFF // 32-bit wide -#endif - -#if PIXIE16_REVISION == PIXIE16_REVA -#define EM_PINGPONGBUFA_ADDR 0x80000 // 32-bit wide -#define EM_PINGPONGBUFB_ADDR 0xC0000 // 32-bit wide -#endif - -#define DATA_MEMORY_ADDRESS 0x4A000 // DSP data memory address -#define HISTOGRAM_MEMORY_ADDRESS 0x0 // histogram memory buffer in external memory -#define MAX_HISTOGRAM_LENGTH 32768 // Maximum MCA histogram length -#define IO_BUFFER_ADDRESS 0x50000 // Address of I/O output buffer -#define IO_BUFFER_LENGTH 65536 // Length of I/O output buffer -#define EXTERNAL_FIFO_LENGTH 131072 // Length of external FIFO - -#define BUFFER_HEAD_LENGTH 6 // Output buffer header length -#define EVENT_HEAD_LENGTH 3 // Event header length -#define CHANNEL_HEAD_LENGTH 9 // Channel header length - -#define EVENT_INFO_LENGTH 68 // Information length for each event -#define CHANNEL_INFO_LENGTH 4 // Information length for each channel -#define EVENT_INFO_HEADER_LENGTH 4 // Information length for each event header - - -/*------------------------------------- - Length limits for certain DSP parameters - --------------------------------------*/ - -#ifdef EXTENDED_FASTFILTER_LEN -#define FASTFILTER_MAX_LEN 128 -#else -#if (PIXIE16_REVISION == PIXIE16_REVD_ITHEMBA) || (PIXIE16_REVISION == PIXIE16_REVD_GENERAL) -#define FASTFILTER_MAX_LEN 64 -#else -#define FASTFILTER_MAX_LEN 32 -#endif -#endif -#define MIN_FASTLENGTH_LEN 1 - -#define SLOWFILTER_MAX_LEN 128 -#define MIN_SLOWLENGTH_LEN 2 -#define MIN_SLOWGAP_LEN 3 - -#ifdef EXTENDED_FASTFILTER_LEN -#define FAST_THRESHOLD_MAX 65536 -#else -#define FAST_THRESHOLD_MAX 16384 -#endif - -#if (PIXIE16_REVISION == PIXIE16_REVD_ITHEMBA) || (PIXIE16_REVISION == PIXIE16_REVD_GENERAL) -#define CFDDELAY_MAX 63 -#define CFDDELAY_MIN 1 - -#define EXTTRIGSTRETCH_MAX 4095 -#define EXTTRIGSTRETCH_MIN 1 - -#define VETOSTRETCH_MAX 4095 -#define VETOSTRETCH_MIN 1 - -#define FASTTRIGBACKLEN_MAX 4095 -#define FASTTRIGBACKLEN_MIN 1 - -#define EXTDELAYLEN_MAX 255 -#define EXTDELAYLEN_MIN 1 - -#define FASTTRIGBACKDELAY_MAX 127 -#define FASTTRIGBACKDELAY_MIN 0 - -#define QDCLEN_MAX 32767 -#define QDCLEN_MIN 1 -#endif - -/*------------------------------------- - CHANCSRA bits definitions - --------------------------------------*/ - -#define CCSRA_GOOD 2 // Channel may be read, good-channel bit -#define CCSRA_POLARITY 5 // Control polarity: 1: negative, 0: positive -#if (VARIANT == REVD_GENERAL) -#define CCSRA_TRACEENA 8 // 1: enable trace capture and associated header data; 0: disable trace capture and associated header data -#define CCSRA_QDCENA 9 // 1: enable QDC summing and associated header data; 0: dsiable QDC summing and associated header data -#endif -#define CCSRA_ENARELAY 14 // Control input relay: 1: connect, 0: disconnect - - /*------------------------------------- - MODCSRB bits definitions - --------------------------------------*/ - -#define MODCSRB_PULLUP 0 // Control pullup: 1: pulled up, 0: not pulled up -#define MODCSRB_BPCONNECTION 1 // Control BP_Connection: 1: connected, 0: disconnected -#define MODCSRB_MASTERMODULE 2 // Control Master/Worker module: 1: Master module, 0: Worker module -#define MODCSRB_FASTTRIGSRC 3 // Control fast trigger source in system FPGA: 1: Master module only, 0: all modules wired-or - -#define MODCSRB_DIRMOD 4 // Control Director module: 1: Director module; 0: other modules -#define MODCSRB_RECTRIGENA 5 // Enable Director module's record trigger (1) or disable it (0) -#define MODCSRB_CHASSISMASTER 6 // Control chassis master module: 1: chassis master module; 0: chassis non-master module -#define MODCSRB_MWMOD 7 // Control Manger/Worker module: 1: Manger/Worker module; 0: other modules -#define MODCSRB_RIGHTASTMOD 8 // Control Right Assistant module: 1: Right Assistant module; 0: other modules -#define MODCSRB_LEFTASTMOD 9 // Control Left Assistant module: 1: Left Assistant module; 0: other modules -#define MODCSRB_INHIBITENA 10 // Control external INHIBIT signal: 1: use INHIBIT; 0: don't use INHIBIT -#define MODCSRB_MULTCRATES 11 // Distribute clock and triggers in multiple crates: multiple crates (1) or only single crate (0) - -/*------------------------------------- - Control parameters - --------------------------------------*/ - -#define MAX_PAR_NAME_LENGTH 65 // Maximum length of parameter names -#define RANDOMINDICES_LENGTH 8192 // number of random indices (currently only used for tau finder) -#define MAX_ERRMSG_LENGTH 1024 // Maximum length of error message - -#define BASELINES_BLOCK_LEN 18 // Length of each baslines length (default: 2 timestamp words + 16 baselines) -#define MAX_NUM_BASELINES 3640 // Maximum number of baselines available after each baseline acquisition run - -#define EXTFIFO_READ_THRESH 1024 // Reading out threshold for external FIFO watermmark level - -#if (PIXIE16_REVISION == PIXIE16_REVD_ITHEMBA) || (PIXIE16_REVISION == PIXIE16_REVD_GENERAL) -#define PCI_STOPRUN_REGADDR 0x44 // PCI register address in the System FPGA for stopping run -#endif - -/*------------------------------------- - Frequently used Control Tasks - --------------------------------------*/ - -#define SET_DACS 0 // Set DACs -#define ENABLE_INPUT 1 // Enable detect signal input -#define RAMP_OFFSETDACS 3 // Ramp Offset DACs -#define GET_TRACES 4 // Acquire ADC traces -#define PROGRAM_FIPPI 5 // Program FIPPIs -#define GET_BASELINES 6 // Get baselines -#define ADJUST_OFFSETS 7 // Adjust DC-offsets - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Scan/utkscan/experiment/include/E11006Processor.hpp b/Scan/utkscan/experiment/include/E11006Processor.hpp deleted file mode 100644 index 51b081ad2..000000000 --- a/Scan/utkscan/experiment/include/E11006Processor.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/** \file E11006Processor.hpp - * \brief A class specific to the e11006 experiment - * \author S. V. Paulauskas - * \date June 18, 2014 - */ -#ifndef __E11006PROCESSOR_HPP_ -#define __E11006PROCESSOR_HPP_ - -#include "EventProcessor.hpp" - -///Processor for the e11006 experiment -class E11006Processor : public EventProcessor { - public: - /** Default Constructor */ - E11006Processor(); // no virtual c'tors - /** Default Destructor */ - ~E11006Processor(){}; - - /** Process an event - * \param [in] event : the event to process - * \return true if successful*/ - bool Process(RawEvent &event); - - /** Declares plots */ - void DeclarePlots(void); -}; -#endif // __E11006PROCESSOR_HPP_ diff --git a/Scan/utkscan/experiment/include/VandleAtLeribssProcessor.hpp b/Scan/utkscan/experiment/include/VandleAtLeribssProcessor.hpp deleted file mode 100644 index da13f8f0a..000000000 --- a/Scan/utkscan/experiment/include/VandleAtLeribssProcessor.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/** \file VandleAtLeribssProcessor.hpp - * \brief A class to process data from the LeRIBSS 2012 campaign. - * - *\author S. V. Paulauskas - *\date February 5, 2015 - */ -#ifndef __VANDLEATLERIBSSPROCESSOR_HPP_ -#define __VANDLEATLERIBSSPROCESSOR_HPP_ - -#include "EventProcessor.hpp" -#include "VandleProcessor.hpp" - -/// Class to process VANDLE related events -class VandleAtLeribssProcessor : public VandleProcessor { -public: - /** Default Constructor */ - VandleAtLeribssProcessor(); - /** Default Destructor */ - ~VandleAtLeribssProcessor() {}; - /** Declare the plots used in the analysis */ - virtual void DeclarePlots(void); - - /** Constructor taking a list of detector types as an argument - * \param [in] typeList : the list of bar types that are in the analysis - * \param [in] res : The resolution of the DAMM histograms - * \param [in] offset : The offset of the DAMM histograms - * \param [in] numStarts : the number of starts in the analysis */ - VandleAtLeribssProcessor(const std::vector &typeList, - const double &res, const double &offset, - const double &numStarts); - - /** Process the event - * \param [in] event : the event to process - * \return Returns true if the processing was successful */ - virtual bool Process(RawEvent &event); -private: - std::string fileName_; //!< the name of the his file - std::vector fileNames_; //!< the vector of output file names -}; -#endif diff --git a/Scan/utkscan/experiment/source/Anl1471Processor.cpp b/Scan/utkscan/experiment/source/Anl1471Processor.cpp deleted file mode 100644 index 368caf7c8..000000000 --- a/Scan/utkscan/experiment/source/Anl1471Processor.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/** \file Anl1471Processor.cpp - *\brief Processes information for VANDLE - * - * Processes VANDLE data for the ANL experiment number 1471 - * - *\author S. V. Paulauskas - *\date September 19, 2015 - */ -#include -#include - -#include - -#include "BarBuilder.hpp" -#include "DammPlotIds.hpp" -#include "GetArguments.hpp" -#include "Globals.hpp" -#include "RawEvent.hpp" -#include "TimingMapBuilder.hpp" -#include "Anl1471Processor.hpp" - -namespace dammIds { - namespace vandle { - const unsigned int DEBUGGING_OFFSET = 70; - const int DD_DEBUGGING0 = 0+DEBUGGING_OFFSET; //!< General Purpose - const int DD_DEBUGGING1 = 1+DEBUGGING_OFFSET; //!< TOF - banana - const int DD_DEBUGGING2 = 2+DEBUGGING_OFFSET; //!< TOf -lower bars w/ banana - const int DD_DEBUGGING3 = 3+DEBUGGING_OFFSET; //!< TOF - upper bars w/ banana - const int DD_DEBUGGING4 = 4+DEBUGGING_OFFSET; //!< TOF gated 600 kev - const int DD_DEBUGGING5 = 5+DEBUGGING_OFFSET; //!< TOF gated 700 kev - const int DD_DEBUGGING6 = 6+DEBUGGING_OFFSET; //!< TOF - bar 12 ban gated - const int DD_DEBUGGING7 = 7+DEBUGGING_OFFSET; //!< Unused - const int DD_DEBUGGING8 = 8+DEBUGGING_OFFSET; //!< Unused - const int DD_DEBUGGING9 = 9+DEBUGGING_OFFSET; //!< Bar loc vs tof gated - const int DD_DEBUGGING10 = 10+DEBUGGING_OFFSET; //!< Decay vs. Tof - const int DD_DEBUGGING11 = 11+DEBUGGING_OFFSET; //!< Decay vs. Genergy - const int DD_DEBUGGING12 = 12+DEBUGGING_OFFSET; //!< Decay vs Tof banana - } -}//namespace dammIds - -using namespace std; -using namespace dammIds::vandle; - -void Anl1471Processor::DeclarePlots(void) { - VandleProcessor::DeclarePlots(); - DeclareHistogram2D(DD_DEBUGGING0, SC, S7, "General Purpose"); - DeclareHistogram2D(DD_DEBUGGING1, SA, SD, "TOF - banana gated"); - DeclareHistogram2D(DD_DEBUGGING2, SA, SD, "TOF - Lower Bars Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING3, SA, SD, "TOF - Upper Bars Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING4, SA, SD, "TOF - Gated 600 keV"); - DeclareHistogram2D(DD_DEBUGGING5, SA, SD, "TOF - Gated 700 keV"); - DeclareHistogram2D(DD_DEBUGGING6, SA, SC, "TOF - Bar 12 Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING7, SA, SA, "Currently Unused"); - DeclareHistogram2D(DD_DEBUGGING8, SA, SA, "Currently Unused"); - DeclareHistogram2D(DD_DEBUGGING9, SC, S7, "Bar Loc vs. TOF - gated"); - DeclareHistogram2D(DD_DEBUGGING10, SB, SA, "Decay Time vs. ToF"); - DeclareHistogram2D(DD_DEBUGGING11, SC, SA, "Decay Time vs. GEnergy"); - DeclareHistogram2D(DD_DEBUGGING12, SA, SA, "Decay Time vs. ToF - banana"); - - DeclareHistogram2D(DEBUGGING_OFFSET+20, SA, SA, "QDC TOF - Lower 0"); - DeclareHistogram2D(DEBUGGING_OFFSET+21, SA, SA, "QDC TOF - Lower 1"); - DeclareHistogram2D(DEBUGGING_OFFSET+22, SA, SA, "QDC TOF - Upper 0"); - DeclareHistogram2D(DEBUGGING_OFFSET+23, SA, SA, "QDC TOF - Upper 1"); - DeclareHistogram2D(DEBUGGING_OFFSET+24, SA, SD, "QDC TOF - Upper "); - DeclareHistogram2D(DEBUGGING_OFFSET+25, SA, SD, "QDC TOF - Lower"); -} - -Anl1471Processor::Anl1471Processor(const std::vector &typeList, - const double &res, const double &offset, const double &numStarts) : - VandleProcessor(typeList,res,offset,numStarts) { - associatedTypes.insert("vandle"); - - char hisFileName[32]; - GetArgument(1, hisFileName, 32); - string temp = hisFileName; - temp = temp.substr(0, temp.find_first_of(" ")); - stringstream name; - name << temp; - fileName_ = name.str(); - fileNames_.push_back(fileName_ + "-tof-sm.dat"); - fileNames_.push_back(fileName_ + "-tof-md.dat"); - fileNames_.push_back(fileName_ + "-tof-04Plus.dat"); -} - -bool Anl1471Processor::Process(RawEvent &event) { - if (!EventProcessor::Process(event)) - return(false); - if(!VandleProcessor::Process(event)) - return(false); - - for (BarMap::iterator it = bars_.begin(); it != bars_.end(); it++) { - TimingDefs::TimingIdentifier barId = (*it).first; - BarDetector bar = (*it).second; - if(!bar.GetHasEvent()) - continue; - - unsigned int barLoc = barId.first; - TimingCalibration cal = bar.GetCalibration(); - - int bananaNum; - if(bar.GetType() == "small") - bananaNum = 2; - if(bar.GetType() == "medium") - bananaNum = 1; - - for(BarMap::iterator itStart = barStarts_.begin(); - itStart != barStarts_.end(); itStart++) { - BarDetector start = (*itStart).second; - - unsigned int startLoc = (*itStart).first.first; - unsigned int barPlusStartLoc = numStarts_*barLoc+startLoc; - - double tofOffset = cal.GetTofOffset(startLoc); - double tof = bar.GetWalkCorTimeAve() - - start.GetTimeAverage() + tofOffset; - double corTof = - VandleProcessor::CorrectTOF(tof, bar.GetFlightPath(), cal.GetZ0()); - - bool inPeel = histo.BananaTest(bananaNum, - corTof*plotMult_+plotOffset_, - bar.GetQdc()); - //All of them are gated using a banana gate - if(inPeel) { - ofstream data; - if(bar.GetType() == "small") { - data.open(fileNames_[0].c_str(), ios::app); - data << corTof << " " << bar.GetQdc() << endl; - } else { - data.open(fileNames_[1].c_str(), ios::app); - data << corTof << " " << bar.GetQdc() << endl; - } - data.close(); - } - - double cycleTime = TreeCorrelator::get()->place("Cycle")->last().time; - cycleTime *= (Globals::get()->clockInSeconds()*1.e9); - - double decayTime = (bar.GetTimeAverage() - cycleTime)/0.01; - - plot(DD_DEBUGGING10, corTof*plotMult_+plotOffset_, decayTime*1.e-9); - if(inPeel) - plot(DD_DEBUGGING12, corTof*plotMult_+plotOffset_, decayTime*1.e-9); - - //ofstream gammaGated; - if(geSummary_->GetMult() > 0 && inPeel) { - const vector &geList = geSummary_->GetList(); - for(vector::const_iterator itGe = geList.begin(); - itGe != geList.end(); itGe++) { - double calEnergy = (*itGe)->GetCalEnergy(); - plot(DD_DEBUGGING11, calEnergy, decayTime * 1e-9); - }// for(vector::const_iterator - }//geSummary_->GetMult() > 0 - }//loop over starts - }//loop over bars - EndProcess(); - return(true); -} diff --git a/Scan/utkscan/experiment/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt deleted file mode 100644 index 13e53cb67..000000000 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(EXPERIMENT_SOURCES - TemplateExpProcessor.cpp -) - -add_library(ExperimentObjects OBJECT ${EXPERIMENT_SOURCES}) diff --git a/Scan/utkscan/experiment/source/E11006Processor.cpp b/Scan/utkscan/experiment/source/E11006Processor.cpp deleted file mode 100644 index 6a0550a8d..000000000 --- a/Scan/utkscan/experiment/source/E11006Processor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** \file E11006Processor.cpp - * \brief A class specific to the e11006 experiment - *\author S. V. Paulauskas - *\date June 18, 2014 - */ -#include -#include - -#include - -#include "DammPlotIds.hpp" -#include "RawEvent.hpp" -#include "E11006Processor.hpp" - -//declare the namespace for the histogram numbers -namespace dammids { - namespace e11006 { - const int D_TEMP 0; //!< Temporary histogram - } -} - -using namespace std; -using namespace dammids::e11006; - -void E11006Processor::DeclarePlots(void) { - //declare a single histogram - DeclareHistogram1D(D_TEMP, S5, "1D Debugging"); -} - - -E11006Processor::E11006Processor(): EventProcessor(OFFSET,RANGE) { - name = "e11006"; - //associate the processor with both the tac and scintillator event types - associatedTypes.insert("tac"); - associatedTypes.insert("scint"); -} - -bool E11006Processor::Process(RawEvent &event) -{ - if (!EventProcessor::Process(event)) - return false; - - //get the list of all the tacs in the current event - static const vector &tacEvents = - event.GetSummary("vandleSmall")->GetList(); - //get the list of all the scintillators with the subtype "de" in the - //current event - static const vector &scintEvents = - event.GetSummary("scint:de")->GetList(); - - - //let's just loop over all of the tac events currently - for(vector::iterator it = tacEvents.begin(); it != tacEvents.end(); - it++) { - //for a summary of the nonsense you can access from the ChanEvent see - //ChanEvent.hpp (it will be listed under the long list of Get methods) - - //get the location of the tac event - unsigned int location = (*it)->GetChanID().GetLocation(); - //get the subtype of the tac event (maybe not useful but instructive) - string subType = (*it)->GetChanID().GetSubtype(); - //how about we do something useful like plot an energy? - if(location == 0) - plot(it->GetEnergy()); - } - - EndProcess(); - return true; -} diff --git a/Scan/utkscan/experiment/source/VandleAtLeribssProcessor.cpp b/Scan/utkscan/experiment/source/VandleAtLeribssProcessor.cpp deleted file mode 100644 index ea242fe9b..000000000 --- a/Scan/utkscan/experiment/source/VandleAtLeribssProcessor.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/** \file VandleAtLeribssProcessor.cpp - *\brief Processes information for VANDLE - * - * Processes VANDLE data for the LeRIBSS 2012 experiment - * - *\author S. V. Paulauskas - *\date February 5, 2015 - */ -#include -#include - -#include - -#include "BarBuilder.hpp" -#include "DammPlotIds.hpp" -#include "GetArguments.hpp" -#include "Globals.hpp" -#include "RawEvent.hpp" -#include "TimingMapBuilder.hpp" -#include "VandleAtLeribssProcessor.hpp" - -namespace dammIds { - namespace vandle { - const unsigned int DEBUGGING_OFFSET = 70; - const int DD_DEBUGGING0 = 0+DEBUGGING_OFFSET; - const int DD_DEBUGGING1 = 1+DEBUGGING_OFFSET; - const int DD_DEBUGGING2 = 2+DEBUGGING_OFFSET; - const int DD_DEBUGGING3 = 3+DEBUGGING_OFFSET; - const int DD_DEBUGGING4 = 4+DEBUGGING_OFFSET; - const int DD_DEBUGGING5 = 5+DEBUGGING_OFFSET; - const int DD_DEBUGGING6 = 6+DEBUGGING_OFFSET; - const int DD_DEBUGGING7 = 7+DEBUGGING_OFFSET; - const int DD_DEBUGGING8 = 8+DEBUGGING_OFFSET; - const int DD_DEBUGGING9 = 9+DEBUGGING_OFFSET; - const int DD_DEBUGGING10 = 10+DEBUGGING_OFFSET; - const int DD_DEBUGGING11 = 11+DEBUGGING_OFFSET; - const int DD_DEBUGGING12 = 12+DEBUGGING_OFFSET; - } -}//namespace dammIds - -using namespace std; -using namespace dammIds::vandle; - -void VandleAtLeribssProcessor::DeclarePlots(void) { - VandleProcessor::DeclarePlots(); - DeclareHistogram2D(DD_DEBUGGING0, SC, S7, "General Purpose"); - DeclareHistogram2D(DD_DEBUGGING1, SA, SD, "TOF - banana gated"); - DeclareHistogram2D(DD_DEBUGGING2, SA, SD, "TOF - Lower Bars Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING3, SA, SD, "TOF - Upper Bars Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING4, SA, SD, "TOF - Gated 600 keV"); - DeclareHistogram2D(DD_DEBUGGING5, SA, SD, "TOF - Gated 700 keV"); - DeclareHistogram2D(DD_DEBUGGING6, SA, SC, "TOF - Bar 12 Banana Gated"); - DeclareHistogram2D(DD_DEBUGGING7, SA, SA, "Currently Unused"); - DeclareHistogram2D(DD_DEBUGGING8, SA, SA, "Currently Unused"); - DeclareHistogram2D(DD_DEBUGGING9, SC, S7, "Bar Loc vs. TOF - gated"); - DeclareHistogram2D(DD_DEBUGGING10, SB, SA, "Decay Time vs. ToF"); - DeclareHistogram2D(DD_DEBUGGING11, SC, SA, "Decay Time vs. GEnergy"); - DeclareHistogram2D(DD_DEBUGGING12, SA, SA, "Decay Time vs. ToF - banana"); - - DeclareHistogram2D(DEBUGGING_OFFSET+20, SA, SA, "QDC TOF - Lower 0"); - DeclareHistogram2D(DEBUGGING_OFFSET+21, SA, SA, "QDC TOF - Lower 1"); - DeclareHistogram2D(DEBUGGING_OFFSET+22, SA, SA, "QDC TOF - Upper 0"); - DeclareHistogram2D(DEBUGGING_OFFSET+23, SA, SA, "QDC TOF - Upper 1"); - DeclareHistogram2D(DEBUGGING_OFFSET+24, SA, SD, "QDC TOF - Upper "); - DeclareHistogram2D(DEBUGGING_OFFSET+25, SA, SD, "QDC TOF - Lower"); -} - -VandleAtLeribssProcessor::VandleAtLeribssProcessor(const std::vector &typeList, - const double &res, const double &offset, const double &numStarts) : - VandleProcessor(typeList,res,offset,numStarts) { - associatedTypes.insert("vandle"); - - char hisFileName[32]; - GetArgument(1, hisFileName, 32); - string temp = hisFileName; - temp = temp.substr(0, temp.find_first_of(" ")); - stringstream name; - name << temp; - fileName_ = name.str(); - fileNames_.push_back(fileName_ + "-tof.dat"); - fileNames_.push_back(fileName_ + "-tof-02Plus.dat"); - fileNames_.push_back(fileName_ + "-tof-04Plus.dat"); -} - -bool VandleAtLeribssProcessor::Process(RawEvent &event) { - if (!EventProcessor::Process(event)) - return(false); - if(!VandleProcessor::Process(event)) - return(false); - - for (BarMap::iterator it = bars_.begin(); it != bars_.end(); it++) { - TimingDefs::TimingIdentifier barId = (*it).first; - BarDetector bar = (*it).second; - if(!bar.GetHasEvent()) - continue; - - unsigned int barLoc = barId.first; - TimingCalibration cal = bar.GetCalibration(); - - bool isLower = barLoc > 6 && barLoc < 16; - bool isUpper = barLoc > 29 && barLoc < 39; - bool isCleared = isLower; - int bananaNum = 1; - - for(TimingMap::iterator itStart = starts_.begin(); - itStart != starts_.end(); itStart++) { - HighResTimingData start = (*itStart).second; - if(!start.GetIsValidData()) - continue; - - unsigned int startLoc = (*itStart).first.first; - unsigned int barPlusStartLoc = numStarts_*barLoc+startLoc; - - //!--------- CUT On Beta Energy ---------- - if(start.GetPixieEnergy() < 1000) - continue; - - double tofOffset = cal.GetTofOffset(startLoc); - double tof = bar.GetWalkCorTimeAve() - - start.GetWalkCorrectedTime() + tofOffset; - double corTof = - VandleProcessor::CorrectTOF(tof, bar.GetFlightPath(), cal.GetZ0()); - - bool inPeel = histo.BananaTest(bananaNum, - corTof*plotMult_+plotOffset_, - bar.GetQdc()); - - if(isLower) { - if(startLoc == 0) - plot(DEBUGGING_OFFSET+20, - tof*plotMult_+plotOffset_, bar.GetQdc()); - else - plot(DEBUGGING_OFFSET+21, - tof*plotMult_+plotOffset_, bar.GetQdc()); - } - - if(isUpper) { - if(startLoc == 0) - plot(DEBUGGING_OFFSET+22, - tof*plotMult_+plotOffset_, bar.GetQdc()); - else - plot(DEBUGGING_OFFSET+23, - tof*plotMult_+plotOffset_, bar.GetQdc()); - } - - //All of them are gated using a banana gate - if(inPeel) { - plot(DD_DEBUGGING9, corTof*plotMult_+plotOffset_, barPlusStartLoc); - - if(isCleared) - plot(DD_DEBUGGING1, corTof*plotMult_+plotOffset_,bar.GetQdc()); - - if(isLower) { - ofstream data; - data.open(fileNames_[0].c_str(), ios::app); - data << corTof << endl; - data.close(); - - plot(DD_DEBUGGING2, corTof*plotMult_+plotOffset_, bar.GetQdc()); - } - if(isUpper) - plot(DD_DEBUGGING3, corTof*plotMult_+plotOffset_, bar.GetQdc()); - - if(barLoc == 12) - plot(DD_DEBUGGING6, corTof*plotMult_+plotOffset_, bar.GetQdc()); - } - - if(isLower) - plot(DEBUGGING_OFFSET+24, - corTof*plotMult_+plotOffset_, bar.GetQdc()); - if(isUpper) - plot(DEBUGGING_OFFSET+25, - corTof*plotMult_+plotOffset_, bar.GetQdc()); - - double cycleTime = TreeCorrelator::get()->place("Cycle")->last().time; - cycleTime *= (Globals::get()->clockInSeconds()*1.e9); - - double decayTime = (bar.GetTimeAverage() - cycleTime)/0.01; - - plot(DD_DEBUGGING10, corTof*plotMult_+plotOffset_, decayTime*1.e-9); - if(inPeel && isCleared) - plot(DD_DEBUGGING12, corTof*plotMult_+plotOffset_, decayTime*1.e-9); - - ofstream gammaGated; - if(geSummary_->GetMult() > 0 && isCleared && inPeel) { - const vector &geList = geSummary_->GetList(); - for(vector::const_iterator itGe = geList.begin(); - itGe != geList.end(); itGe++) { - double calEnergy = (*itGe)->GetCalEnergy(); - plot(DD_DEBUGGING11, calEnergy, decayTime * 1e-9); - if(calEnergy >= 595 && calEnergy <= 603) { - if(isLower) { - gammaGated.open(fileNames_[1].c_str(), ios::app); - gammaGated << corTof << endl; - } - plot(DD_DEBUGGING4, corTof * plotMult_ + plotOffset_, bar.GetQdc()); - } - if(calEnergy >= 692 && calEnergy <= 704) { - if(isLower) { - gammaGated.open(fileNames_[2].c_str(), ios::app); - gammaGated << corTof << endl; - } - plot(DD_DEBUGGING5, corTof * plotMult_ + plotOffset_, bar.GetQdc()); - } // if(calEnergy >= 692 - }// for(vector::const_iterator - gammaGated.close(); - }//geSummary_->GetMult() > 0 - }//loop over starts - }//loop over bars - EndProcess(); - return(true); -} diff --git a/share/CMakeLists.txt b/Share/CMakeLists.txt similarity index 100% rename from share/CMakeLists.txt rename to Share/CMakeLists.txt diff --git a/share/modulefiles/pixieSuite b/Share/modulefiles/pixieSuite similarity index 100% rename from share/modulefiles/pixieSuite rename to Share/modulefiles/pixieSuite diff --git a/share/plx/init.d/plxload b/Share/plx/init.d/plxload similarity index 100% rename from share/plx/init.d/plxload rename to Share/plx/init.d/plxload diff --git a/share/plx/init.d/plxunload b/Share/plx/init.d/plxunload similarity index 100% rename from share/plx/init.d/plxunload rename to Share/plx/init.d/plxunload diff --git a/share/plx/systemd/plx.service b/Share/plx/systemd/plx.service similarity index 64% rename from share/plx/systemd/plx.service rename to Share/plx/systemd/plx.service index 28528286c..5492fa7b5 100644 --- a/share/plx/systemd/plx.service +++ b/Share/plx/systemd/plx.service @@ -4,8 +4,8 @@ Description=Service file for PLX Driver 9054 for communication with XIA Pixie16 [Service] Type=oneshot Environment="PLX_SDK_DIR=/opt/plx/current/PlxSdk" -ExecStart=/opt/plx/current/PlxSdk/Bin/Plx_load 9054 -ExecStop=/opt/plx/current/PlxSdk/Bin/Plx_unload 9054 +ExecStart=/bin/bash /opt/plx/current/PlxSdk/Bin/Plx_load 9054 +ExecStop=/bin/bash /opt/plx/current/PlxSdk/Bin/Plx_unload 9054 RemainAfterExit=yes [Install] diff --git a/ThirdParty/CMakeLists.txt b/ThirdParty/CMakeLists.txt new file mode 100644 index 000000000..0391c89e4 --- /dev/null +++ b/ThirdParty/CMakeLists.txt @@ -0,0 +1,2 @@ +install(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX}) +add_subdirectory(source) \ No newline at end of file diff --git a/Scan/utkscan/core/include/pugiconfig.hpp b/ThirdParty/include/pugiconfig.hpp similarity index 100% rename from Scan/utkscan/core/include/pugiconfig.hpp rename to ThirdParty/include/pugiconfig.hpp diff --git a/Scan/utkscan/core/include/pugixml.hpp b/ThirdParty/include/pugixml.hpp similarity index 100% rename from Scan/utkscan/core/include/pugixml.hpp rename to ThirdParty/include/pugixml.hpp diff --git a/ThirdParty/source/CMakeLists.txt b/ThirdParty/source/CMakeLists.txt new file mode 100644 index 000000000..8cfbf14b1 --- /dev/null +++ b/ThirdParty/source/CMakeLists.txt @@ -0,0 +1,12 @@ +#We will build a separate library for each one of the third party +#libraries/codes that we are going to use. However, we'll dump them all into +#the same folder for simplicity's sake. + +#Build pugixml. This software is used to parse XML files. +set(PugixmlSources pugixml.cpp) +add_library(PugixmlObjects OBJECT ${PugixmlSources}) +add_library(PugixmlStatic STATIC $) +if(BUILD_SHARED_LIBS) + add_library(Pugixml SHARED $) + install(TARGETS Pugixml DESTINATION lib) +endif(BUILD_SHARED_LIBS) \ No newline at end of file diff --git a/Scan/utkscan/core/source/pugixml.cpp b/ThirdParty/source/pugixml.cpp similarity index 100% rename from Scan/utkscan/core/source/pugixml.cpp rename to ThirdParty/source/pugixml.cpp diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake deleted file mode 100644 index a847455fa..000000000 --- a/cmake/modules/FindPXI.cmake +++ /dev/null @@ -1,101 +0,0 @@ -# Find the PXI Library -# -# Sets the usual variables expected for find_package scripts: -# -# PXI_LIBRARY_DIR -# PXI_FOUND - true if PXI was found. -# - -find_path(PXI_ROOT_DIR - NAMES software firmware dsp configuration - HINTS ENV PXI_ROOT - PATHS /opt/xia/current - DOC "Path to pixie firmware.") - -find_path(PXI_LIBRARY_DIR - NAMES libPixie16App.a - HINTS ${PXI_ROOT_DIR}/software - DOC "Path to pixie library.") - -# Support the REQUIRED and QUIET arguments, and set PXI_FOUND if found. -include (FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS (PXI DEFAULT_MSG PXI_ROOT_DIR PXI_LIBRARY_DIR) - -if (PXI_FOUND) - set (PXI_INCLUDE_DIR ${PXI_LIBRARY_DIR}/inc ${PXI_LIBRARY_DIR}/sys ${PXI_LIBRARY_DIR}/app) - set(PXI_LIBRARIES -lPixie16App -lPixie16Sys) -endif() - -mark_as_advanced(PXI_LIBRARY_DIR) - -function(PXI_CONFIG) - message(STATUS "Creating Pixie configuration.") - #Write the base directory - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "PixieBaseDir\t\t${PXI_ROOT_DIR}\n") - - #create an installer that can be invoked by - #add_custom_target(config ${CMAKE_COMMAND} -P pixie_cfg.cmake) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake - "file(INSTALL pixie.cfg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n" - ) - - #Following are lists of keys and the glob expr to find the files - set(CONFIG_NAME SpFpgaFile ComFpgaFile DspConfFile DspVarFile CrateConfig SlotFile DspSetFile) - set(CONFIG_EXPR - firmware/fippixie16*.bin #SpFpgaFile - firmware/syspixie16*.bin #ComFpgaFile - dsp/Pixie16DSP*.ldr #DspConfFile - dsp/Pixie16DSP*.var #DspVarFile - test/pxisys*.ini #CrateConfig - configuration/slot_def.set #SlotFile - configuration/default.set #DspSetFile - ) - - #We loop over each item in the list and search for a matching file - foreach(CONFIG_STEP RANGE 0 6) - #Get key name and expression form the list - list(GET CONFIG_NAME ${CONFIG_STEP} KEY) - list(GET CONFIG_EXPR ${CONFIG_STEP} GLOB_EXPR) - - #Find all files matching hte expression - # Returns the path of the file relative to the base directory. - file(GLOB FILE_MATCHES RELATIVE ${PXI_ROOT_DIR} ${PXI_ROOT_DIR}/${GLOB_EXPR}) - - #Check that a unique match was found - list(LENGTH FILE_MATCHES NUM_MATCHES) - if (NOT NUM_MATCHES EQUAL 1) - message(STATUS "WARNING: Unable to autocomplete configuration! Unique ${KEY} file (${GLOB_EXPR}) not found!") - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg - "# Multiple options found! Make a choice on the following line and remove this comment.\n") - endif() - - if (${KEY} MATCHES "SlotFile") - if (NUM_MATCHES EQUAL 1) - configure_file(${PXI_ROOT_DIR}/${FILE_MATCHES} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake - "file(INSTALL slot_def.set DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") - set(FILE_MATCHES "./slot_def.set") - endif() - elseif (${KEY} MATCHES "DspSetFile") - if (NUM_MATCHES EQUAL 1) - configure_file(${PXI_ROOT_DIR}/${FILE_MATCHES} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake - "file(INSTALL default.set - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") - #Rename set file to current.set to maintain default.set for backup - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie_cfg.cmake - "file(INSTALL default.set - RENAME current.set - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n") - set(FILE_MATCHES ./current.set) - endif() - endif () - #Append the config file - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "${KEY}\t\t${FILE_MATCHES}\n") - endforeach() - - #Added the working set file name - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "DspWorkingSetFile\t./current.set") - -endfunction()