From aafe588d341c4d54b14d48c1a8041d0d98ab589e Mon Sep 17 00:00:00 2001 From: ksmith0 Date: Thu, 27 Oct 2016 16:48:42 -0400 Subject: [PATCH 001/255] Removed PLD_header delete statement PLD_header::~PLD_header had an uneeded delete statement. This was causing a seg fault when quitting poll2 on nitemp. Former-commit-id: 4f2946055b6826f3380477e05b07ec29626e1143 --- Core/source/hribf_buffers.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 392446ea8..473a43c58 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -101,7 +101,6 @@ PLD_header::PLD_header() : BufferType(HEAD, 0){ // 0x44414548 "HEAD" /// Destructor. PLD_header::~PLD_header(){ - if(run_title){ delete[] run_title; } } /// Get the length of the header buffer. From e10a56eb6b5cd2f1bf578e3ce5fa579d63e9ef59 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 29 Nov 2016 16:17:27 -0500 Subject: [PATCH 002/255] Updating gitignore to exclude build directories Former-commit-id: 65b717170cbb0509d02233f46107f354e84321d5 --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cdbb78d8e..0d690ab7d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ #Build files *.o -build/ +*build* #Backup files *~ @@ -44,4 +44,4 @@ HIS LDF HIS/* LDF/* -data +data \ No newline at end of file From 983581fbbd701ff7e404bdaa78dde12535c9b8e3 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 30 Nov 2016 12:07:38 -0500 Subject: [PATCH 003/255] Making the build ignore less broad. Former-commit-id: 84489ceff539ca7d6f9fe380aa5117d2b08e790a --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0d690ab7d..b1c83d318 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ #Build files *.o -*build* #Backup files *~ @@ -24,6 +23,7 @@ ValgrindOut.xml #Ignore the build and exec directory build/ +*-build-*/ install/ doc/ From ac5452d891e75f5bbdf1e0a9148f052b0f753711 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Tue, 25 Oct 2016 17:02:21 -0500 Subject: [PATCH 004/255] Updated poll2 parsing debug dump message. The message now provides more useful information about the previus and next event to allow debugging. Former-commit-id: d1d1e9d98061d659b95f330760e652ecd6da588d --- Poll/source/poll2_core.cpp | 53 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 58b7d2434..b1bd45d9c 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1783,10 +1783,10 @@ bool Poll::ReadFIFO() { //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,9 +1797,10 @@ 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; + std::cout << Display::ErrorStr() << " Slot read " << slotRead + << " not the same as slot expected " + << slotExpected << std::endl; + std::cout << std::hex << fifoData[parseWords] << std::dec << std::endl; break; } else if (chanRead < 0 || chanRead > 15) { @@ -1807,7 +1808,7 @@ bool Poll::ReadFIFO() { break; } else if(eventSize == 0){ - std::cout << Display::ErrorStr() << "ZERO EVENT SIZE in mod " << mod << "!\n"; + std::cout << Display::ErrorStr() << " ZERO EVENT SIZE in mod " << mod << "!\n"; break; } @@ -1818,6 +1819,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. @@ -1837,23 +1839,36 @@ bool Poll::ReadFIFO() { } //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 + << " at " << parseWords - dataWords << "/" << nWords[mod] + << " (" << parseWords << "/" << dataWords + nWords[mod] << ") words into FIFO." << std::endl; + //Print the previous event + std::cout << "\nEvent prior to parsing error:"; 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 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] << " "; + for(size_t i=0;i< eventSize;i++) { + if (i%5 == 0) std::cout << std::endl << "\t"; + std::cout << "0x" << std::right << std::setw(8) << std::setfill('0'); + std::cout << fifoData[parseWords - prevEventSize + i] << " "; } std::cout << std::dec << std::endl; + //Print the following event + std::cout << "\nEvent following parsing error:"; + size_t outputSize = eventSize; + if (eventSize > 50) { + outputSize = 50; + std::cout << " (Truncated at " << outputSize << " words.)"; + } + std::cout << std::hex; + for(size_t i=0;i< outputSize;i++) { + if (i%5 == 0) std::cout << std::endl << "\t"; + std::cout << "0x" << std::right << std::setw(8) << std::setfill('0'); + std::cout << fifoData[parseWords + i] << " "; + } + std::cout << std::dec << std::endl << std::endl; + do_stop_acq = true; had_error = true; return false; From 892321b88bb484db7364cf9c11eaf8dee3943e0c Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 26 Oct 2016 09:25:50 -0500 Subject: [PATCH 005/255] Corrected poll2 parse debug message. The event prior to parsing error was using wrong evet size. This has been corrected and a message about each event size is now displayed. Former-commit-id: 601679a40bb8773e396b2dd8db3a2fffc9cd423d --- Poll/source/poll2_core.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index b1bd45d9c..bc21938f0 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1845,9 +1845,9 @@ bool Poll::ReadFIFO() { << " (" << parseWords << "/" << dataWords + nWords[mod] << ") words into FIFO." << std::endl; //Print the previous event - std::cout << "\nEvent prior to parsing error:"; + std::cout << "\nEvent prior to parsing error (" << prevEventSize << " words):"; std::cout << std::hex; - for(size_t i=0;i< eventSize;i++) { + for(size_t i=0;i< prevEventSize;i++) { if (i%5 == 0) std::cout << std::endl << "\t"; std::cout << "0x" << std::right << std::setw(8) << std::setfill('0'); std::cout << fifoData[parseWords - prevEventSize + i] << " "; @@ -1855,7 +1855,7 @@ bool Poll::ReadFIFO() { std::cout << std::dec << std::endl; //Print the following event - std::cout << "\nEvent following parsing error:"; + std::cout << "\nEvent following parsing error (" << eventSize << " words):"; size_t outputSize = eventSize; if (eventSize > 50) { outputSize = 50; From 7e30f69ba98b20b96d6b9b8a1ff334b3ec503a75 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 26 Oct 2016 09:49:18 -0500 Subject: [PATCH 006/255] Poll2 parse debugging updated. Updated the output when a parsing error is encountered to display the event previous, at, and following the parsing error. In addition, during the run end process if an error had been encountered the FIFO is not read out as we may have missed a partial event and would be lost. Former-commit-id: c503a240fa3000ee82aed017d45c635fa8775c99 --- Poll/source/poll2_core.cpp | 53 +++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index bc21938f0..0aa80c265 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1580,7 +1580,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 +1596,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. @@ -1800,7 +1800,6 @@ bool Poll::ReadFIFO() { std::cout << Display::ErrorStr() << " Slot read " << slotRead << " not the same as slot expected " << slotExpected << std::endl; - std::cout << std::hex << fifoData[parseWords] << std::dec << std::endl; break; } else if (chanRead < 0 || chanRead > 15) { @@ -1840,34 +1839,58 @@ bool Poll::ReadFIFO() { //If parseWords is small then the parse failed for some reason else if (parseWords < dataWords + nWords[mod]) { //Determine the fifo position from successfully parsed words plus the last event length. - std::cout << Display::ErrorStr() << " Parsing indicated corrupted data for module " << mod - << " at " << parseWords - dataWords << "/" << nWords[mod] + 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 << "\nEvent prior to parsing error (" << prevEventSize << " words):"; - std::cout << std::hex; + 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 << "\t"; + 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::endl; + std::cout << std::dec << std::setfill(' ') << std::endl; - //Print the following event - std::cout << "\nEvent following parsing error (" << eventSize << " words):"; + //Print the parsed event + std::cout << "|\n| Event at parsing error (" << eventSize << " words):"; size_t outputSize = eventSize; if (eventSize > 50) { outputSize = 50; - std::cout << " (Truncated at " << outputSize << " words.)"; + std::cout << "\n| (Truncated at " << outputSize << " words.)"; } - std::cout << std::hex; + std::cout << std::hex << std::setfill('0'); for(size_t i=0;i< outputSize;i++) { - if (i%5 == 0) std::cout << std::endl << "\t"; + 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::endl << std::endl; + std::cout << std::dec << std::setfill(' ') << std::endl; + + //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); + } + 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 != eventSize) + 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::setfill(' ') << std::endl << "|\n"; do_stop_acq = true; had_error = true; From 4976d3df949ba3a9cf17afd19172fb158fb7e245 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 26 Oct 2016 09:52:04 -0500 Subject: [PATCH 007/255] Poll2 parse debug message correction. Mistakenly used the wrong event size for the truncation message display for the event following the parsing error. Former-commit-id: 2ddfe43af0122f3c76349d641ca872084f97744b --- Poll/source/poll2_core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 0aa80c265..11e6d8f81 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1881,7 +1881,7 @@ bool Poll::ReadFIFO() { if (eventSize > 50) outputSize = 50; if (parseWords + eventSize + outputSize >= dataWords + nWords[mod]) outputSize = dataWords + nWords[mod] - (parseWords + eventSize); - if (outputSize != eventSize) + if (outputSize != nextEventSize) std::cout << "\n| (Truncated at " << outputSize << " words.)"; std::cout << std::hex << std::setfill('0'); From 7ea1a8b559513a6518cc6dba8932b9e4abd555e4 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 26 Oct 2016 13:19:45 -0500 Subject: [PATCH 008/255] Poll2 parse errors display each error. Previously one error would supress the others. Now all messages are printed. Former-commit-id: e943de02adf1d7c1fbb540f8c680e7d7766e9da6 --- Poll/source/poll2_core.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 11e6d8f81..473eb5608 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1778,7 +1778,7 @@ 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(); @@ -1800,16 +1800,17 @@ bool Poll::ReadFIFO() { std::cout << Display::ErrorStr() << " Slot read " << slotRead << " not the same as slot expected " << slotExpected << std::endl; - break; + 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){ + if(eventSize == 0){ std::cout << Display::ErrorStr() << " ZERO EVENT SIZE in mod " << mod << "!\n"; - break; + had_error = true; } + if (had_error) break; // Update the statsHandler with the event (for monitor.bash) if(!virtualChannel && statsHandler){ @@ -1834,7 +1835,6 @@ 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]) { From 242cf886b832bc72cb51acbc5cb6bb9c2a3635f8 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 20 Oct 2016 10:26:21 -0500 Subject: [PATCH 009/255] pread/write uses ranges and reads hex input. Added the capability to specify modules or channels with a colon character delimiting a range. For example, pwrite 0 0:4 TRIGGER_THRESHOLD 0x1a would set the trigger threshold for module 0 and channels 0-4 to the hex value 0x1a (decimal 26). Also, acceptable input includes scientific notation and octal. Former-commit-id: 209d663f61de37430d31fb1c024f05cb06455c4b --- Poll/include/poll2_core.h | 7 +++ Poll/source/poll2_core.cpp | 96 +++++++++++++++++++++++++++++++------- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/Poll/include/poll2_core.h b/Poll/include/poll2_core.h index c8457c17b..3db778315 100644 --- a/Poll/include/poll2_core.h +++ b/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/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 473eb5608..5569db7d0 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -829,6 +829,30 @@ 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)); + } + else stop = start; + } + catch (const std::invalid_argument &ia) { + return false; + } + return true; +} /////////////////////////////////////////////////////////////////////////////// // Poll::CommandControl /////////////////////////////////////////////////////////////////////////////// @@ -846,10 +870,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 +1061,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"; @@ -1059,7 +1111,7 @@ void Poll::CommandControl(){ 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); - + ParameterModuleWriter writer; if(forModule(pif, mod, writer, make_pair(arguments.at(1), value))){ pif->SaveDSPParameters(); } } @@ -1074,17 +1126,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"; From 7105c54d8a41228245ae74c7393480cac40c2c7a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sat, 26 Nov 2016 21:23:33 -0500 Subject: [PATCH 010/255] Improved efficiency of Gsl2Fitter Former-commit-id: 92ebfe0b36770c8268ede4070a8f4514babc906c --- Scan/utkscan/analyzers/include/FitDriver.hpp | 4 +- .../analyzers/include/FittingAnalyzer.hpp | 6 ++- Scan/utkscan/analyzers/include/GslFitter.hpp | 25 ++++++---- .../analyzers/source/FittingAnalyzer.cpp | 46 +++++++++---------- Scan/utkscan/analyzers/source/Gsl1Fitter.cpp | 13 ++---- Scan/utkscan/analyzers/source/Gsl2Fitter.cpp | 19 +++----- 6 files changed, 50 insertions(+), 63 deletions(-) diff --git a/Scan/utkscan/analyzers/include/FitDriver.hpp b/Scan/utkscan/analyzers/include/FitDriver.hpp index 229193bc6..5d3032506 100644 --- a/Scan/utkscan/analyzers/include/FitDriver.hpp +++ b/Scan/utkscan/analyzers/include/FitDriver.hpp @@ -41,6 +41,7 @@ class FitDriver { /// \param[in] weight The weight for the fit virtual void PerformFit(const std::vector &data, const std::pair &pars, + const bool &isFastSipm, const double &weight = 1., const double &area = 1.) {}; /// Sets the data that we are going to fit @@ -66,9 +67,6 @@ class FitDriver { 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 diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index b1e9fbc31..f13aa0914 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -13,6 +13,7 @@ #include #include "FitDriver.hpp" +#include "Globals.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" @@ -23,7 +24,7 @@ class FittingAnalyzer : public TraceAnalyzer { FittingAnalyzer(const std::string &s); /** Default Destructor */ - ~FittingAnalyzer() {}; + ~FittingAnalyzer(); /** Declare plots for the analyzer */ virtual void DeclarePlots(void); /** Analyzes the traces @@ -35,7 +36,8 @@ class FittingAnalyzer : public TraceAnalyzer { const std::string &detSubtype, const std::map & tagMap); private: - FitDriver::FITTER_TYPE fitterType_; + FitDriver *driver_; + Globals *globals_; }; #endif // __FITTINGANALYZER_HPP_ // David is awesome. diff --git a/Scan/utkscan/analyzers/include/GslFitter.hpp b/Scan/utkscan/analyzers/include/GslFitter.hpp index d9d38b4b2..4fc1e0cce 100644 --- a/Scan/utkscan/analyzers/include/GslFitter.hpp +++ b/Scan/utkscan/analyzers/include/GslFitter.hpp @@ -2,38 +2,43 @@ /// \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 "FitDriver.hpp" class GslFitter : public FitDriver{ public: ///Default Constructor - GslFitter(const bool &isFastSipm) : FitDriver() {isFastSipm_ = isFastSipm;} + GslFitter() : FitDriver() {}; ///Default Destructor - virtual ~GslFitter(){}; + virtual ~GslFitter() {}; ///\return the phase from the GSL fit - virtual double GetPhase(void){return phase_;} + double GetPhase(void){return phase_;} ///\return the amplitude from the GSL fit - virtual double GetAmplitude(void) {return amp_;} + double GetAmplitude(void) {return amp_;} ///\return the chi^2 from the GSL fit - virtual double GetChiSq(void) {return chi_*chi_;} + double GetChiSq(void) {return chi_*chi_;} ///\return the chi^2dof from the GSL fit - virtual double GetChiSqPerDof(void) {return GetChiSq()/dof_;} + 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, + void PerformFit(const std::vector &data, const std::pair &pars, + const bool &isSipmFast = false, const double &weight = 1., const double &area = 1.); private: - bool isFastSipm_; - double amp_; double chi_; double dof_; diff --git a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp index e0a5857d1..ef0092f89 100644 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp @@ -15,7 +15,6 @@ #include -#include "Globals.hpp" #include "DammPlotIds.hpp" #include "FitDriver.hpp" #include "FittingAnalyzer.hpp" @@ -36,24 +35,33 @@ void FittingAnalyzer::DeclarePlots(void) { FittingAnalyzer::FittingAnalyzer(const std::string &s) { name = "FittingAnalyzer"; if(s == "GSL" || s == "gsl") { - fitterType_ = FitDriver::GSL; + driver_ = new GslFitter(); } else { - fitterType_ = FitDriver::UNKNOWN; + 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(); + globals_ = Globals::get(); const double sigmaBaseline = trace.GetValue("sigmaBaseline"); const double maxVal = trace.GetValue("maxval"); @@ -66,39 +74,27 @@ void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, trace.plot(D_SIGMA, sigmaBaseline*100); if(!isDblBetaT) { - if(sigmaBaseline > globals->sigmaBaselineThresh()) { + if(sigmaBaseline > globals_->sigmaBaselineThresh()) { EndAnalyze(); return; } } else { - if(sigmaBaseline > globals->siPmtSigmaBaselineThresh()) { + if(sigmaBaseline > globals_->siPmtSigmaBaselineThresh()) { EndAnalyze(); return; } } - pair pars = globals->fitPars(detType+":"+detSubtype); + 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; - } + pars = globals_->fitPars(detType+":"+detSubtype+":timing"); - driver->PerformFit(waveform, pars, sigmaBaseline, qdc); - trace.InsertValue("phase", driver->GetPhase()+maxPos); + driver_->PerformFit(waveform, pars, isDblBetaT, 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()); + 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/Gsl1Fitter.cpp b/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp index 30798b964..364906af6 100644 --- a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp +++ b/Scan/utkscan/analyzers/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 @@ -57,7 +49,8 @@ using namespace std; void GslFitter::PerformFit(const std::vector &data, const std::pair &pars, - const double &weight/* = 1.*/, + const bool & isSipmFast/*= false */, + const double &weight/* = 1.*/, const double &area/* = 1.*/) { gsl_multifit_function_fdf f; int status; @@ -77,7 +70,7 @@ void GslFitter::PerformFit(const std::vector &data, f.n = sizeFit; f.params = &fitData; - if(!isFastSipm_) { + if(!isSipmFast) { numParams = 2; xInit[0] = 0.0; xInit[1] = 2.5; diff --git a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp b/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp index 5923743e7..00aa995a9 100644 --- a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp +++ b/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp @@ -2,13 +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 @@ -40,6 +33,7 @@ using namespace std; void GslFitter::PerformFit(const std::vector &data, const std::pair &pars, + const bool & isSipmFast/*= false */, const double &weight/* = 1.*/, const double &area/* = 1.*/) { gsl_multifit_function_fdf f; @@ -48,7 +42,7 @@ void GslFitter::PerformFit(const std::vector &data, size_t p; double xInit[3]; - if(!isFastSipm_) { + if(!isSipmFast) { p = 2; xInit[0] = 0.0; xInit[1] = 2.5; @@ -75,8 +69,8 @@ void GslFitter::PerformFit(const std::vector &data, 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 xtol = 1e-4; + double gtol = 1e-4; double ftol = 0.0; f.n = n; @@ -89,21 +83,20 @@ void GslFitter::PerformFit(const std::vector &data, } gsl_multifit_fdfsolver_wset (s, &f, &x.vector, &w.vector); - gsl_multifit_fdfsolver_driver(s, 1000, xtol, gtol, ftol, &info); + gsl_multifit_fdfsolver_driver(s, 100, 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_) { + if(!isSipmFast) { 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); From 6f1483091ccd2f68471bcb68ed0d42b52c6b5e49 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 30 Nov 2016 12:02:10 -0500 Subject: [PATCH 011/255] Named a magic number in the Gsl2Fitter.cpp I have addressed a magic number in the Gsl2Fitter, the magic number 100 was actually the maximum number of iterations. Former-commit-id: 1ea30e566628d2c8c5882fdf2f1093b6cd2c5092 --- Scan/utkscan/analyzers/source/Gsl2Fitter.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp b/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp index 00aa995a9..1c671d511 100644 --- a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp +++ b/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp @@ -69,9 +69,10 @@ void GslFitter::PerformFit(const std::vector &data, gsl_vector_view x = gsl_vector_view_array (xInit,p); gsl_vector_view w = gsl_vector_view_array (weights,n); - double xtol = 1e-4; - double gtol = 1e-4; - double ftol = 0.0; + 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; @@ -83,7 +84,7 @@ void GslFitter::PerformFit(const std::vector &data, } gsl_multifit_fdfsolver_wset (s, &f, &x.vector, &w.vector); - gsl_multifit_fdfsolver_driver(s, 100, xtol, gtol, ftol, &info); + gsl_multifit_fdfsolver_driver(s, maxIter, xtol, gtol, ftol, &info); gsl_multifit_fdfsolver_jac(s,jac); gsl_multifit_covar (jac, 0.0, covar); From f2adce89f69522fdd054def9fbf3d55fae1ba2e4 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 30 Nov 2016 12:05:44 -0500 Subject: [PATCH 012/255] Addressing scoping change in Fitting Analyzer. The globals_ variable had been added for simplicity, but was only used in a single instance so created unnecessary code bloat. Former-commit-id: 180ed87131e214050a5a34e8ed7d516ff5c5eceb --- Scan/utkscan/analyzers/include/FittingAnalyzer.hpp | 1 - Scan/utkscan/analyzers/source/FittingAnalyzer.cpp | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index f13aa0914..a4af1130e 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -37,7 +37,6 @@ class FittingAnalyzer : public TraceAnalyzer { const std::map & tagMap); private: FitDriver *driver_; - Globals *globals_; }; #endif // __FITTINGANALYZER_HPP_ // David is awesome. diff --git a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp index ef0092f89..397e620c8 100644 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp @@ -61,7 +61,7 @@ void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, return; } - globals_ = Globals::get(); + Globals *globals = Globals::get(); const double sigmaBaseline = trace.GetValue("sigmaBaseline"); const double maxVal = trace.GetValue("maxval"); @@ -74,20 +74,20 @@ void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, trace.plot(D_SIGMA, sigmaBaseline*100); if(!isDblBetaT) { - if(sigmaBaseline > globals_->sigmaBaselineThresh()) { + if(sigmaBaseline > globals->sigmaBaselineThresh()) { EndAnalyze(); return; } } else { - if(sigmaBaseline > globals_->siPmtSigmaBaselineThresh()) { + if(sigmaBaseline > globals->siPmtSigmaBaselineThresh()) { EndAnalyze(); return; } } - pair pars = globals_->fitPars(detType+":"+detSubtype); + pair pars = globals->fitPars(detType+":"+detSubtype); if(isDblBetaT) - pars = globals_->fitPars(detType+":"+detSubtype+":timing"); + pars = globals->fitPars(detType+":"+detSubtype+":timing"); driver_->PerformFit(waveform, pars, isDblBetaT, sigmaBaseline, qdc); trace.InsertValue("phase", driver_->GetPhase()+maxPos); From ac284e39e83dcc9de2e04ab145b5f5d3a725a3a5 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 30 Nov 2016 13:00:59 -0500 Subject: [PATCH 013/255] Removed unnecessary header and fixed if statement. Former-commit-id: c326e9b1e1d44603141719351dc9f12fb5834903 --- Scan/utkscan/analyzers/include/FittingAnalyzer.hpp | 1 - Scan/utkscan/analyzers/source/Gsl1Fitter.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index a4af1130e..cf080b92d 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -13,7 +13,6 @@ #include #include "FitDriver.hpp" -#include "Globals.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" diff --git a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp b/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp index 364906af6..45d9a1c8a 100644 --- a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp +++ b/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp @@ -105,7 +105,7 @@ void GslFitter::PerformFit(const std::vector &data, gsl_multifit_covar (s->J, 0.0, covar); chi_ = gsl_blas_dnrm2(s->f); - if(!isFastSipm_) { + if(!isSipmFast) { phase_ = gsl_vector_get(s->x,0); amp_ = gsl_vector_get(s->x,1); } else { From 736478e4cfa3c309b9d2eb932b768369609b5fbf Mon Sep 17 00:00:00 2001 From: Thomas King Date: Wed, 30 Nov 2016 13:08:43 -0500 Subject: [PATCH 014/255] Fixes compilation issues with Gsl1Fitter Former-commit-id: 0ebed3f732dcff032aa2c56b42eb4ac35f23781f --- Scan/utkscan/analyzers/tests/test_gslfitter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp b/Scan/utkscan/analyzers/tests/test_gslfitter.cpp index 1c3767cde..ebc0c1481 100644 --- a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp +++ b/Scan/utkscan/analyzers/tests/test_gslfitter.cpp @@ -37,11 +37,11 @@ int main(int argc, char* argv[]){ bool isSiPmTiming = false; //Instance the fitter and pass in the flag for the SiPm - GslFitter fitter(isSiPmTiming); + GslFitter fitter; //Actually perform the fitting try { - fitter.PerformFit(data, pars, weight, area); + fitter.PerformFit(data, pars, isSiPmTiming, weight, area); } catch(...) { cerr << "Something went wrong with the fit" << endl; } From 106a03bfc8a657cc1dd3220f7d22bf7242dfce31 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 23 Nov 2016 18:55:44 -0500 Subject: [PATCH 015/255] Adding cmake to find UnitTest++ for performing unit tests When tests is enabled we now search for the UnitTest++ library and includes. This package is not currently required since the written tests do not explicitly use it. (yet) Former-commit-id: 90cfe6cfec357f87bc4844a9f74d017bfdc5513a --- CMakeLists.txt | 9 +++++++- Scan/utkscan/analyzers/tests/CMakeLists.txt | 2 +- .../analyzers/tests/test_gslfitter.cpp | 16 +++++++------- cmake/modules/FindUnitTest++.cmake | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 cmake/modules/FindUnitTest++.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c235523aa..962459729 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,14 @@ find_package (PLX) #Find the Pixie Firmware find_package (PXI) +#Find the UnitTest++ Package. This package can be obtained from +#https://github.com/unittest-cpp/unittest-cpp.git +if(BUILD_TESTS) + find_package(UnitTest++) + link_directories(${UNITTEST++_LIBRARY_DIR}) + include_directories(${UNITTEST++_INCLUDE_DIR}) +endif(BUILD_TESTS) + #Find curses library used for poll2/scan/skeleton/scope/etc if(USE_NCURSES) find_package(Curses REQUIRED) @@ -102,7 +110,6 @@ 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) diff --git a/Scan/utkscan/analyzers/tests/CMakeLists.txt b/Scan/utkscan/analyzers/tests/CMakeLists.txt index 9568d1ef8..357e22f25 100644 --- a/Scan/utkscan/analyzers/tests/CMakeLists.txt +++ b/Scan/utkscan/analyzers/tests/CMakeLists.txt @@ -8,5 +8,5 @@ if(USE_GSL) #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}) + target_link_libraries(test_gslfitter ${GSL_LIBRARIES} UnitTest++) 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 index ebc0c1481..3900b0a64 100644 --- a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp +++ b/Scan/utkscan/analyzers/tests/test_gslfitter.cpp @@ -8,24 +8,24 @@ using namespace std; -int main(int argc, char* argv[]){ +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 { + 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++ ) + 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); + pair pars = make_pair(0.2659404170, 0.208054799179688); //Standard deviation of the baseline provides weight double weight = 1.9761847389475; @@ -47,9 +47,9 @@ int main(int argc, char* argv[]){ } //Output the fit results and compare to what we get with gnuplot - cout << "Amplitude = " << fitter.GetAmplitude() << endl + cout << "Chi^2 = " << fitter.GetChiSq() << endl << "Amplitude from Gnuplot = 0.8565802" << endl - << "Chi^2 = " << fitter.GetChiSq() << endl - << "Phase = " << fitter.GetPhase() << endl - << "Phase from Gnuplot = -0.0826487" << endl; + << "Amplitude = " << fitter.GetAmplitude() << endl + << "Phase from Gnuplot = -0.0826487" << endl + << "Phase = " << fitter.GetPhase() << endl; } \ No newline at end of file diff --git a/cmake/modules/FindUnitTest++.cmake b/cmake/modules/FindUnitTest++.cmake new file mode 100644 index 000000000..775d0d818 --- /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 + PATH_SUFFIXES UnitTest++) +#Locate the library +find_path(UNITTEST++_LIBRARY_DIR + NAMES libUnitTest++.a + PATHS /opt/UnitTest++ + 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) From 4489ff5eda69f7a33062d00e5a510f7d60351a6b Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 23 Nov 2016 19:08:59 -0500 Subject: [PATCH 016/255] Preparing to add some unit tests for the core classes Former-commit-id: a3c125bf645c8e194caa9b90ceb70b2056cab3c4 --- Scan/utkscan/core/CMakeLists.txt | 4 ++++ Scan/utkscan/core/tests/CMakeLists.txt | 0 2 files changed, 4 insertions(+) create mode 100644 Scan/utkscan/core/tests/CMakeLists.txt diff --git a/Scan/utkscan/core/CMakeLists.txt b/Scan/utkscan/core/CMakeLists.txt index b7307a5f4..3c95c3de0 100644 --- a/Scan/utkscan/core/CMakeLists.txt +++ b/Scan/utkscan/core/CMakeLists.txt @@ -1 +1,5 @@ +if(BUILD_TESTS) + add_subdirectory(tests) +endif(BUILD_TESTS) + add_subdirectory(source) \ No newline at end of file diff --git a/Scan/utkscan/core/tests/CMakeLists.txt b/Scan/utkscan/core/tests/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb From 318909d5c1acddf768165351ad78d4c519dc9651 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 25 Nov 2016 14:54:46 -0500 Subject: [PATCH 017/255] Fixed up compilation so that we can build the unit tests for Core The CMakeLists.txt have all been updated so that we can begin to build the tests for the classes in Core. I have added the UnitTest++ package as a required package before the utkscan tests can be built. Former-commit-id: 616328208e82f476620a24d32009326bb04541c8 --- CMakeLists.txt | 8 -------- Scan/ScanLib/include/Utilities.hpp | 8 ++++++++ Scan/utkscan/CMakeLists.txt | 13 +++++++++++-- Scan/utkscan/core/CMakeLists.txt | 4 ++-- Scan/utkscan/core/source/CMakeLists.txt | 14 ++++++++------ Scan/utkscan/core/tests/CMakeLists.txt | 4 ++++ Scan/utkscan/core/tests/unittest-WalkCorrector.cpp | 9 +++++++++ 7 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 Scan/ScanLib/include/Utilities.hpp create mode 100644 Scan/utkscan/core/tests/unittest-WalkCorrector.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 962459729..04253b44f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,14 +90,6 @@ find_package (PLX) #Find the Pixie Firmware find_package (PXI) -#Find the UnitTest++ Package. This package can be obtained from -#https://github.com/unittest-cpp/unittest-cpp.git -if(BUILD_TESTS) - find_package(UnitTest++) - link_directories(${UNITTEST++_LIBRARY_DIR}) - include_directories(${UNITTEST++_INCLUDE_DIR}) -endif(BUILD_TESTS) - #Find curses library used for poll2/scan/skeleton/scope/etc if(USE_NCURSES) find_package(Curses REQUIRED) diff --git a/Scan/ScanLib/include/Utilities.hpp b/Scan/ScanLib/include/Utilities.hpp new file mode 100644 index 000000000..9f705304a --- /dev/null +++ b/Scan/ScanLib/include/Utilities.hpp @@ -0,0 +1,8 @@ +// +// Created by vincent on 11/25/16. +// + +#ifndef PIXIESUITE_UTILITIES_HPP +#define PIXIESUITE_UTILITIES_HPP + +#endif //PIXIESUITE_UTILITIES_HPP diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index 76e70143c..12617318b 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -7,6 +7,14 @@ 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) +#Find the UnitTest++ Package. This package can be obtained from +#https://github.com/unittest-cpp/unittest-cpp.git +if(BUILD_UTKSCAN_TESTS) + find_package(UnitTest++ REQUIRED) + link_directories(${UNITTEST++_LIBRARY_DIR}) + include_directories(${UNITTEST++_INCLUDE_DIR}) +endif(BUILD_UTKSCAN_TESTS) + # newreadout is needed to account for a change to pixie16 readout # structure change on 03/20/08. Is is REQUIRED!! add_definitions(-D newreadout) @@ -61,6 +69,7 @@ add_subdirectory(processors) if(NOT USE_HRIBF) set(SCAN_NAME utkscan) add_executable(${SCAN_NAME} + $ $ $ $ @@ -68,6 +77,7 @@ if(NOT USE_HRIBF) else(USE_HRIBF) set(SCAN_NAME utkscanor) add_executable(${SCAN_NAME} + $ $ $ $ @@ -96,5 +106,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/Scan/utkscan/core/CMakeLists.txt index 3c95c3de0..c366d5def 100644 --- a/Scan/utkscan/core/CMakeLists.txt +++ b/Scan/utkscan/core/CMakeLists.txt @@ -1,5 +1,5 @@ -if(BUILD_TESTS) +if(BUILD_UTKSCAN_TESTS) add_subdirectory(tests) -endif(BUILD_TESTS) +endif(BUILD_UTKSCAN_TESTS) add_subdirectory(source) \ No newline at end of file diff --git a/Scan/utkscan/core/source/CMakeLists.txt b/Scan/utkscan/core/source/CMakeLists.txt index 730c3526f..9093a856f 100644 --- a/Scan/utkscan/core/source/CMakeLists.txt +++ b/Scan/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 @@ -41,6 +35,14 @@ 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} diff --git a/Scan/utkscan/core/tests/CMakeLists.txt b/Scan/utkscan/core/tests/CMakeLists.txt index e69de29bb..a38652d86 100644 --- a/Scan/utkscan/core/tests/CMakeLists.txt +++ b/Scan/utkscan/core/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(unittest-WalkCorrector unittest-WalkCorrector.cpp + ../source/WalkCorrector.cpp) +target_link_libraries(unittest-WalkCorrector UnitTest++ ${LIBS}) +install(TARGETS unittest-WalkCorrector DESTINATION bin/unittests) \ No newline at end of file diff --git a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp new file mode 100644 index 000000000..6f8976600 --- /dev/null +++ b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp @@ -0,0 +1,9 @@ +///@file unittest-WalkCorrector.cpp +///@brief Main driver to test the Walk Corrector. +///@author S. V. Paulauskas +///@date November 25, 2016 +#include + +int main(int argv, char* argc[]) { + return(UnitTest::RunAllTests()); +} From 120c4440c0127d208f9d857f0a03ebcf4439608e Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 25 Nov 2016 16:07:36 -0500 Subject: [PATCH 018/255] Adding unit tests for testing the output of the Model methods I have moved the Model_* methods to be public so that they can be unit tested. I am also tweaking the methods so that they use const references to avoid unnecessary copies. Former-commit-id: 8342231ceaf4b2e79a5003ae4b6376d6cb1876d3 --- Scan/utkscan/core/include/WalkCorrector.hpp | 24 ++--- Scan/utkscan/core/source/WalkCorrector.cpp | 24 ++--- Scan/utkscan/core/tests/CMakeLists.txt | 2 +- .../core/tests/unittest-WalkCorrector.cpp | 88 ++++++++++++++++++- 4 files changed, 112 insertions(+), 26 deletions(-) diff --git a/Scan/utkscan/core/include/WalkCorrector.hpp b/Scan/utkscan/core/include/WalkCorrector.hpp index 9bb738bff..5ad9b39e0 100644 --- a/Scan/utkscan/core/include/WalkCorrector.hpp +++ b/Scan/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,6 @@ 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_; - /** \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 +75,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 +101,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 +131,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/WalkCorrector.cpp b/Scan/utkscan/core/source/WalkCorrector.cpp index aa8623127..2e0e018c4 100644 --- a/Scan/utkscan/core/source/WalkCorrector.cpp +++ b/Scan/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/tests/CMakeLists.txt b/Scan/utkscan/core/tests/CMakeLists.txt index a38652d86..4d2894ec9 100644 --- a/Scan/utkscan/core/tests/CMakeLists.txt +++ b/Scan/utkscan/core/tests/CMakeLists.txt @@ -1,4 +1,4 @@ add_executable(unittest-WalkCorrector unittest-WalkCorrector.cpp - ../source/WalkCorrector.cpp) + ../source/WalkCorrector.cpp ../source/Identifier.cpp) target_link_libraries(unittest-WalkCorrector UnitTest++ ${LIBS}) install(TARGETS unittest-WalkCorrector DESTINATION bin/unittests) \ No newline at end of file diff --git a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp index 6f8976600..451687cec 100644 --- a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp +++ b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp @@ -1,9 +1,95 @@ ///@file unittest-WalkCorrector.cpp -///@brief Main driver to test the Walk Corrector. +///@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; + +///@brief Test for the method Model_None that will always return a zero. +TEST_FIXTURE(WalkCorrector, Test_Model_None) { + CHECK(Model_None() == 0.0); +} + +///@brief Test for method Model_A +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); +} + int main(int argv, char* argc[]) { +// Identifier id("unit", "test", 123); + return(UnitTest::RunAllTests()); } From d65dfe08cd0f5321cd6fd5f59fe75c91e7a86872 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sat, 26 Nov 2016 16:02:50 -0500 Subject: [PATCH 019/255] Writing tests for Identifier Creating unit tests for Identifier to ensure that the methods are working properly. Former-commit-id: d768cf911ccb1da9834c130385c4b5b1fbab8109 --- Scan/utkscan/core/include/Identifier.hpp | 48 +++++--- Scan/utkscan/core/source/Identifier.cpp | 6 +- Scan/utkscan/core/tests/CMakeLists.txt | 6 +- .../core/tests/unittest-Identifier.cpp | 112 ++++++++++++++++++ .../core/tests/unittest-WalkCorrector.cpp | 7 +- 5 files changed, 156 insertions(+), 23 deletions(-) create mode 100644 Scan/utkscan/core/tests/unittest-Identifier.cpp diff --git a/Scan/utkscan/core/include/Identifier.hpp b/Scan/utkscan/core/include/Identifier.hpp index 3da8b9380..960e3ae2c 100644 --- a/Scan/utkscan/core/include/Identifier.hpp +++ b/Scan/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;} + /** 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) 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 * @@ -119,6 +130,12 @@ class Identifier { } } + ///@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; @@ -128,8 +145,9 @@ class Identifier { 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. + 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 */ }; diff --git a/Scan/utkscan/core/source/Identifier.cpp b/Scan/utkscan/core/source/Identifier.cpp index a44b3684b..7c5b99611 100644 --- a/Scan/utkscan/core/source/Identifier.cpp +++ b/Scan/utkscan/core/source/Identifier.cpp @@ -9,12 +9,12 @@ using namespace std; + + int Identifier::GetTag(const std::string &s) const { map::const_iterator it = tag.find(s); - - if (it == tag.end()) { + if (it == tag.end()) return(std::numeric_limits::max()); - } return it->second; } diff --git a/Scan/utkscan/core/tests/CMakeLists.txt b/Scan/utkscan/core/tests/CMakeLists.txt index 4d2894ec9..24ab9b9e6 100644 --- a/Scan/utkscan/core/tests/CMakeLists.txt +++ b/Scan/utkscan/core/tests/CMakeLists.txt @@ -1,4 +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) \ No newline at end of file +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/Scan/utkscan/core/tests/unittest-Identifier.cpp b/Scan/utkscan/core/tests/unittest-Identifier.cpp new file mode 100644 index 000000000..08299d619 --- /dev/null +++ b/Scan/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/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp index 451687cec..2f456b84b 100644 --- a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp +++ b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp @@ -13,12 +13,13 @@ using namespace std; -///@brief Test for the method Model_None that will always return a zero. +///Initialize an Identifier object to test methods. +Identifier id("unit", "test", 3); + TEST_FIXTURE(WalkCorrector, Test_Model_None) { CHECK(Model_None() == 0.0); } -///@brief Test for method Model_A TEST_FIXTURE(WalkCorrector, Test_ModelA) { vector par = {0.5,2.1,3.7,0.4,0.1}; double raw = 20.3; @@ -89,7 +90,5 @@ TEST_FIXTURE(WalkCorrector, Test_Model_VD) { } int main(int argv, char* argc[]) { -// Identifier id("unit", "test", 123); - return(UnitTest::RunAllTests()); } From cf2ac99e854c979f6bb0f5f8a13dfa9dc030febe Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sat, 26 Nov 2016 19:18:06 -0500 Subject: [PATCH 020/255] Adding test fixture to test the GetCorrection method. I also moved the methods to calculate the parameters to protected from public. Former-commit-id: 7f5930556d4b21d6af7c4f65cdffff5813a8cfa8 --- Scan/utkscan/core/include/WalkCorrector.hpp | 1 + .../core/tests/unittest-WalkCorrector.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Scan/utkscan/core/include/WalkCorrector.hpp b/Scan/utkscan/core/include/WalkCorrector.hpp index 5ad9b39e0..582e6a240 100644 --- a/Scan/utkscan/core/include/WalkCorrector.hpp +++ b/Scan/utkscan/core/include/WalkCorrector.hpp @@ -61,6 +61,7 @@ class WalkCorrector { * \return The walk corrected value of raw */ double GetCorrection(Identifier& chanID, double raw) const; +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 diff --git a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp index 2f456b84b..5b7623735 100644 --- a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp +++ b/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp @@ -13,9 +13,6 @@ using namespace std; -///Initialize an Identifier object to test methods. -Identifier id("unit", "test", 3); - TEST_FIXTURE(WalkCorrector, Test_Model_None) { CHECK(Model_None() == 0.0); } @@ -89,6 +86,20 @@ TEST_FIXTURE(WalkCorrector, Test_Model_VD) { 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()); } From 864cd56a7106a25dc22b9097ccda661b586ed6be Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 2 Dec 2016 14:57:53 -0500 Subject: [PATCH 021/255] Moved where we look for the UnitTest++ library and added new flag I wanted to move this up a directory since I will soon be writing unit tests for some of the other classes not specific to utkscan. Former-commit-id: 56738607c2b698744a7685dc43ea4c2fc6a5cda1 --- CMakeLists.txt | 9 +++++++++ Scan/utkscan/CMakeLists.txt | 8 -------- Scan/utkscan/core/CMakeLists.txt | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04253b44f..88fb51fa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ 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) @@ -102,6 +103,14 @@ else() set(USE_NCURSES OFF) endif() +#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_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) diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index 12617318b..ebe82e660 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -7,14 +7,6 @@ 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) -#Find the UnitTest++ Package. This package can be obtained from -#https://github.com/unittest-cpp/unittest-cpp.git -if(BUILD_UTKSCAN_TESTS) - find_package(UnitTest++ REQUIRED) - link_directories(${UNITTEST++_LIBRARY_DIR}) - include_directories(${UNITTEST++_INCLUDE_DIR}) -endif(BUILD_UTKSCAN_TESTS) - # newreadout is needed to account for a change to pixie16 readout # structure change on 03/20/08. Is is REQUIRED!! add_definitions(-D newreadout) diff --git a/Scan/utkscan/core/CMakeLists.txt b/Scan/utkscan/core/CMakeLists.txt index c366d5def..b71414f04 100644 --- a/Scan/utkscan/core/CMakeLists.txt +++ b/Scan/utkscan/core/CMakeLists.txt @@ -1,5 +1,5 @@ -if(BUILD_UTKSCAN_TESTS) +if(BUILD_UNITTESTS) add_subdirectory(tests) -endif(BUILD_UTKSCAN_TESTS) +endif(BUILD_UNITTESTS) add_subdirectory(source) \ No newline at end of file From 43114c020a4c64dafa23e2a08de5daaf7221f29d Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 2 Dec 2016 15:40:18 -0500 Subject: [PATCH 022/255] Updated cmake module to look for the default UnitTest++ install dir. Former-commit-id: 1c31294b8284003058354daedb87d8f2537a1f2b --- cmake/modules/FindUnitTest++.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindUnitTest++.cmake b/cmake/modules/FindUnitTest++.cmake index 775d0d818..e619f273e 100644 --- a/cmake/modules/FindUnitTest++.cmake +++ b/cmake/modules/FindUnitTest++.cmake @@ -7,12 +7,12 @@ #Locate the Include directory find_path(UNITTEST++_INCLUDE_DIR NAMES UnitTest++.h - PATHS /opt/UnitTest++/include + PATHS /opt/UnitTest++/include /usr/local/include PATH_SUFFIXES UnitTest++) #Locate the library find_path(UNITTEST++_LIBRARY_DIR NAMES libUnitTest++.a - PATHS /opt/UnitTest++ + PATHS /opt/UnitTest++ /usr/lib/ PATH_SUFFIXES lib) include (FindPackageHandleStandardArgs) From c1e5c7f4ea29026dc10178d11755a67febaf7898 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 25 Nov 2016 09:06:04 -0500 Subject: [PATCH 023/255] Removed pixie16app_defs.h from the Scan side of the project It was used for exactly two values, which are repeated and hard coded in the Unpacker class. They are not used at all in any of the utkscan related code, and are unnecessary. Former-commit-id: 6a0f20fac97516c5164ccb0a1a72b843f4d9da39 --- Scan/utkscan/core/include/ChanEvent.hpp | 4 +- Scan/utkscan/core/include/DetectorSummary.hpp | 3 - Scan/utkscan/core/include/Globals.hpp | 7 - Scan/utkscan/core/include/RawEvent.hpp | 2 - Scan/utkscan/core/include/pixie16app_defs.h | 329 ------------------ Scan/utkscan/core/source/Globals.cpp | 3 - 6 files changed, 1 insertion(+), 347 deletions(-) delete mode 100644 Scan/utkscan/core/include/pixie16app_defs.h diff --git a/Scan/utkscan/core/include/ChanEvent.hpp b/Scan/utkscan/core/include/ChanEvent.hpp index af10983c7..55a9c0cda 100644 --- a/Scan/utkscan/core/include/ChanEvent.hpp +++ b/Scan/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 * diff --git a/Scan/utkscan/core/include/DetectorSummary.hpp b/Scan/utkscan/core/include/DetectorSummary.hpp index 438030e8a..bf1b125b3 100644 --- a/Scan/utkscan/core/include/DetectorSummary.hpp +++ b/Scan/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/Globals.hpp b/Scan/utkscan/core/include/Globals.hpp index e954e5b19..c86941e20 100644 --- a/Scan/utkscan/core/include/Globals.hpp +++ b/Scan/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 @@ -281,9 +278,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_; } @@ -341,7 +335,6 @@ class Globals { std::string outputPath_;//!< The path to additional configuration files std::string revision_;//!< the pixie revision - unsigned int maxWords_;//!< maximum words in the unsigned short numTraces_;//!< number of traces to plot std::vector > reject_;//!< rejection range in time diff --git a/Scan/utkscan/core/include/RawEvent.hpp b/Scan/utkscan/core/include/RawEvent.hpp index a17b14e35..e9ea26d82 100644 --- a/Scan/utkscan/core/include/RawEvent.hpp +++ b/Scan/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/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/core/source/Globals.cpp b/Scan/utkscan/core/source/Globals.cpp index 8d9b429b2..43fb00d07 100644 --- a/Scan/utkscan/core/source/Globals.cpp +++ b/Scan/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_); From 5569cbd297f9751d2cd9e2682e076291db36f9a5 Mon Sep 17 00:00:00 2001 From: ksmith0 Date: Wed, 7 Dec 2016 14:38:06 -0700 Subject: [PATCH 024/255] Changed poll2 reboot message. (#145) Changed reboot message from "... any key ..." to "... Enter key ...". This fixes #142. Former-commit-id: 8e51496248b048c173e19f81a65d3927d92b1fd5 --- Poll/source/poll2_core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 5569db7d0..1136c6948 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1547,7 +1547,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; } From 4fd26c4bb9525ba38f78363b806ab5d77e308b83 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 19 Oct 2016 14:49:55 -0500 Subject: [PATCH 025/255] Revised booting to inspect module type.(Multiconf) The pixie configuration file, pixie.cfg, can now handle an arbitrary number of module types. This is handled by the new tag ModuleType. The tags were split into two groups, module and global types. The global types include: * PixieBaseDir * CrateConfig * SlotFile * DspSetFile * DspWorkSetFile While the module type tags include: * ModuleType * ModuleBaseDir * SpFpgaFile * ComFpgaFile * DspConfFile * DspVarFile If the ModuleType tag is not found all module type files are assumed to be set for the "default" module type, once a ModuleType tag is found all subsequent files are assumed to be unique to that module type. For global type tags the PixieBaseDir is used. For module type tags the ModuleBaseDir is used first, followed by the PixieBaseDir. If no valid base directory is found the current working directory is used as the base. It is no longer required to indicate in the slot_def.set file which modules use the default and alternate configurations. The configuration is determined by polling the module for its type and using the configuration specified for that type. If no matching type was registered in the configuration an error message is produced. For system with a single type of modules if the module type was not found the "default" type is tried. Former-commit-id: 9ef7fbeb56e9c37c45a84b36f7edb23ccd92fd37 --- Interface/include/PixieInterface.h | 12 +- Interface/source/PixieInterface.cpp | 244 +++++++++++++++++++++------- 2 files changed, 189 insertions(+), 67 deletions(-) diff --git a/Interface/include/PixieInterface.h b/Interface/include/PixieInterface.h index 18637f491..860d7c4b0 100644 --- a/Interface/include/PixieInterface.h +++ b/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/source/PixieInterface.cpp b/Interface/source/PixieInterface.cpp index b81bba3b5..0deda423a 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Interface/source/PixieInterface.cpp @@ -96,28 +96,25 @@ 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)) { @@ -128,7 +125,7 @@ PixieInterface::PixieInterface(const char *fn) : hasAlternativeConfig(false), lo 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 +142,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 +214,11 @@ 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)) { + 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,9 +231,26 @@ 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: " << InfoStr(moduleType) << "\n"; + } //Store configuration - configStrings[tag] = ConfigFileName(value); + if (tag == "SpFpgaFile" || tag == "ComFpgaFile" || tag == "DspConfFile" || tag == "DspVarFile" || tag == "TrigFpgaFile" || tag == "ModuleBaseDir") { + if (moduleType == "") { + moduleType = "default"; + std::cout << "Module Type: " << InfoStr(moduleType) << "\n"; + } + std::cout << " " << tag << "\t" << value << endl; + configStrings[moduleType][tag] = ConfigFileName(moduleType,value); + } + else { + configStrings["global"][tag] = ConfigFileName("global",value); + } //Check if BaseDir is defined differently then in the environment if (tag == "PixieBaseDir") { @@ -194,7 +273,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 +292,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 +331,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("Boot Configuration"); - LeaderPrint("Booting Pixie"); + //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); - //Break the leader print for the Boot status. - if (mode == BootAll) std::cout << std::endl; + 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); } @@ -314,6 +421,7 @@ bool PixieInterface::Boot(int mode, bool useWorkingSetFile) bool hadError = false; bool updated = false; +/* word_t val; for (int i=0; i < numberCards; i++) { @@ -325,6 +433,7 @@ bool PixieInterface::Boot(int mode, bool useWorkingSetFile) hadError = true; } } +*/ if (hadError) cout << ErrorStr() << endl; else if (updated) @@ -446,7 +555,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 +933,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 +963,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); } From 73888f24c5827866f6d55cf7ccdca43793ef6c7c Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 19 Oct 2016 15:28:28 -0500 Subject: [PATCH 026/255] Updated FindPXI to allow user modification. When the user changes `PXI_ROOT_DIR` in the cache, nothing happens as the underlying `PXI_LIBRARY_DIR` is cached. Changed to force a new search at every cmake invocation. Also, require libPixie16Sys.a to be present in `PXI_LIBRARY_DIR`. Former-commit-id: b0d7765d9cb5b78c696fc262eb52c9b15e263ac7 --- cmake/modules/FindPXI.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index a847455fa..4ac84608e 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -6,14 +6,20 @@ # PXI_FOUND - true if PXI was found. # +#find the root directory by looking for the standard names. find_path(PXI_ROOT_DIR NAMES software firmware dsp configuration HINTS ENV PXI_ROOT PATHS /opt/xia/current DOC "Path to pixie firmware.") +#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 + NAMES libPixie16App.a libPixie16Sys.a HINTS ${PXI_ROOT_DIR}/software DOC "Path to pixie library.") From de94e10b30b3c798d7b06e770896e903c547b3bf Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 20 Oct 2016 16:31:24 -0500 Subject: [PATCH 027/255] Updated FindPXI module. The module now provides PXI_LIBRARY_DIR and PXI_FIRMWARE_DIR. PXI_LIBRARY_DIR specifies the location of the libraries needed for compilation. PXI_FIRMWARE_DIR specifies the directory where the firmware files can be found, typically /opt/xia/. PXI_CONFIG now search PXI_FIRMWARE_DIR for multiple firmwares for various module types and attempts to determine their type. This is then assembled into the pixie.cfg file written to share/config. Former-commit-id: 6bb56dc231d8dd395a53d2f078e70443359f6682 --- cmake/modules/FindPXI.cmake | 134 ++++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 27 deletions(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index 4ac84608e..8c3194b58 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -6,13 +6,6 @@ # PXI_FOUND - true if PXI was found. # -#find the root directory by looking for the standard names. -find_path(PXI_ROOT_DIR - NAMES software firmware dsp configuration - HINTS ENV PXI_ROOT - PATHS /opt/xia/current - DOC "Path to pixie firmware.") - #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) @@ -20,24 +13,32 @@ 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}/software + HINTS ${PXI_ROOT_DIR} + PATHS /opt/xia/current + PATH_SUFFIXES software DOC "Path to pixie library.") +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_ROOT_DIR PXI_LIBRARY_DIR) +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() -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") + + 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) @@ -45,34 +46,32 @@ function(PXI_CONFIG) "file(INSTALL pixie.cfg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/config)\n" ) + #Write the base directory + file(WRITE ${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 SpFpgaFile ComFpgaFile DspConfFile DspVarFile CrateConfig SlotFile DspSetFile) + set(CONFIG_NAME 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) + 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 hte expression + + #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 configuration! Unique ${KEY} file (${GLOB_EXPR}) not found!") + message(STATUS "WARNING: Unable to autocomplete configuration!\n\tUnique ${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") + "# Multiple / zero options found! Choose below and remove this comment.\n") endif() if (${KEY} MATCHES "SlotFile") @@ -97,11 +96,92 @@ function(PXI_CONFIG) 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() + endforeach(CONFIG_STEP RANGE 0 2) #Added the working set file name - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "DspWorkingSetFile\t./current.set") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "DspWorkingSetFile\t./current.set\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}) + + #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 (NOT MODULE_TYPE) + set(MODULE_TYPE "${TYPE}-${REVISION}") + else (NOT MODULE_TYPE) + if(NOT MODULE_TYPE EQUAL "${TYPE}-${REVISION}") + list(APPEND MODULE_TYPE "${TYPE}-${REVISION}") + endif(NOT MODULE_TYPE EQUAL "${TYPE}-${REVISION}") + endif (NOT MODULE_TYPE) + endforeach(FILENAME ${FILE_MATCHES}) + + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "\n") + + list(LENGTH MODULE_TYPE NUM_MATCHES) + if (NOT NUM_MATCHES EQUAL 1) + message(STATUS "WARNING: Multiple module types found in ${FIRMWARE_DIR}") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "# Multiple / zero options found! Choose below and remove this comment.\n") + endif() + + 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) + message(STATUS "WARNING: Unable to autocomplete configuration!\n\tUnique ${KEY} file (${GLOB_EXPR}) not found!") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg + "# Multiple / zero options found! Choose below and remove this comment.\n") + 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) + From d14b78958255785a1381065efcaef3b66863d1c8 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 10:04:56 -0500 Subject: [PATCH 028/255] Added multiple ModuleType warning and ignore. Any modules types listed same as a previous one will be ignored. Former-commit-id: 76b4a97c818caa607a1048a5275a22cd5b9f81f9 --- Interface/source/PixieInterface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Interface/source/PixieInterface.cpp b/Interface/source/PixieInterface.cpp index 0deda423a..65de71e97 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Interface/source/PixieInterface.cpp @@ -237,6 +237,12 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) if (tag == "ModuleType") { moduleType = ParseModuleTypeTag(value); std::cout << "Module Type: " << InfoStr(moduleType) << "\n"; + + //If we have two multiple entires for one type we use only the first. + if (configStrings.find(moduleType) != configStrings.end()) { + std::cout << WarningStr() << " Duplicate module type information will be ignored. (" << moduleType << ")\n"; + moduleType = "ignored_" + moduleType; + } } //Store configuration From d174183d83eba1467b31701c6de48a0784cbd8b7 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 10:05:37 -0500 Subject: [PATCH 029/255] Updated FindPXI to look in /opt/xia/software Since the firmware is searched separately from the software it is no longer necessary to create the /opt/xia/current link. Instead /opt/xia/software can be created. Both are supported. Former-commit-id: 2e04cff43a8243d6fa329064147487da7e4311a6 --- cmake/modules/FindPXI.cmake | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index 8c3194b58..fbe95f6f1 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -14,10 +14,12 @@ unset(PXI_LIBRARY_DIR CACHE) find_path(PXI_LIBRARY_DIR NAMES libPixie16App.a libPixie16Sys.a HINTS ${PXI_ROOT_DIR} - PATHS /opt/xia/current + 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) @@ -69,7 +71,7 @@ function(PXI_CONFIG) #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!\n\tUnique ${KEY} file (${GLOB_EXPR}) not found!") + message(STATUS "WARNING: Unable to autocomplete global configuration!\n\tUnique ${KEY} file (${GLOB_EXPR}) not found!") file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "# Multiple / zero options found! Choose below and remove this comment.\n") endif() @@ -111,6 +113,13 @@ function(PXI_CONFIG) 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 @@ -145,6 +154,8 @@ function(PXI_CONFIG) "# Multiple / zero options found! Choose below and remove this comment.\n") endif() + message(STATUS "Autoconfiguring module type: ${MODULE_TYPE}.") + 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") @@ -161,7 +172,8 @@ function(PXI_CONFIG) #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!\n\tUnique ${KEY} file (${GLOB_EXPR}) not found!") + message(STATUS "WARNING: Unable to autocomplete ${MODULE_TYPE} configuration!") + message(STATUS "\tUnique ${KEY} file (${GLOB_EXPR}) not found!") file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "# Multiple / zero options found! Choose below and remove this comment.\n") endif() From 1a0a0b5bdf0d05b91009ae3f22bdb857e4861e9f Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 10:23:17 -0500 Subject: [PATCH 030/255] FindPXI PXI_CONFIG for revd RevD modules are all 12b100m and the firmware file may not list this information. If we find revd we can guess and put this information in the config file. Former-commit-id: ea937e5b65d353559eb7bd43ed82b8c609ef620c --- cmake/modules/FindPXI.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index fbe95f6f1..1f4383f73 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -136,6 +136,10 @@ function(PXI_CONFIG) 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 can add it for revd as they should all be 12b100m + if (${REVISION} STREQUAL "revd" AND "${TYPE}" STREQUAL "") + set(TYPE "12b100m") + endif() if (NOT MODULE_TYPE) set(MODULE_TYPE "${TYPE}-${REVISION}") else (NOT MODULE_TYPE) From 8d16fb5073139f2c240620b258b13637a9da6f89 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 16:14:24 -0500 Subject: [PATCH 031/255] Changed PXI_CONFIG for revd modules The type is now set the to "unknown" if the bit resultion and adc rate can not be determined. Former-commit-id: 5501718c2030b04728ff43d625f4e65cf078dceb --- cmake/modules/FindPXI.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index 1f4383f73..d59a083ff 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -136,9 +136,9 @@ function(PXI_CONFIG) 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 can add it for revd as they should all be 12b100m - if (${REVISION} STREQUAL "revd" AND "${TYPE}" STREQUAL "") - set(TYPE "12b100m") + #If type is missing we set it to "unknown" + if ("${TYPE}" STREQUAL "") + set(TYPE "unknown") endif() if (NOT MODULE_TYPE) set(MODULE_TYPE "${TYPE}-${REVISION}") From 9323b9931b3b9922be3c92c7d791ac37cf828102 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 16:16:21 -0500 Subject: [PATCH 032/255] Removed comment around PixieInterface::Boot The slot set portion was commented out. This led to slot read errors. Former-commit-id: 0de3c4c76ba6e99c525b879c45754550715bef43 --- Interface/source/PixieInterface.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Interface/source/PixieInterface.cpp b/Interface/source/PixieInterface.cpp index 65de71e97..ef279fc78 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Interface/source/PixieInterface.cpp @@ -427,7 +427,6 @@ bool PixieInterface::Boot(int mode, bool useWorkingSetFile) bool hadError = false; bool updated = false; -/* word_t val; for (int i=0; i < numberCards; i++) { @@ -439,7 +438,7 @@ bool PixieInterface::Boot(int mode, bool useWorkingSetFile) hadError = true; } } -*/ + if (hadError) cout << ErrorStr() << endl; else if (updated) From 34fc4d5ae4a184d9354edaba97f5db8217a86035 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 21 Oct 2016 16:17:21 -0500 Subject: [PATCH 033/255] Updated PrintModuleInfo. Added padding to make the output more pleasant. Former-commit-id: b49da9a5010106a1ed70549be3c8470f22d79528 --- Poll/source/poll2_core.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 1136c6948..798b32a01 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -233,8 +233,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 " << From 66d2871d6f423e65940ea694711241592a148c04 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 7 Dec 2016 16:31:10 -0600 Subject: [PATCH 034/255] Amended pixie.cfg error messages. It was request that the error messages be more clear. Revised both the messages at the cmake level during autoconfiguring and those placed in pixie.cfg. Former-commit-id: 0f7a58eb660f09e6067022e70eb8a0971209c079 --- cmake/modules/FindPXI.cmake | 69 ++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index d59a083ff..7f28c44f7 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -72,8 +72,13 @@ function(PXI_CONFIG) 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!") - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg - "# Multiple / zero options found! Choose below and remove this comment.\n") + 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") @@ -140,26 +145,42 @@ function(PXI_CONFIG) if ("${TYPE}" STREQUAL "") set(TYPE "unknown") endif() - if (NOT MODULE_TYPE) - set(MODULE_TYPE "${TYPE}-${REVISION}") - else (NOT MODULE_TYPE) - if(NOT MODULE_TYPE EQUAL "${TYPE}-${REVISION}") - list(APPEND MODULE_TYPE "${TYPE}-${REVISION}") - endif(NOT MODULE_TYPE EQUAL "${TYPE}-${REVISION}") - endif (NOT MODULE_TYPE) + + #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") - list(LENGTH MODULE_TYPE NUM_MATCHES) - if (NOT NUM_MATCHES EQUAL 1) - message(STATUS "WARNING: Multiple module types found in ${FIRMWARE_DIR}") - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg - "# Multiple / zero options found! Choose below and remove this comment.\n") - endif() - 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(" ${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(" ${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") @@ -176,10 +197,18 @@ function(PXI_CONFIG) #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 ${MODULE_TYPE} configuration!") - message(STATUS "\tUnique ${KEY} file (${GLOB_EXPR}) not found!") - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg - "# Multiple / zero options found! Choose below and remove this comment.\n") + if (NOT ERROR) + set(ERROR TRUE) + message(STATUS "WARNING: Unable to autocomplete ${MODULE_TYPE} configuration!") + endif (NOT ERROR) + message(" 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 From 96d00b0aac57bc07d7f82bb4bb2f63827406b915 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 7 Dec 2016 18:41:33 -0600 Subject: [PATCH 035/255] Added pixie.cfg readme block. Added some information about how the pixie.cfg file works. Former-commit-id: 47d5dcc3d087100fb67f2b4a038933849fe54dc1 --- cmake/modules/FindPXI.cmake | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/cmake/modules/FindPXI.cmake b/cmake/modules/FindPXI.cmake index 7f28c44f7..9121132c7 100644 --- a/cmake/modules/FindPXI.cmake +++ b/cmake/modules/FindPXI.cmake @@ -48,8 +48,32 @@ function(PXI_CONFIG) "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(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "PixieBaseDir\t\t${PXI_ROOT_DIR}\n") + 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) @@ -111,6 +135,8 @@ function(PXI_CONFIG) #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}") From 8ea8e4846903165aa6e0de4191eadb562d8e5bcd Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 7 Dec 2016 19:23:23 -0600 Subject: [PATCH 036/255] Updated Configuration File Parse to be more strict. The configuration file (pixie.cfg) parsing now requires that only one set of parameters per module type are specified, duplicates are not allowed. This includes duplicate ModuleTypes as well as module specific tags. Duplicate tags are highlighted in red. Changed the verbosity of the messages to include information about the global tags that were specified. Former-commit-id: 90b071496403c9b5cfb0f687c917b9126f8583dc --- Interface/source/PixieInterface.cpp | 49 ++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/Interface/source/PixieInterface.cpp b/Interface/source/PixieInterface.cpp index ef279fc78..366585901 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Interface/source/PixieInterface.cpp @@ -118,10 +118,11 @@ PixieInterface::PixieInterface(const char *fn) : lock("PixieInterface") 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. @@ -217,6 +218,7 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) std::cout << "Reading Pixie Configuration\n"; //Loop over lines in config file + bool error = false; string moduleType = ""; while (std::getline(in,line)) { //Get a string stream of current line @@ -235,32 +237,53 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) //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: " << InfoStr(moduleType) << "\n"; - //If we have two multiple entires for one type we use only the first. + std::cout << "Module Type: "; + + //If we have multiple entires for one type we throw and error. if (configStrings.find(moduleType) != configStrings.end()) { - std::cout << WarningStr() << " Duplicate module type information will be ignored. (" << moduleType << ")\n"; + 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";} } //Store configuration - if (tag == "SpFpgaFile" || tag == "ComFpgaFile" || tag == "DspConfFile" || tag == "DspVarFile" || tag == "TrigFpgaFile" || tag == "ModuleBaseDir") { + 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"; } - std::cout << " " << tag << "\t" << value << endl; - configStrings[moduleType][tag] = ConfigFileName(moduleType,value); + 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 { - configStrings["global"][tag] = ConfigFileName("global",value); + 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")) ) { @@ -271,6 +294,8 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) } } + if (error) return false; + return true; } From 9ba571dacc8896f526a6394aa13ddb35ef4ae147 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Wed, 7 Dec 2016 19:36:42 -0600 Subject: [PATCH 037/255] Adjusted Read Configuration to list Base Dir. If the ModuleBaseDir is not specified before another module tag the PixieBaseDir tag and value are printed again to make it clear where the configuration will search for the associated module files. Former-commit-id: 886dd633179041f831b136cb8fb445a015b469c8 --- Interface/source/PixieInterface.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Interface/source/PixieInterface.cpp b/Interface/source/PixieInterface.cpp index 366585901..e5924bd7e 100644 --- a/Interface/source/PixieInterface.cpp +++ b/Interface/source/PixieInterface.cpp @@ -219,6 +219,7 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) //Loop over lines in config file bool error = false; + bool newModule = false; string moduleType = ""; while (std::getline(in,line)) { //Get a string stream of current line @@ -254,6 +255,8 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) moduleType = "ignored_" + moduleType; } else {std::cout << InfoStr(moduleType) << "\n";} + + newModule = true; } //Store configuration @@ -262,6 +265,10 @@ bool PixieInterface::ReadConfigurationFile(const char *fn) 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; From 86c3aa3ca73b0ae869128e6841897e33398548e4 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 20:41:05 -0600 Subject: [PATCH 038/255] Corrected mod-chan range '-1' issue. If the module or channel was specified as -1, an error was thrown. Extended the allowed characters to include the minus sign. In addition, added some error checking to not permit negative numbers when ranges are specifed and the start value is required to be less than the stop value. Former-commit-id: f6f7331a51fbf1e228a92b5ac32c94db9860ad32 --- Poll/source/poll2_core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 798b32a01..191859644 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -837,7 +837,7 @@ void Poll::get_traces(int mod_, int chan_, int thresh_/*=0*/){ /// 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; + if (arg.find_first_not_of("-0123456789:") != std::string::npos) return false; size_t delimeterPos = arg.find(':'); try { @@ -845,6 +845,7 @@ bool Poll::SplitParameterArgs(const std::string &arg, int &start, int &stop) { //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; } From c09200759bd8769291e58a521a6c8c9e065b94ee Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 20:54:47 -0600 Subject: [PATCH 039/255] Added ranges to pmread / pmwrite & hex capability. Copied functionality for module ranges from pread / pwrite to pmread / pmwrite. Using stod for the values in pmwrite even though only unsigned int is allowed. This permits the use of hex values with a simple cast to unsigned int. Invalid unsigned arguments are caught by looking for decimal point and negative sign. Former-commit-id: da2b5b9877bb4fa7d01c088e71541965ad019aef --- Poll/source/poll2_core.cpp | 51 ++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 191859644..a65a6967f 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1091,14 +1091,14 @@ void Poll::CommandControl(){ ParameterChannelWriter writer; bool error = false; - for (int mod = modStart; mod <= modStop; mod++) { - for (int ch = chStart; ch <= chStop; ch++) { + 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(); + if (!error) pif->SaveDSPParameters(); } else{ std::cout << sys_message_head << "Invalid number of parameters to pwrite\n"; @@ -1108,13 +1108,36 @@ 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(); } + for (int mod = modStart; mod <= modStop; mod++) { + if(forModule(pif, mod, writer, make_pair(arguments.at(1), value))){ + pif->SaveDSPParameters(); + } + } } else{ std::cout << sys_message_head << "Invalid number of parameters to pmwrite\n"; @@ -1157,11 +1180,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"; @@ -2017,3 +2045,4 @@ std::string yesno(bool value_){ if(value_){ return "Yes"; } return "No"; } + From 65cde663b50213adbe22eaff5bb9f90fdd73106c Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 21:00:29 -0600 Subject: [PATCH 040/255] Added ranges to adjust_offsets. Added ranges to adjust_offsets using the same functionality as with p(m)read / p(m)write. Former-commit-id: ce2965d4febfe1f988b877e950ac052f51e148e8 --- Poll/source/poll2_core.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index a65a6967f..823cd05e8 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1204,11 +1204,16 @@ 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(); } + for (int mod = modStart; mod <= modStop; mod++) { + if(forModule(pif, mod, adjuster, 0)){ pif->SaveDSPParameters(); } + } } else{ std::cout << sys_message_head << "Invalid number of parameters to adjust_offsets\n"; From fdb8604274b451c7fbe4f3c4f93a1b8d3a64b177 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 21:09:30 -0600 Subject: [PATCH 041/255] Added ranges to toggle. Added functionality similar to pread / pwrite. This addresses the request in issue #139. Former-commit-id: 8e06e49a8b5eafd9920c55de529e863fe78d1ae9 --- Poll/source/poll2_core.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 823cd05e8..b4fab9e64 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1249,14 +1249,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"; From 66ff008b2b0a95d4a2e10b54ef19f5a23e43124a Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 21:16:12 -0600 Subject: [PATCH 042/255] Changed pmwrite / adjust_offsets DSP write. The DSP setting were being written afte each module. Changed this to only write after all modules had been adjusted. Former-commit-id: 2484b610670d9e8ec58f0c0b05066ad8dac87562 --- Poll/source/poll2_core.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index b4fab9e64..883f70336 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1133,11 +1133,13 @@ void Poll::CommandControl(){ } ParameterModuleWriter writer; + bool error = false; for (int mod = modStart; mod <= modStop; mod++) { - if(forModule(pif, mod, writer, make_pair(arguments.at(1), value))){ - pif->SaveDSPParameters(); + 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"; @@ -1211,9 +1213,11 @@ void Poll::CommandControl(){ } OffsetAdjuster adjuster; + bool error = false; for (int mod = modStart; mod <= modStop; mod++) { - if(forModule(pif, mod, adjuster, 0)){ pif->SaveDSPParameters(); } + 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"; From d18134f28ce1522f6568a7afc32ad4fe261007f8 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Thu, 8 Dec 2016 21:22:35 -0600 Subject: [PATCH 043/255] Added hex capability to csr_test. Using method from pmwrite to check and convert input value. Former-commit-id: d9b10fbe6646e471bb1d171c1e6271204761378c --- Poll/source/poll2_core.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Poll/source/poll2_core.cpp b/Poll/source/poll2_core.cpp index 883f70336..4ac8cd7fc 100644 --- a/Poll/source/poll2_core.cpp +++ b/Poll/source/poll2_core.cpp @@ -1308,8 +1308,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"; From 5ff0d37b4bf161897cfe15a905032b4cd30a200b Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Mon, 12 Dec 2016 16:54:42 -0600 Subject: [PATCH 044/255] Updated CTerminalTest to display TERM. The CTerminalTest program now displays the TERM environment variable when starting. Also, changed to static library linkage. Former-commit-id: f089308f972d1b923c08ba143ab900e99a11d015 --- Core/tests/CMakeLists.txt | 2 +- Core/tests/CTerminalTest.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/tests/CMakeLists.txt b/Core/tests/CMakeLists.txt index 60b5258cc..aecb8d9f0 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 PixieCoreStatic) 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> "); From b45873e6a4a070e88e95151c489ab0954f1b4908 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Mon, 19 Dec 2016 12:18:41 -0500 Subject: [PATCH 045/255] Abstracted ROOT canvas from scope to RootScanner. The ROOT canvas and zoom functionality has been moved to RootScanner class and scope now inherits from this class. Former-commit-id: 76a4c9a8bc7345133aba7a10ca17615a9936c96f --- Scan/ScanLib/include/RootScanner.hpp | 35 +++++ Scan/ScanLib/source/CMakeLists.txt | 2 +- Scan/ScanLib/source/RootScanner.cpp | 189 +++++++++++++++++++++++++++ Scan/util/include/scope.hpp | 18 +-- Scan/util/source/scope.cpp | 132 +++++-------------- 5 files changed, 264 insertions(+), 112 deletions(-) create mode 100644 Scan/ScanLib/include/RootScanner.hpp create mode 100644 Scan/ScanLib/source/RootScanner.cpp diff --git a/Scan/ScanLib/include/RootScanner.hpp b/Scan/ScanLib/include/RootScanner.hpp new file mode 100644 index 000000000..0e8ea8b2a --- /dev/null +++ b/Scan/ScanLib/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 constexpr 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/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt index 7b75349b2..f86d78fcf 100644 --- a/Scan/ScanLib/source/CMakeLists.txt +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -1,5 +1,5 @@ #Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp) +set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp RootScanner.cpp) #Add the sources to the library add_library(ScanObjects OBJECT ${ScanSources}) diff --git a/Scan/ScanLib/source/RootScanner.cpp b/Scan/ScanLib/source/RootScanner.cpp new file mode 100644 index 000000000..2be64fdee --- /dev/null +++ b/Scan/ScanLib/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/util/include/scope.hpp b/Scan/util/include/scope.hpp index d4144a79e..112c11174 100644 --- a/Scan/util/include/scope.hpp +++ b/Scan/util/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,8 +213,6 @@ 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; diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index a6207a858..919036d0f 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -1,5 +1,5 @@ -#include #include +#include // PixieCore libraries #include "XiaData.hpp" @@ -14,11 +14,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,7 +86,7 @@ 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(); @@ -123,7 +121,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,12 +141,6 @@ 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(); @@ -169,8 +161,6 @@ scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : ScanInterface() { /// Destructor. scopeScanner::~scopeScanner(){ - canvas->Close(); - delete canvas; delete graph; delete cfdGraph; delete cfdLine; @@ -212,37 +202,21 @@ 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. @@ -253,23 +227,7 @@ void scopeScanner::Plot(){ 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"); @@ -283,7 +241,7 @@ void scopeScanner::Plot(){ // 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); - cfdLine->DrawLine(cfdCrossing*ADC_TIME_STEP, userZoomVals[1][0], cfdCrossing*ADC_TIME_STEP, userZoomVals[1][1]); + cfdLine->DrawLine(cfdCrossing*ADC_TIME_STEP, GetCanvas()->GetUymin(), cfdCrossing*ADC_TIME_STEP, GetCanvas()->GetUymax()); cfdGraph->Draw("LSAME"); } @@ -302,23 +260,15 @@ void scopeScanner::Plot(){ float evtMax = *std::max_element(evt->event->adcTrace.begin(), evt->event->adcTrace.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++) { @@ -346,10 +296,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 +313,7 @@ void scopeScanner::Plot(){ } // Update the canvas. - canvas->Update(); + GetCanvas()->Update(); // Save the TGraph to a file. if (saveFile_ != "") { @@ -580,7 +529,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 +604,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 +622,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 +648,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 + From 2b793ef28b62829f309da4e9980c0afb685a6d01 Mon Sep 17 00:00:00 2001 From: Thomas King Date: Tue, 13 Dec 2016 16:17:28 -0500 Subject: [PATCH 046/255] Update to gitIgnore to exclude doxywarning.txt Former-commit-id: 3a73cbb5085e2c4e09f85a28d36a894dfd0b8348 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b1c83d318..45aea2368 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ build/ *-build-*/ install/ doc/ +doxywarning.txt #Ignore IDE files *.cbp From be7e21feed1574e9d9005f260ce97d81e3717857 Mon Sep 17 00:00:00 2001 From: Thomas King Date: Wed, 14 Dec 2016 10:17:30 -0500 Subject: [PATCH 047/255] Added doxywarning.txt/ Changed doc/doxyfile the doxywarning.txt does not need to be tracked. Updated the doc/doxyfile to not generate documentation for files under paass/install/. This fixes a large number of the errors logged in doxywarning.txt. Former-commit-id: bec861e6b54cd7fac5ee4810b97fcf53be046f9d --- .gitignore | 5 +++-- doc/doxyfile | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 45aea2368..fd510478b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ latex/ tmp/ doc/classdiagramRawEvent.svg ValgrindOut.xml +doc/ +doxywarning.txt #Compressed Files *.bz2 @@ -25,8 +27,7 @@ ValgrindOut.xml build/ *-build-*/ install/ -doc/ -doxywarning.txt + #Ignore IDE files *.cbp diff --git a/doc/doxyfile b/doc/doxyfile index 261d73dcc..ea65c824c 100644 --- a/doc/doxyfile +++ b/doc/doxyfile @@ -832,7 +832,8 @@ 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 = */EventDict/* \ + */install/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the From fafdb822183af272d8df2fe2c8f1686febbce29c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 14 Dec 2016 20:44:04 -0500 Subject: [PATCH 048/255] Fixing doxygen build I fixed the doxygen build so that it will actually build the documentation that we want. The side effect of this is that we automatically exclude the install and build directories. Former-commit-id: c91d3c36b61a0e6113952cd582b3b367f09ea6b3 --- doc/doxyfile | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/doxyfile b/doc/doxyfile index ea65c824c..df37b8156 100644 --- a/doc/doxyfile +++ b/doc/doxyfile @@ -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 = ./Core cmake doc/pages/ Interface MCA Poll \ + PxiDump Scan Setup # 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,11 @@ 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 \ +EXCLUDE = Scan/utkscan/core/include/pugiconfig.hpp \ + Scan/utkscan/core/include/pugixml.hpp \ + Scan/utkscan/core/source/pugixml.cpp \ Scan/utkscan/include/MersenneTwister.hpp \ - Scan/utkscan/src/core/pugixml.cpp \ README.md \ - Scan/utkscan/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,8 +832,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/* \ - */install/* +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 From 438833c1ec8b205aff1563266c83432670a8c4ae Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 22 Nov 2016 20:43:37 -0500 Subject: [PATCH 049/255] Removing list of known detectors. This concept is antiquated, and we do not need the restriction since we have the experiment specific processors that can link into any of the known types. We still need to ensure that people are calling things by the right name for the subprocessors, but we'll have to think of a better way. Former-commit-id: cb6dc888761c63ac1b40370419fc87438875b24e --- Scan/utkscan/core/source/DetectorLibrary.cpp | 39 +------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorLibrary.cpp b/Scan/utkscan/core/source/DetectorLibrary.cpp index facd3262f..927ec424d 100644 --- a/Scan/utkscan/core/source/DetectorLibrary.cpp +++ b/Scan/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; } From 26874f79467607aaf589798936a97b0cbf70731d Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Mon, 21 Nov 2016 17:51:29 -0500 Subject: [PATCH 050/255] Added new cfd algorithm Former-commit-id: ea2e00051448bd7015e2b62dd1b1b189237822de --- Scan/ScanLib/include/XiaData.hpp | 26 +++-- Scan/ScanLib/source/XiaData.cpp | 169 +++++++++++++++++++++++++------ Scan/util/source/scope.cpp | 3 +- 3 files changed, 159 insertions(+), 39 deletions(-) diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index 9158240c3..ea9f5dba4 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -51,7 +51,7 @@ class XiaData{ virtual ~XiaData(); /// Get the event ID number (mod * chan). - unsigned int getID(){ return(modNum*16+chanNum); } + int getID(){ return(modNum*16+chanNum); } /// Reserve specified number of bins for the channel trace. void reserve(const size_t &size_); @@ -108,8 +108,11 @@ class ChannelEvent{ /// Destructor. ~ChannelEvent(); + + /// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. + float ComputeBaseline(); - /// Correct the trace baseline, baseline standard deviation, and find the pulse maximum. + /// Correct the trace baseline. float CorrectBaseline(); /// Find the leading edge of the pulse at a given percentage of pulse maximum. @@ -117,15 +120,26 @@ class ChannelEvent{ /// 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); + + /// Perform CFD analysis on the waveform using the XIA algorithm. + float AnalyzeXiaCFD(const float &F_=0.5, const size_t &D_=1, const size_t &L_=1); + + /// Perform CFD analysis on the waveform using the pol3 + pol2 algorithm. + float AnalyzeCFD(const float &F_=0.5); /// Clear all variables and clear the trace vector and arrays. void Clear(); }; +void calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2); + +float calculateP2(const short &x0, const std::vector &trace, float &Xmax); + +void calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3); + +float calculateP3(const short &x0, const std::vector &trace, float &Xmax); + #endif diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index c3f79323f..159422198 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -112,34 +112,56 @@ ChannelEvent::~ChannelEvent(){ if(yvals){ delete[] yvals; } } -float ChannelEvent::CorrectBaseline(){ - if(!event || size == 0){ return -9999; } - else if(baseline_corrected){ return maximum; } +/// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. +float ChannelEvent::ComputeBaseline(){ + if(size == 0){ return -9999; } + if(baseline > 0){ return baseline; } - // Find the baseline + // Find the baseline. baseline = 0.0; - size_t sample_size = (10 <= size ? 10:size); + size_t sample_size = (15 <= size ? 15:size); for(size_t i = 0; i < sample_size; i++){ - baseline += (float)event->adcTrace[i]; + baseline += event->adcTrace[i]; } - baseline = baseline/sample_size; + baseline = float(baseline)/sample_size; - // Calculate the standard deviation + // 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 += (event->adcTrace[i] - baseline)*(event->adcTrace[i] - baseline); } stddev = std::sqrt((1.0/sample_size) * stddev); - // Find the maximum value, the maximum bin, and correct the baseline + // Find the maximum value and the maximum bin. maximum = -9999.0; + for(size_t i = 0; i < size; i++){ + if(event->adcTrace[i]-baseline > maximum){ + maximum = event->adcTrace[i]-baseline; + max_index = i; + } + } + + // Find the pulse maximum by fitting with a third order polynomial. + float realMax; + if(event->adcTrace[max_index-1] >= event->adcTrace[max_index+1]) // Favor the left side of the pulse. + maximum = calculateP3(max_index-2, event->adcTrace, realMax) - baseline; + else // Favor the right side of the pulse. + maximum = calculateP3(max_index-1, event->adcTrace, realMax) - baseline; + + return baseline; +} + +float ChannelEvent::CorrectBaseline(){ + if(!event || size == 0){ return -9999; } + else if(baseline_corrected){ return maximum; } + + // Calculate the baseline. + this->ComputeBaseline(); + + // Find the maximum value, the maximum bin, and correct the baseline 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; @@ -182,34 +204,23 @@ float ChannelEvent::IntegratePulse(const size_t &start_/*=0*/, const size_t &sto 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; +float ChannelEvent::AnalyzeXiaCFD(const float &F_/*=0.5*/, const size_t &D_/*=1*/, const size_t &L_/*=1*/){ + if(size == 0 || baseline < 0){ return -9999; } + if(!cfdvals) cfdvals = new float[size]; - } float cfdMinimum = 9999; size_t cfdMinIndex = 0; - cfdCrossing = -9999; + 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_ * yvals[cfdIndex - i] - yvals[cfdIndex - i - D_]; + cfdvals[cfdIndex] += F_ * (event->adcTrace[cfdIndex - i]-baseline) - (event->adcTrace[cfdIndex - i - D_]-baseline); } if(cfdvals[cfdIndex] < cfdMinimum){ cfdMinimum = cfdvals[cfdIndex]; @@ -222,13 +233,45 @@ float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/, const size_t &D_/*=1*/, // 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]); + phase = cfdIndex - cfdvals[cfdIndex]/(cfdvals[cfdIndex+1]-cfdvals[cfdIndex]); break; } } } - return cfdCrossing; + return phase; +} + +/// Perform CFD analysis on the waveform. +float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/){ + if(size == 0 || baseline < 0){ return -9999; } + + float threshold = F_*maximum + baseline; + + phase = -9999; + for(size_t cfdIndex = max_index; cfdIndex > 0; cfdIndex--){ + if(event->adcTrace[cfdIndex-1] < threshold && event->adcTrace[cfdIndex] >= threshold){ + float p0, p1, p2; + + // Fit the rise of the trace to a 2nd order polynomial. + calculateP2(cfdIndex-1, event->adcTrace, p0, p1, p2); + + // Calculate the phase of the trace. + phase = (-p1+std::sqrt(p1*p1 - 4*p2*(p0 - threshold)))/(2*p2); + + break; + } + } + + return phase; +} + +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; } void ChannelEvent::Clear(){ @@ -258,3 +301,65 @@ void ChannelEvent::Clear(){ yvals = NULL; cfdvals = NULL; } + +void calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2){ + float x1[3], x2[3]; + for(size_t i = 0; i < 3; i++){ + x1[i] = (x0+i); + x2[i] = std::pow(x0+i, 2); + } + + // messy + const int *y = &trace.data()[x0]; + + float denom = 1*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*x1[2]-x1[1]*1); + + p0 = (y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom; + p1 = (1*(y[1]*x2[2]-x2[1]*y[2]) - y[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*y[2]-y[1]*1))/denom; + p2 = (1*(x1[1]*y[2]-y[1]*x1[2]) - x1[0]*(1*y[2]-y[1]*1) + y[0]*(1*x1[2]-x1[1]*1))/denom; +} + +float calculateP2(const short &x0, const std::vector &trace, float &Xmax){ + float p0, p1, p2; + calculateP2(x0, trace, p0, p1, p2); + + // Calculate the maximum of the polynomial. + Xmax = -p1/(2*p2); + return (p0 + p1*Xmax + p2*Xmax*Xmax); +} + +void calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3){ + float x1[4], x2[4], x3[4]; + for(size_t i = 0; i < 4; i++){ + x1[i] = (x0+i); + x2[i] = std::pow(x0+i, 2); + x3[i] = std::pow(x0+i, 3); + } + + // messy + const int *y = &trace.data()[x0]; + + float denom = 1*(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]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])); + + p0 = (y[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])) - x1[0]*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(y[1]*(x1[2]*x3[3]-x1[3]*x3[2]) - y[2]*(x1[1]*x3[3]-x1[3]*x3[1]) + y[3]*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(y[1]*(x1[2]*x2[3]-x1[3]*x2[2]) - y[2]*(x1[1]*x2[3]-x1[3]*x2[1]) + y[3]*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; + p1 = (1*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - y[0]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) - x3[0]*(1*(y[2]*x2[3]-y[3]*x2[2]) - 1*(y[1]*x2[3]-y[3]*x2[1]) + 1*(y[1]*x2[2]-y[2]*x2[1])))/denom; + p2 = (1*(x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - x1[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) + y[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])))/denom; + p3 = (1*(x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - x1[0]*(1*(x2[2]*y[3]-x2[3]*y[2]) - 1*(x2[1]*y[3]-x2[3]*y[1]) + 1*(x2[1]*y[2]-x2[2]*y[1])) + x2[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])) - y[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; +} + +float calculateP3(const short &x0, const std::vector &trace, float &Xmax){ + float p0, p1, p2, p3; + calculateP3(x0, trace, p0, p1, p2, p3); + + // Calculate the maximum of the polynomial. + float xmax1 = (-2*p2+std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); + float xmax2 = (-2*p2-std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); + + if((2*p2+6*p3*xmax1) < 0){ // The second derivative is negative (i.e. this is a maximum). + Xmax = xmax1; + return (p0 + p1*xmax1 + p2*xmax1*xmax1 + p3*xmax1*xmax1*xmax1); + } + + Xmax = xmax2; + return (p0 + p1*xmax2 + p2*xmax2*xmax2 + p3*xmax2*xmax2*xmax2); +} diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index 919036d0f..580f831ef 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -236,7 +236,8 @@ void scopeScanner::Plot(){ if(performCfd_){ // Find the zero-crossing of the cfd waveform. - float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_, cfdD_, cfdL_); + //float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_, cfdD_, cfdL_); + float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_); // Draw the cfd waveform. for(size_t cfdIndex = 0; cfdIndex < chanEvents_.front()->size; cfdIndex++) From a13ffbc8ab2dc36997e6e795b50e19dba17ab382 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Mon, 21 Nov 2016 18:07:59 -0500 Subject: [PATCH 051/255] Removed ChannelEvent::CorrectBaseline() Former-commit-id: 79ac7f735179e389bfcd8efcc197590050d4a2b3 --- Scan/ScanLib/include/XiaData.hpp | 8 +----- Scan/ScanLib/source/XiaData.cpp | 48 ++++++-------------------------- Scan/util/source/scope.cpp | 3 +- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index ea9f5dba4..f0ee4a5c4 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -81,9 +81,7 @@ class ChannelEvent{ 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. @@ -95,7 +93,6 @@ class ChannelEvent{ 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. @@ -112,9 +109,6 @@ class ChannelEvent{ /// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. float ComputeBaseline(); - /// Correct the trace baseline. - float CorrectBaseline(); - /// Find the leading edge of the pulse at a given percentage of pulse maximum. float FindLeadingEdge(const float &thresh_=0.05); diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 159422198..3eb008f4e 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -85,8 +85,6 @@ void XiaData::clear(){ /// Default constructor. ChannelEvent::ChannelEvent(){ event = NULL; - xvals = NULL; - yvals = NULL; cfdvals = NULL; Clear(); } @@ -94,22 +92,15 @@ ChannelEvent::ChannelEvent(){ /// 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; } + if(cfdvals){ delete[] cfdvals; } } /// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. @@ -151,40 +142,22 @@ float ChannelEvent::ComputeBaseline(){ return baseline; } -float ChannelEvent::CorrectBaseline(){ - if(!event || size == 0){ return -9999; } - else if(baseline_corrected){ return maximum; } - - // Calculate the baseline. - this->ComputeBaseline(); - - // Find the maximum value, the maximum bin, and correct the baseline - for(size_t i = 0; i < event->adcTrace.size(); i++){ - xvals[i] = i; - yvals[i] = event->adcTrace[i]-baseline; - } - - baseline_corrected = true; - - return maximum; -} - float ChannelEvent::FindLeadingEdge(const float &thresh_/*=0.05*/){ - if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } + if(!event || ComputeBaseline() < 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){ + if(event->adcTrace[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]))); } + // y1 = event->adcTrace[index], y2 = event->adcTrace[index+1] + if(event->adcTrace[index+1] == event->adcTrace[index]){ return index+1; } + else{ return (phase = (index + (thresh_ * maximum - event->adcTrace[index])/(event->adcTrace[index+1] - event->adcTrace[index]))); } } } @@ -192,13 +165,13 @@ float ChannelEvent::FindLeadingEdge(const float &thresh_/*=0.05*/){ } float ChannelEvent::IntegratePulse(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ - if(!event || (!baseline_corrected && CorrectBaseline() < 0)){ return -9999; } + if(!event || ComputeBaseline() < 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]); + qdc += 0.5*(event->adcTrace[i-1] + event->adcTrace[i]) - baseline; } return qdc; @@ -287,18 +260,13 @@ void ChannelEvent::Clear(){ 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/util/source/scope.cpp b/Scan/util/source/scope.cpp index 580f831ef..f94b0bcea 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -378,8 +378,7 @@ bool scopeScanner::AddEvent(XiaData *event_){ ChannelEvent *channel_event = new ChannelEvent(event_); //Process the waveform. - //channel_event->FindLeadingEdge(); - channel_event->CorrectBaseline(); + channel_event->ComputeBaseline(); channel_event->FindQDC(); //Push the channel event into the deque. From d44ae5e7c622711092d1cd0b4af751f397572c6e Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Mon, 21 Nov 2016 18:22:40 -0500 Subject: [PATCH 052/255] Now save pol3 params inside ChannelEvent class Former-commit-id: 540434642917ea8935ce4555c6962bb2e2c9a245 --- Scan/ScanLib/include/XiaData.hpp | 10 ++++------ Scan/ScanLib/source/XiaData.cpp | 27 ++++++--------------------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index f0ee4a5c4..1c2f8cbfa 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -93,6 +93,8 @@ class ChannelEvent{ 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). + float cfdPar[7]; /// Array of floats for storing cfd polynomial fits. + bool ignore; /// Ignore this event. XiaData *event; /// The low level pixie event. @@ -128,12 +130,8 @@ class ChannelEvent{ void Clear(); }; -void calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2); - -float calculateP2(const short &x0, const std::vector &trace, float &Xmax); - -void calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3); +float calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2); -float calculateP3(const short &x0, const std::vector &trace, float &Xmax); +float calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3); #endif diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 3eb008f4e..e6df8a633 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -133,11 +133,10 @@ float ChannelEvent::ComputeBaseline(){ } // Find the pulse maximum by fitting with a third order polynomial. - float realMax; if(event->adcTrace[max_index-1] >= event->adcTrace[max_index+1]) // Favor the left side of the pulse. - maximum = calculateP3(max_index-2, event->adcTrace, realMax) - baseline; + maximum = calculateP3(max_index-2, event->adcTrace, cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; else // Favor the right side of the pulse. - maximum = calculateP3(max_index-1, event->adcTrace, realMax) - baseline; + maximum = calculateP3(max_index-1, event->adcTrace, cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; return baseline; } @@ -270,7 +269,7 @@ void ChannelEvent::Clear(){ cfdvals = NULL; } -void calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2){ +float calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2){ float x1[3], x2[3]; for(size_t i = 0; i < 3; i++){ x1[i] = (x0+i); @@ -285,18 +284,12 @@ void calculateP2(const short &x0, const std::vector &trace, float &p0, floa p0 = (y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom; p1 = (1*(y[1]*x2[2]-x2[1]*y[2]) - y[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*y[2]-y[1]*1))/denom; p2 = (1*(x1[1]*y[2]-y[1]*x1[2]) - x1[0]*(1*y[2]-y[1]*1) + y[0]*(1*x1[2]-x1[1]*1))/denom; -} - -float calculateP2(const short &x0, const std::vector &trace, float &Xmax){ - float p0, p1, p2; - calculateP2(x0, trace, p0, p1, p2); // Calculate the maximum of the polynomial. - Xmax = -p1/(2*p2); - return (p0 + p1*Xmax + p2*Xmax*Xmax); + return (p0 - p1*p1/(4*p2)); } -void calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3){ +float calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3){ float x1[4], x2[4], x3[4]; for(size_t i = 0; i < 4; i++){ x1[i] = (x0+i); @@ -313,21 +306,13 @@ void calculateP3(const short &x0, const std::vector &trace, float &p0, floa p1 = (1*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - y[0]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) - x3[0]*(1*(y[2]*x2[3]-y[3]*x2[2]) - 1*(y[1]*x2[3]-y[3]*x2[1]) + 1*(y[1]*x2[2]-y[2]*x2[1])))/denom; p2 = (1*(x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - x1[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) + y[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])))/denom; p3 = (1*(x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - x1[0]*(1*(x2[2]*y[3]-x2[3]*y[2]) - 1*(x2[1]*y[3]-x2[3]*y[1]) + 1*(x2[1]*y[2]-x2[2]*y[1])) + x2[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])) - y[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; -} -float calculateP3(const short &x0, const std::vector &trace, float &Xmax){ - float p0, p1, p2, p3; - calculateP3(x0, trace, p0, p1, p2, p3); - // Calculate the maximum of the polynomial. float xmax1 = (-2*p2+std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); float xmax2 = (-2*p2-std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); - if((2*p2+6*p3*xmax1) < 0){ // The second derivative is negative (i.e. this is a maximum). - Xmax = xmax1; + if((2*p2+6*p3*xmax1) < 0) // The second derivative is negative (i.e. this is a maximum). return (p0 + p1*xmax1 + p2*xmax1*xmax1 + p3*xmax1*xmax1*xmax1); - } - Xmax = xmax2; return (p0 + p1*xmax2 + p2*xmax2*xmax2 + p3*xmax2*xmax2*xmax2); } From 29bea3f24313bf1e7ba6f07c9d108e890bb18176 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Tue, 22 Nov 2016 12:55:49 -0500 Subject: [PATCH 053/255] Added cfd polynomials to scope Former-commit-id: f184d7055024bbdbf3657d07308d3f9af4d4c411 --- Scan/ScanLib/include/XiaData.hpp | 5 ++-- Scan/ScanLib/source/XiaData.cpp | 28 +++++++++--------- Scan/util/include/scope.hpp | 3 +- Scan/util/source/scope.cpp | 49 +++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index 1c2f8cbfa..c3fc75723 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -92,6 +92,7 @@ class ChannelEvent{ 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). + size_t cfdIndex; /// The index in the trace just above the CFD threshold. float cfdPar[7]; /// Array of floats for storing cfd polynomial fits. @@ -130,8 +131,8 @@ class ChannelEvent{ void Clear(); }; -float calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2); +float calculateP2(const short &x0, int *y, float &p0, float &p1, float &p2); -float calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3); +float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, float &p3); #endif diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index e6df8a633..8e166a77a 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -132,11 +132,16 @@ float ChannelEvent::ComputeBaseline(){ } } + std::cout << "-----------------------------------------\n"; + std::cout << "maximum = " << maximum << std::endl; + // Find the pulse maximum by fitting with a third order polynomial. if(event->adcTrace[max_index-1] >= event->adcTrace[max_index+1]) // Favor the left side of the pulse. - maximum = calculateP3(max_index-2, event->adcTrace, cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; + maximum = calculateP3(max_index-2, &event->adcTrace.data()[max_index-2], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; else // Favor the right side of the pulse. - maximum = calculateP3(max_index-1, event->adcTrace, cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; + maximum = calculateP3(max_index-1, &event->adcTrace.data()[max_index-1], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; + + std::cout << "maximum = " << maximum << std::endl; return baseline; } @@ -221,15 +226,13 @@ float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/){ float threshold = F_*maximum + baseline; phase = -9999; - for(size_t cfdIndex = max_index; cfdIndex > 0; cfdIndex--){ + for(cfdIndex = max_index; cfdIndex > 0; cfdIndex--){ if(event->adcTrace[cfdIndex-1] < threshold && event->adcTrace[cfdIndex] >= threshold){ - float p0, p1, p2; - // Fit the rise of the trace to a 2nd order polynomial. - calculateP2(cfdIndex-1, event->adcTrace, p0, p1, p2); + calculateP2(cfdIndex-1, &event->adcTrace.data()[cfdIndex-1], cfdPar[4], cfdPar[5], cfdPar[6]); // Calculate the phase of the trace. - phase = (-p1+std::sqrt(p1*p1 - 4*p2*(p0 - threshold)))/(2*p2); + phase = (-cfdPar[5]+std::sqrt(cfdPar[5]*cfdPar[5] - 4*cfdPar[6]*(cfdPar[4] - threshold)))/(2*cfdPar[6]); break; } @@ -254,6 +257,7 @@ void ChannelEvent::Clear(){ qdc = -9999; cfdCrossing = -9999; max_index = 0; + cfdIndex = 0; hires_energy = -9999; hires_time = -9999; @@ -269,16 +273,13 @@ void ChannelEvent::Clear(){ cfdvals = NULL; } -float calculateP2(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2){ +float calculateP2(const short &x0, int *y, float &p0, float &p1, float &p2){ float x1[3], x2[3]; for(size_t i = 0; i < 3; i++){ x1[i] = (x0+i); x2[i] = std::pow(x0+i, 2); } - // messy - const int *y = &trace.data()[x0]; - float denom = 1*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*x1[2]-x1[1]*1); p0 = (y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom; @@ -289,7 +290,7 @@ float calculateP2(const short &x0, const std::vector &trace, float &p0, flo return (p0 - p1*p1/(4*p2)); } -float calculateP3(const short &x0, const std::vector &trace, float &p0, float &p1, float &p2, float &p3){ +float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, float &p3){ float x1[4], x2[4], x3[4]; for(size_t i = 0; i < 4; i++){ x1[i] = (x0+i); @@ -297,9 +298,6 @@ float calculateP3(const short &x0, const std::vector &trace, float &p0, flo x3[i] = std::pow(x0+i, 3); } - // messy - const int *y = &trace.data()[x0]; - float denom = 1*(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]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])); p0 = (y[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])) - x1[0]*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(y[1]*(x1[2]*x3[3]-x1[3]*x3[2]) - y[2]*(x1[1]*x3[3]-x1[3]*x3[1]) + y[3]*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(y[1]*(x1[2]*x2[3]-x1[3]*x2[2]) - y[2]*(x1[1]*x2[3]-x1[3]*x2[1]) + y[3]*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; diff --git a/Scan/util/include/scope.hpp b/Scan/util/include/scope.hpp index 112c11174..c2151eed4 100644 --- a/Scan/util/include/scope.hpp +++ b/Scan/util/include/scope.hpp @@ -214,8 +214,9 @@ class scopeScanner : public RootScanner { std::string saveFile_; ///< The name of the file to save a trace. TGraph *graph; ///< The TGraph for plotting traces. - TGraph *cfdGraph; ///< The TGraph for plotting cfd analysis. TLine *cfdLine; + TF1 *cfdPol3; + TF1 *cfdPol2; TH2F *hist; ///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(); @@ -162,8 +165,9 @@ scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : RootScanner() { /// Destructor. scopeScanner::~scopeScanner(){ delete graph; - delete cfdGraph; delete cfdLine; + delete cfdPol3; + delete cfdPol2; delete hist; delete paulauskasFunc; } @@ -177,14 +181,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); @@ -235,15 +235,32 @@ void scopeScanner::Plot(){ float highVal = (chanEvents_.front()->max_index + fitHigh_) * ADC_TIME_STEP; if(performCfd_){ + ChannelEvent *evt = chanEvents_.front(); + // Find the zero-crossing of the cfd waveform. - //float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_, cfdD_, cfdL_); - float cfdCrossing = chanEvents_.front()->AnalyzeCFD(cfdF_); + float cfdCrossing = evt->AnalyzeCFD(cfdF_); + + // Draw the cfd crossing line. + cfdLine->DrawLine(cfdCrossing*ADC_TIME_STEP, userZoomVals[1][0], cfdCrossing*ADC_TIME_STEP, userZoomVals[1][1]); + + // 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 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); - cfdLine->DrawLine(cfdCrossing*ADC_TIME_STEP, GetCanvas()->GetUymin(), cfdCrossing*ADC_TIME_STEP, GetCanvas()->GetUymax()); - cfdGraph->Draw("LSAME"); + // 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_){ From 147c9777efce9b5ab75f622c25f18e3cb6e26ba7 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Tue, 22 Nov 2016 12:59:34 -0500 Subject: [PATCH 054/255] Fixed 2nd and 3rd order polynomial rounding error Former-commit-id: 1067141cf95fc4c10f0acdfef5a989b13c8fb48c --- Scan/ScanLib/source/XiaData.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 8e166a77a..40b709bfc 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -274,36 +274,36 @@ void ChannelEvent::Clear(){ } float calculateP2(const short &x0, int *y, float &p0, float &p1, float &p2){ - float x1[3], x2[3]; + double x1[3], x2[3]; for(size_t i = 0; i < 3; i++){ x1[i] = (x0+i); x2[i] = std::pow(x0+i, 2); } - float denom = 1*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*x1[2]-x1[1]*1); + double denom = (x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(x2[2]-x2[1]*1) + x2[0]*(x1[2]-x1[1]*1); - p0 = (y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom; - p1 = (1*(y[1]*x2[2]-x2[1]*y[2]) - y[0]*(1*x2[2]-x2[1]*1) + x2[0]*(1*y[2]-y[1]*1))/denom; - p2 = (1*(x1[1]*y[2]-y[1]*x1[2]) - x1[0]*(1*y[2]-y[1]*1) + y[0]*(1*x1[2]-x1[1]*1))/denom; + p0 = (float)((y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom); + p1 = (float)(((y[1]*x2[2]-x2[1]*y[2]) - y[0]*(x2[2]-x2[1]*1) + x2[0]*(y[2]-y[1]*1))/denom); + p2 = (float)(((x1[1]*y[2]-y[1]*x1[2]) - x1[0]*(y[2]-y[1]*1) + y[0]*(x1[2]-x1[1]*1))/denom); // Calculate the maximum of the polynomial. return (p0 - p1*p1/(4*p2)); } float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, float &p3){ - float x1[4], x2[4], x3[4]; + double x1[4], x2[4], x3[4]; for(size_t i = 0; i < 4; i++){ x1[i] = (x0+i); x2[i] = std::pow(x0+i, 2); x3[i] = std::pow(x0+i, 3); } - float denom = 1*(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]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])); + 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])); - p0 = (y[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])) - x1[0]*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(y[1]*(x1[2]*x3[3]-x1[3]*x3[2]) - y[2]*(x1[1]*x3[3]-x1[3]*x3[1]) + y[3]*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(y[1]*(x1[2]*x2[3]-x1[3]*x2[2]) - y[2]*(x1[1]*x2[3]-x1[3]*x2[1]) + y[3]*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; - p1 = (1*(y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - y[0]*(1*(x2[2]*x3[3]-x2[3]*x3[2]) - 1*(x2[1]*x3[3]-x2[3]*x3[1]) + 1*(x2[1]*x3[2]-x2[2]*x3[1])) + x2[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) - x3[0]*(1*(y[2]*x2[3]-y[3]*x2[2]) - 1*(y[1]*x2[3]-y[3]*x2[1]) + 1*(y[1]*x2[2]-y[2]*x2[1])))/denom; - p2 = (1*(x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - x1[0]*(1*(y[2]*x3[3]-y[3]*x3[2]) - 1*(y[1]*x3[3]-y[3]*x3[1]) + 1*(y[1]*x3[2]-y[2]*x3[1])) + y[0]*(1*(x1[2]*x3[3]-x1[3]*x3[2]) - 1*(x1[1]*x3[3]-x1[3]*x3[1]) + 1*(x1[1]*x3[2]-x1[2]*x3[1])) - x3[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])))/denom; - p3 = (1*(x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - x1[0]*(1*(x2[2]*y[3]-x2[3]*y[2]) - 1*(x2[1]*y[3]-x2[3]*y[1]) + 1*(x2[1]*y[2]-x2[2]*y[1])) + x2[0]*(1*(x1[2]*y[3]-x1[3]*y[2]) - 1*(x1[1]*y[3]-x1[3]*y[1]) + 1*(x1[1]*y[2]-x1[2]*y[1])) - y[0]*(1*(x1[2]*x2[3]-x1[3]*x2[2]) - 1*(x1[1]*x2[3]-x1[3]*x2[1]) + 1*(x1[1]*x2[2]-x1[2]*x2[1])))/denom; + p0 = (float)((y[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])) - y[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])) + y[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])) - y[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); + p1 = (float)(((y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - (y[0]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[2]-x2[2]*x3[0])) + (y[0]*(x2[1]*x3[3]-x2[3]*x3[1]) - y[1]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[1]-x2[1]*x3[0])) - (y[0]*(x2[1]*x3[2]-x2[2]*x3[1]) - y[1]*(x2[0]*x3[2]-x2[2]*x3[0]) + y[2]*(x2[0]*x3[1]-x2[1]*x3[0]))) / denom); + p2 = (float)(((x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - (x1[0]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[2]-y[2]*x3[0])) + (x1[0]*(y[1]*x3[3]-y[3]*x3[1]) - x1[1]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[1]-y[1]*x3[0])) - (x1[0]*(y[1]*x3[2]-y[2]*x3[1]) - x1[1]*(y[0]*x3[2]-y[2]*x3[0]) + x1[2]*(y[0]*x3[1]-y[1]*x3[0]))) / denom); + p3 = (float)(((x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - (x1[0]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[2]-x2[2]*y[0])) + (x1[0]*(x2[1]*y[3]-x2[3]*y[1]) - x1[1]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[1]-x2[1]*y[0])) - (x1[0]*(x2[1]*y[2]-x2[2]*y[1]) - x1[1]*(x2[0]*y[2]-x2[2]*y[0]) + x1[2]*(x2[0]*y[1]-x2[1]*y[0]))) / denom); // Calculate the maximum of the polynomial. float xmax1 = (-2*p2+std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); From e8a8e158798d3b8f538f846854b6795b017b34c2 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Tue, 22 Nov 2016 13:01:31 -0500 Subject: [PATCH 055/255] Removed debug statements from XiaData.cpp Former-commit-id: cf85b717b36180ae836382001a56bf18850a9342 --- Scan/ScanLib/source/XiaData.cpp | 5 ----- Scan/util/source/scope.cpp | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 40b709bfc..19784544e 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -132,17 +132,12 @@ float ChannelEvent::ComputeBaseline(){ } } - std::cout << "-----------------------------------------\n"; - std::cout << "maximum = " << maximum << std::endl; - // Find the pulse maximum by fitting with a third order polynomial. if(event->adcTrace[max_index-1] >= event->adcTrace[max_index+1]) // Favor the left side of the pulse. maximum = calculateP3(max_index-2, &event->adcTrace.data()[max_index-2], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; else // Favor the right side of the pulse. maximum = calculateP3(max_index-1, &event->adcTrace.data()[max_index-1], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; - std::cout << "maximum = " << maximum << std::endl; - return baseline; } diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index 60682dabb..3f04353e0 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -129,7 +129,7 @@ scopeScanner::scopeScanner(int mod /*= 0*/, int chan/*=0*/) : RootScanner() { init = false; running = true; performFit_ = false; - performCfd_ = true; + performCfd_ = false; numEvents = 20; numAvgWaveforms_ = 1; cfdF_ = 0.5; From 5493630a493b2ce0099900122377bd49ba3d8e34 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Tue, 22 Nov 2016 13:05:02 -0500 Subject: [PATCH 056/255] Updated calculateP3 function for readability Former-commit-id: e68daf55ce88de90d8fde5c80802e1fd72909635 --- Scan/ScanLib/source/XiaData.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 19784544e..ee12cc8c3 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -293,12 +293,27 @@ float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, floa x3[i] = std::pow(x0+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])); - - p0 = (float)((y[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])) - y[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])) + y[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])) - y[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); - p1 = (float)(((y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - (y[0]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[2]-x2[2]*x3[0])) + (y[0]*(x2[1]*x3[3]-x2[3]*x3[1]) - y[1]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[1]-x2[1]*x3[0])) - (y[0]*(x2[1]*x3[2]-x2[2]*x3[1]) - y[1]*(x2[0]*x3[2]-x2[2]*x3[0]) + y[2]*(x2[0]*x3[1]-x2[1]*x3[0]))) / denom); - p2 = (float)(((x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - (x1[0]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[2]-y[2]*x3[0])) + (x1[0]*(y[1]*x3[3]-y[3]*x3[1]) - x1[1]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[1]-y[1]*x3[0])) - (x1[0]*(y[1]*x3[2]-y[2]*x3[1]) - x1[1]*(y[0]*x3[2]-y[2]*x3[0]) + x1[2]*(y[0]*x3[1]-y[1]*x3[0]))) / denom); - p3 = (float)(((x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - (x1[0]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[2]-x2[2]*y[0])) + (x1[0]*(x2[1]*y[3]-x2[3]*y[1]) - x1[1]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[1]-x2[1]*y[0])) - (x1[0]*(x2[1]*y[2]-x2[2]*y[1]) - x1[1]*(x2[0]*y[2]-x2[2]*y[0]) + x1[2]*(x2[0]*y[1]-x2[1]*y[0]))) / denom); + 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])); + + p0 = (float)((y[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])) - + y[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])) + + y[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])) - + y[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); + p1 = (float)(((y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - + (y[0]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[2]-x2[2]*x3[0])) + + (y[0]*(x2[1]*x3[3]-x2[3]*x3[1]) - y[1]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[1]-x2[1]*x3[0])) - + (y[0]*(x2[1]*x3[2]-x2[2]*x3[1]) - y[1]*(x2[0]*x3[2]-x2[2]*x3[0]) + y[2]*(x2[0]*x3[1]-x2[1]*x3[0]))) / denom); + p2 = (float)(((x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - + (x1[0]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[2]-y[2]*x3[0])) + + (x1[0]*(y[1]*x3[3]-y[3]*x3[1]) - x1[1]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[1]-y[1]*x3[0])) - + (x1[0]*(y[1]*x3[2]-y[2]*x3[1]) - x1[1]*(y[0]*x3[2]-y[2]*x3[0]) + x1[2]*(y[0]*x3[1]-y[1]*x3[0]))) / denom); + p3 = (float)(((x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - + (x1[0]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[2]-x2[2]*y[0])) + + (x1[0]*(x2[1]*y[3]-x2[3]*y[1]) - x1[1]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[1]-x2[1]*y[0])) - + (x1[0]*(x2[1]*y[2]-x2[2]*y[1]) - x1[1]*(x2[0]*y[2]-x2[2]*y[0]) + x1[2]*(x2[0]*y[1]-x2[1]*y[0]))) / denom); // Calculate the maximum of the polynomial. float xmax1 = (-2*p2+std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); From 4e0b646fac4aab0695ac576191b95c3093edb83f Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 14 Dec 2016 19:37:37 -0500 Subject: [PATCH 057/255] Creating the HelperFunction header. Rearranging files to generalize. All of the functions except two pass all of their Unit Tests. These functions provide generalized use of different things that we use to have relegated to classes. This has broken functionality of the WaveformAnalyzer and the Fitting Analyzer since we have moved some of their functions to this new header. This will be fixed in a subsequent commit. Former-commit-id: 41cb0387741eb9623fd0e55924130de22078e925 --- Scan/CMakeLists.txt | 16 +- Scan/Resources/CMakeLists.txt | 6 + .../include/GslFitter.hpp | 18 +- Scan/Resources/include/HelperEnumerations.hpp | 18 + Scan/Resources/include/HelperFunctions.hpp | 435 ++++++++++++++++++ .../include/PolynomialCfdCalculator.hpp | 22 + .../include/TimingDriver.hpp} | 46 +- Scan/Resources/include/XiaCfd.hpp | 21 + Scan/Resources/source/CMakeLists.txt | 28 ++ .../source/Gsl1Fitter.cpp | 0 .../source/Gsl2Fitter.cpp | 34 +- .../source/PolynomialCfdCalculator.cpp | 38 ++ Scan/Resources/source/XiaCfd.cpp | 48 ++ .../tests/CMakeLists.txt | 10 +- .../tests/test_gslfitter.cpp | 0 .../tests/unittest-HelperFunctions.cpp | 220 +++++++++ Scan/ScanLib/include/Utilities.hpp | 8 - Scan/ScanLib/include/XiaData.hpp | 22 - Scan/ScanLib/source/XiaData.cpp | 207 +-------- Scan/utkscan/CMakeLists.txt | 7 - Scan/utkscan/analyzers/CMakeLists.txt | 6 +- .../analyzers/include/FittingAnalyzer.hpp | 2 +- Scan/utkscan/analyzers/source/CMakeLists.txt | 7 +- .../analyzers/source/FittingAnalyzer.cpp | 2 +- .../analyzers/source/WaveformAnalyzer.cpp | 96 ---- 25 files changed, 913 insertions(+), 404 deletions(-) create mode 100644 Scan/Resources/CMakeLists.txt rename Scan/{utkscan/analyzers => Resources}/include/GslFitter.hpp (72%) create mode 100644 Scan/Resources/include/HelperEnumerations.hpp create mode 100644 Scan/Resources/include/HelperFunctions.hpp create mode 100644 Scan/Resources/include/PolynomialCfdCalculator.hpp rename Scan/{utkscan/analyzers/include/FitDriver.hpp => Resources/include/TimingDriver.hpp} (60%) create mode 100644 Scan/Resources/include/XiaCfd.hpp create mode 100644 Scan/Resources/source/CMakeLists.txt rename Scan/{utkscan/analyzers => Resources}/source/Gsl1Fitter.cpp (100%) rename Scan/{utkscan/analyzers => Resources}/source/Gsl2Fitter.cpp (83%) create mode 100644 Scan/Resources/source/PolynomialCfdCalculator.cpp create mode 100644 Scan/Resources/source/XiaCfd.cpp rename Scan/{utkscan/analyzers => Resources}/tests/CMakeLists.txt (61%) rename Scan/{utkscan/analyzers => Resources}/tests/test_gslfitter.cpp (100%) create mode 100644 Scan/Resources/tests/unittest-HelperFunctions.cpp delete mode 100644 Scan/ScanLib/include/Utilities.hpp diff --git a/Scan/CMakeLists.txt b/Scan/CMakeLists.txt index 2c4398393..35a32783d 100644 --- a/Scan/CMakeLists.txt +++ b/Scan/CMakeLists.txt @@ -1,6 +1,15 @@ option(USE_HRIBF "Use HRIBF library for scan base." OFF) +option(USE_GSL "Use GSL for Pulse Fitting" OFF) -#Everything below is dependent on ScanLib, so we include the headers. +#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(ScanLib/include) if(USE_HRIBF) @@ -14,13 +23,14 @@ if(USE_HRIBF) add_subdirectory(scanor) endif(USE_HRIBF) -#We will always build this since it includes a static lib for the rest -include_directories(ScanLib/include) +#We will always build these two since they include static lib for the rest add_subdirectory(ScanLib) +add_subdirectory(Resources) #Build utilities. add_subdirectory(util) + if(BUILD_UTKSCAN) add_subdirectory(utkscan) endif(BUILD_UTKSCAN) \ No newline at end of file diff --git a/Scan/Resources/CMakeLists.txt b/Scan/Resources/CMakeLists.txt new file mode 100644 index 000000000..ae30a4f0f --- /dev/null +++ b/Scan/Resources/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories(include) +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/Scan/utkscan/analyzers/include/GslFitter.hpp b/Scan/Resources/include/GslFitter.hpp similarity index 72% rename from Scan/utkscan/analyzers/include/GslFitter.hpp rename to Scan/Resources/include/GslFitter.hpp index 4fc1e0cce..12a6ab0bf 100644 --- a/Scan/utkscan/analyzers/include/GslFitter.hpp +++ b/Scan/Resources/include/GslFitter.hpp @@ -12,14 +12,14 @@ #include #include -#include "FitDriver.hpp" +#include "TimingDriver.hpp" -class GslFitter : public FitDriver{ +class GslFitter : public TimingDriver { public: ///Default Constructor - GslFitter() : FitDriver() {}; + GslFitter() : TimingDriver() {}; ///Default Destructor - virtual ~GslFitter() {}; + ~GslFitter() {}; ///\return the phase from the GSL fit double GetPhase(void){return phase_;} @@ -38,6 +38,16 @@ class GslFitter : public FitDriver{ const bool &isSipmFast = false, const double &weight = 1., const double &area = 1.); + + //! 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: double amp_; double chi_; diff --git a/Scan/Resources/include/HelperEnumerations.hpp b/Scan/Resources/include/HelperEnumerations.hpp new file mode 100644 index 000000000..02a5af74f --- /dev/null +++ b/Scan/Resources/include/HelperEnumerations.hpp @@ -0,0 +1,18 @@ +// +// Created by vincent on 12/6/16. +// + +#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}; +} + + + + +#endif //PIXIESUITE_HELPERENUMERATIONS_HPP diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp new file mode 100644 index 000000000..26a02f6a3 --- /dev/null +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -0,0 +1,435 @@ +///@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 { + static const pair > CalculatePoly2( + const vector &data, const unsigned int &startBin) { + 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 = (double) ((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 = (double) ( + ((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 = (double) ( + ((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}; + + // Calculate the maximum of the polynomial. + //@TODO Is this actually the maximum of the polynomial?? + return make_pair(p0 - p1 * p1 / (4 * p2), coeffs); + } + + 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 { + inline double CalculateAverage(const vector &data) { + double sum = 0.0; + for (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. + inline double CalculateStandardDeviation(const vector &data, + const double &mean) { + double stddev = 0.0; + for (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 + 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 = 30; + + ///@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. + 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 minumum" + " 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 + 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. + 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. + 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); + } + + inline unsigned int FindLeadingEdge(const vector &data, + const double &threshold, + const pair &maxInfo) { + if (threshold <= 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."); + unsigned int val = 9999; + for (size_t index = maxInfo.first; + index > minimum_baseline_length; index--) { + if (data[index] <= threshold * maxInfo.second) { + // Interpolate and return the value + // y = thresh_ * maximum + // x = (x1 + (y-y1)/(y2-y1)) + // x1 = index, x2 = index+1 + // y1 = data[index], y2 = data[index+1] + if (data[index + 1] == data[index]) + val = index + 1; + else + val = index + (threshold * maxInfo.second - data[index]) / + (data[index + 1] - data[index]); + } + } + return val; + } + + 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()); + } + vector tmp(); + return Statistics::CalculateIntegral( + vector(data.begin() + range.first, + data.begin() + range.second)); + } +/* + + 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_); + } + } + + + + //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); + } + + +*/ +} +#endif //PIXIESUITE_HELPERFUNCTIONS_HPP diff --git a/Scan/Resources/include/PolynomialCfdCalculator.hpp b/Scan/Resources/include/PolynomialCfdCalculator.hpp new file mode 100644 index 000000000..ef794624d --- /dev/null +++ b/Scan/Resources/include/PolynomialCfdCalculator.hpp @@ -0,0 +1,22 @@ +// +// Created by vincent on 12/6/16. +// + +#ifndef PIXIESUITE_POLYNOMIALCFDCALCULATOR_HPP +#define PIXIESUITE_POLYNOMIALCFDCALCULATOR_HPP + +#include + +class PolynomialCfdCalculator : public CfdDriver { +public: + PolynomialCfdCalculator(){}; + ~PolynomialCfdCalculator(){}; + + /// Perform CFD analysis on the waveform using the pol2 algorithm. + double AnalyzeCFD(const double &f = 0.5, + vector &trc, const + double &maximum, + const double &baseline); +}; + +#endif //PIXIESUITE_POLYNOMIALCFD_HPP diff --git a/Scan/utkscan/analyzers/include/FitDriver.hpp b/Scan/Resources/include/TimingDriver.hpp similarity index 60% rename from Scan/utkscan/analyzers/include/FitDriver.hpp rename to Scan/Resources/include/TimingDriver.hpp index 5d3032506..a6274b608 100644 --- a/Scan/utkscan/analyzers/include/FitDriver.hpp +++ b/Scan/Resources/include/TimingDriver.hpp @@ -1,22 +1,20 @@ -/// \file FitDriver.hpp +/// \file TimingDriver.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 +#ifndef PIXIESUITE_TIMINGDRIVER_HPP +#define PIXIESUITE_TIMINGDRIVER_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 { +/// An abstract class that will be used to handle timing. +class TimingDriver { public: ///Default Constructor - FitDriver() {}; + TimingDriver() {}; ///Default destructor - virtual ~FitDriver(){}; + virtual ~TimingDriver(){}; /// Gets the amplitude found by the fit. Does nothing by default. We assume /// that the children will overload this with their specific implementation. @@ -30,10 +28,11 @@ class FitDriver { /// 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.;} + + virtual double CalculatePhase(const std::vector &data, + const std::pair &pars, + const double &maxPosition) {} + ///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 @@ -43,13 +42,8 @@ class FitDriver { const std::pair &pars, const bool &isFastSipm, 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;} + const double &area = 1.) {} + /// 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;} @@ -58,19 +52,11 @@ class FitDriver { /// \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 - }; + 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 +#endif //PIXIESUITE_TIMINGDRIVER_HPP diff --git a/Scan/Resources/include/XiaCfd.hpp b/Scan/Resources/include/XiaCfd.hpp new file mode 100644 index 000000000..7473a143f --- /dev/null +++ b/Scan/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/Scan/Resources/source/CMakeLists.txt b/Scan/Resources/source/CMakeLists.txt new file mode 100644 index 000000000..74f392fe7 --- /dev/null +++ b/Scan/Resources/source/CMakeLists.txt @@ -0,0 +1,28 @@ +#Set the utility sources that we will make a lib out of +set(UtilitySources PolynomialCfdCalculator.cpp) + +if(USE_GSL) + if(${GSL_VERSION} GREATER 1.9) + set(UtilitySources ${UtilitySources} Gsl2Fitter.cpp) + else(${GSL_VERSION} LESS 2.0) + set(UtilitySources ${UtilitySources} Gsl1Fitter.cpp) + endif(${GSL_VERSION} GREATER 1.9) +endif(USE_GSL) + +#Add the sources to the library +add_library(UtilityObjects OBJECT ${UtilitySources}) + +if(BUILD_SHARED_LIBS) + message(STATUS "Building Utility Shared Objects") + add_library(UtilityLibrary SHARED $) + target_link_libraries(UtilityLibrary PixieCoreStatic + ${CMAKE_THREAD_LIBS_INIT}) + if (${CURSES_FOUND}) + target_link_libraries(UtilityLibrary ${CURSES_LIBRARIES}) + endif() + install(TARGETS UtilityLibrary DESTINATION lib) +endif(BUILD_SHARED_LIBS) + +#Create Utility static library and add ncurses if we have it +add_library(UtilityStatic STATIC $) +target_link_libraries(UtilityStatic ${CMAKE_THREAD_LIBS_INIT}) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/Gsl1Fitter.cpp b/Scan/Resources/source/Gsl1Fitter.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/Gsl1Fitter.cpp rename to Scan/Resources/source/Gsl1Fitter.cpp diff --git a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp b/Scan/Resources/source/Gsl2Fitter.cpp similarity index 83% rename from Scan/utkscan/analyzers/source/Gsl2Fitter.cpp rename to Scan/Resources/source/Gsl2Fitter.cpp index 1c671d511..1629006d6 100644 --- a/Scan/utkscan/analyzers/source/Gsl2Fitter.cpp +++ b/Scan/Resources/source/Gsl2Fitter.cpp @@ -64,7 +64,7 @@ void GslFitter::PerformFit(const std::vector &data, 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, + struct 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); @@ -104,11 +104,11 @@ void GslFitter::PerformFit(const std::vector &data, } 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; + size_t n = ((struct TimingDriver::FitData *)FitData)->n; + double *y = ((struct TimingDriver::FitData *)FitData)->y; + double beta = ((struct TimingDriver::FitData *)FitData)->beta; + double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; + double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double alpha = gsl_vector_get (x, 1); @@ -129,10 +129,10 @@ 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 beta = ((struct FitDriver::FitData *)FitData)->beta; - double gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct TimingDriver::FitData *)FitData)->n; + double beta = ((struct TimingDriver::FitData *)FitData)->beta; + double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; + double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double alpha = gsl_vector_get (x, 1); @@ -158,10 +158,10 @@ int CalcPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { } 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; + size_t n = ((struct TimingDriver::FitData *)FitData)->n; + double *y = ((struct TimingDriver::FitData *)FitData)->y; + double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; + double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); @@ -175,9 +175,9 @@ 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 gamma = ((struct FitDriver::FitData *)FitData)->gamma; - double qdc = ((struct FitDriver::FitData *)FitData)->qdc; + size_t n = ((struct TimingDriver::FitData *)FitData)->n; + double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; + double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; double phi = gsl_vector_get (x, 0); double dphi; diff --git a/Scan/Resources/source/PolynomialCfdCalculator.cpp b/Scan/Resources/source/PolynomialCfdCalculator.cpp new file mode 100644 index 000000000..5af8d995d --- /dev/null +++ b/Scan/Resources/source/PolynomialCfdCalculator.cpp @@ -0,0 +1,38 @@ +// +// Created by vincent on 12/6/16. +// +#include + +#include "HelperFunctions.hpp" + +using namespace std; + +/// Perform CFD analysis on the waveform. +double PolynomialCfdCalculator::AnalyzeCFD(const double &f/*=0.5*/, + vector &trc, const + double &maximum, + const double &baseline) { + if (size == 0 || baseline < 0) { return -9999; } + + double threshold = f * maximum + baseline; + double phase = -9999; + vector coeffs; + for (unsigned int cfdIndex = max_index; cfdIndex > 0; cfdIndex--) { + if (event->adcTrace[cfdIndex - 1] < threshold && + event->adcTrace[cfdIndex] >= threshold) { + // Fit the rise of the trace to a 2nd order polynomial. + coeffs = Polynomial::CalculatePoly2(cfdIndex - 1, + &event->adcTrace.data()[cfdIndex - 1], + coeffs); + + // Calculate the phase of the trace. + phase = (-cfdPar[5] + std::sqrt(cfdPar[5] * cfdPar[5] - + 4 * cfdPar[6] * + (cfdPar[4] - threshold))) / + (2 * cfdPar[6]); + + break; + } + } + return phase; +} \ No newline at end of file diff --git a/Scan/Resources/source/XiaCfd.cpp b/Scan/Resources/source/XiaCfd.cpp new file mode 100644 index 000000000..3ae25c1c1 --- /dev/null +++ b/Scan/Resources/source/XiaCfd.cpp @@ -0,0 +1,48 @@ +// +// Created by vincent on 12/6/16. +// + +#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/Scan/utkscan/analyzers/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt similarity index 61% rename from Scan/utkscan/analyzers/tests/CMakeLists.txt rename to Scan/Resources/tests/CMakeLists.txt index 357e22f25..ee7b444be 100644 --- a/Scan/utkscan/analyzers/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -if(USE_GSL) +if(USE_GSL AND BUILD_TESTS) if(${GSL_VERSION} GREATER 1.9) set(GSL_FITTER_SOURCES ../source/Gsl2Fitter.cpp) else(${GSL_VERSION} LESS 2.0) @@ -9,4 +9,10 @@ if(USE_GSL) set(GSL_FITTER_SOURCES ${GSL_FITTER_SOURCES} test_gslfitter.cpp) add_executable(test_gslfitter ${GSL_FITTER_SOURCES}) target_link_libraries(test_gslfitter ${GSL_LIBRARIES} UnitTest++) -endif(USE_GSL) \ No newline at end of file +endif(USE_GSL AND BUILD_TESTS) + +if(BUILD_UNITTESTS) + add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) + target_link_libraries(unittest-HelperFunctions UnitTest++) + install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) +endif(BUILD_UNITTESTS) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/tests/test_gslfitter.cpp b/Scan/Resources/tests/test_gslfitter.cpp similarity index 100% rename from Scan/utkscan/analyzers/tests/test_gslfitter.cpp rename to Scan/Resources/tests/test_gslfitter.cpp diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp new file mode 100644 index 000000000..670abeac8 --- /dev/null +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -0,0 +1,220 @@ +///@file unittest-HelperFunctions.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include +#include +#include + +#include + +#include "HelperFunctions.hpp" + +using namespace std; + +//This is a trace taken from a medium VANDLE module. +static const vector data = { + 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 +}; + + +//An empty data vector to test error checking. +static const vector empty_data; +//A data vector that contains constant data. +static const vector const_data = {1000, 4}; +//A data vector to test the integration +static const vector integration_data = {0, 1, 2, 3, 4, 5}; +//The expected value from the CalculateIntegral function +static const double expected_integral = 12.5; + +//The expected maximum from the poly3 fitting +static const double expected_poly3_val = 3818.0718412264; +//The expected maximum from the pol2 fitting +static const double expected_poly2_val = 10737.0720588236; + +//This is the expected value of the maximum +static const double expected_maximum_value = 3816; +//This is the expected position of the maximum +static const unsigned int expected_max_position = 76; +//This is the pair made from the expected maximum information +static const pair expected_max_info = + make_pair(expected_max_position, expected_maximum_value); + +///This tests that the TraceFunctions::CalculateBaseline function works as +/// expected. This also verifies the Statistics functions CalculateAverage +/// and CalculateStandardDeviation +TEST(TestCalculateBaseline) { + //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 expected_baseline = 436.7428571; + //The expected standard deviation was obtained using the STDEVP function in + // Google Sheets. + static const double expected_standard_deviation = 1.976184739; + + //Checking that we throw a range_error when the range is too small + CHECK_THROW(TraceFunctions::CalculateBaseline(data, 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_data, make_pair(0, 16)), + range_error); + + //Checking that we throw a range_error when the range is inverted + CHECK_THROW(TraceFunctions::CalculateBaseline(data, 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(data, make_pair(0, 1000)), + range_error); + + //Check that we are actually calculating the parameters properly + pair result = + TraceFunctions::CalculateBaseline(data, make_pair(0, 70)); + CHECK_CLOSE(expected_baseline, result.first, 1e-7); + CHECK_CLOSE(expected_standard_deviation, result.second, 1e-9); +} + +TEST(TestFindMaxiumum) { + static const unsigned int trace_delay = 80; + + //Checking that we throw a range_error when the data vector is sized 0 + CHECK_THROW(TraceFunctions::FindMaximum(empty_data, 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(data, 1000), 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(data, 10), 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_data, trace_delay), + range_error); + + pair result = + TraceFunctions::FindMaximum(data, trace_delay); + CHECK_EQUAL(expected_max_position, result.first); + CHECK_EQUAL(expected_maximum_value, result.second); +} + +TEST(TestFindLeadingEdge) { + //This is the expected position of the leading edge of signal. + static const unsigned int expected_leading_edge_position = 72; + + //Check that if we define a threshold that is 0 or less we throw a range + // error + CHECK_THROW(TraceFunctions::FindLeadingEdge(data, -2, expected_max_info), + 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_data, 0.05, + expected_max_info), + 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(const_data, 0.05, + make_pair(2000, 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(expected_leading_edge_position, + TraceFunctions::FindLeadingEdge(data, 0.131, + expected_max_info)); +} + +TEST(TestCalculatePoly3) { + //A data vector that contains only the four points for the Poly3 Fitting. + static const vector poly3_data(data.begin() + 74, + data.begin() + 78); + //A vector containing the coefficients obtained from gnuplot using the data + // from pol3_data with an x value starting at 0 + static const vector expected_poly3_coeffs = + {2358.0, 1635.66666666667, -516.0, 31.3333333333333}; + + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(Polynomial::CalculatePoly3(empty_data, 0), range_error); + + pair > result = + Polynomial::CalculatePoly3(poly3_data, 0); + + + //Check that we are returning the correct coefficients for the data being + // passed. + CHECK_ARRAY_CLOSE(expected_poly3_coeffs, result.second, 4, 1e-6); + + //Check that the calculated maximum value is accurate + CHECK_CLOSE(expected_poly3_val, result.first, 1e-6); +} + +//For determination of the maximum value of the trace this traces favors the +// left side since max+1 is less than max - 1 +TEST(TestExtrapolateMaximum) { + static const vector expected_coeffs = + {-15641316.0007084, 592747.666694852, -7472.00000037373, + 31.3333333349849}; + + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(TraceFunctions::ExtrapolateMaximum(empty_data, + expected_max_info), + range_error); + + pair > result = + TraceFunctions::ExtrapolateMaximum(data, expected_max_info); + + //Check that the calculated maximum value is accurate + CHECK_CLOSE(expected_poly3_val, result.first, 1e-6); + + //Check that we are returning the correct coefficients for the data being + // passed. + CHECK_ARRAY_CLOSE(expected_coeffs, result.second, 4, 1e-3); +} + +TEST(TestCalculatePoly2) { + //A data vector containing only the three points for the Poly2 fitting + static const vector poly2_data(data.begin() + 73, + data.begin() + 75); + //Vector containing the expected coefficients from the poly 2 fit + static const vector expected_poly2_coeffs = + {1122.0, 1278.5, -42.4999999999999}; + + pair > result = + Polynomial::CalculatePoly2(poly2_data, 0); + + CHECK_CLOSE(expected_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_data), range_error); + CHECK_EQUAL(expected_integral, + Statistics::CalculateIntegral(integration_data)); +} + +TEST(TestCalculateQdc) { + static const double expected = 6; + //Check that we are throwing an error when the data is empty + CHECK_THROW(TraceFunctions::CalculateQdc(empty_data, make_pair(0,4)), + range_error); + //Check that we are throwing an error when the range is too large + CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(0,1000)), + range_error); + CHECK_EQUAL(expected, TraceFunctions::CalculateQdc + (integration_data, make_pair(2,5))); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/ScanLib/include/Utilities.hpp b/Scan/ScanLib/include/Utilities.hpp deleted file mode 100644 index 9f705304a..000000000 --- a/Scan/ScanLib/include/Utilities.hpp +++ /dev/null @@ -1,8 +0,0 @@ -// -// Created by vincent on 11/25/16. -// - -#ifndef PIXIESUITE_UTILITIES_HPP -#define PIXIESUITE_UTILITIES_HPP - -#endif //PIXIESUITE_UTILITIES_HPP diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index c3fc75723..c7514c437 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -109,30 +109,8 @@ class ChannelEvent{ /// Destructor. ~ChannelEvent(); - /// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. - float ComputeBaseline(); - - /// 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 using the XIA algorithm. - float AnalyzeXiaCFD(const float &F_=0.5, const size_t &D_=1, const size_t &L_=1); - - /// Perform CFD analysis on the waveform using the pol3 + pol2 algorithm. - float AnalyzeCFD(const float &F_=0.5); - /// Clear all variables and clear the trace vector and arrays. void Clear(); }; -float calculateP2(const short &x0, int *y, float &p0, float &p1, float &p2); - -float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, float &p3); - #endif diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index ee12cc8c3..e0d482439 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -1,5 +1,6 @@ #include +#include "HelperFunctions.hpp" #include "XiaData.hpp" ///////////////////////////////////////////////////////////////////// @@ -103,147 +104,6 @@ ChannelEvent::~ChannelEvent(){ if(cfdvals){ delete[] cfdvals; } } -/// Compute the trace baseline, baseline standard deviation, and find the pulse maximum. -float ChannelEvent::ComputeBaseline(){ - if(size == 0){ return -9999; } - if(baseline > 0){ return baseline; } - - // Find the baseline. - baseline = 0.0; - size_t sample_size = (15 <= size ? 15:size); - for(size_t i = 0; i < sample_size; i++){ - baseline += event->adcTrace[i]; - } - baseline = float(baseline)/sample_size; - - // Calculate the standard deviation. - stddev = 0.0; - for(size_t i = 0; i < sample_size; i++){ - stddev += (event->adcTrace[i] - baseline)*(event->adcTrace[i] - baseline); - } - stddev = std::sqrt((1.0/sample_size) * stddev); - - // Find the maximum value and the maximum bin. - maximum = -9999.0; - for(size_t i = 0; i < size; i++){ - if(event->adcTrace[i]-baseline > maximum){ - maximum = event->adcTrace[i]-baseline; - max_index = i; - } - } - - // Find the pulse maximum by fitting with a third order polynomial. - if(event->adcTrace[max_index-1] >= event->adcTrace[max_index+1]) // Favor the left side of the pulse. - maximum = calculateP3(max_index-2, &event->adcTrace.data()[max_index-2], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; - else // Favor the right side of the pulse. - maximum = calculateP3(max_index-1, &event->adcTrace.data()[max_index-1], cfdPar[0], cfdPar[1], cfdPar[2], cfdPar[3]) - baseline; - - return baseline; -} - -float ChannelEvent::FindLeadingEdge(const float &thresh_/*=0.05*/){ - if(!event || ComputeBaseline() < 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(event->adcTrace[index] <= thresh_ * maximum){ - // Interpolate and return the value - // y = thresh_ * maximum - // x = (x1 + (y-y1)/(y2-y1)) - // x1 = index, x2 = index+1 - // y1 = event->adcTrace[index], y2 = event->adcTrace[index+1] - if(event->adcTrace[index+1] == event->adcTrace[index]){ return index+1; } - else{ return (phase = (index + (thresh_ * maximum - event->adcTrace[index])/(event->adcTrace[index+1] - event->adcTrace[index]))); } - } - } - - return -9999; -} - -float ChannelEvent::IntegratePulse(const size_t &start_/*=0*/, const size_t &stop_/*=0*/){ - if(!event || ComputeBaseline() < 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*(event->adcTrace[i-1] + event->adcTrace[i]) - baseline; - } - - return qdc; -} - -/// Perform CFD analysis on the waveform. -float ChannelEvent::AnalyzeXiaCFD(const float &F_/*=0.5*/, const size_t &D_/*=1*/, const size_t &L_/*=1*/){ - if(size == 0 || baseline < 0){ return -9999; } - if(!cfdvals) - cfdvals = new float[size]; - - float 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; -} - -/// Perform CFD analysis on the waveform. -float ChannelEvent::AnalyzeCFD(const float &F_/*=0.5*/){ - if(size == 0 || baseline < 0){ return -9999; } - - float threshold = F_*maximum + baseline; - - phase = -9999; - for(cfdIndex = max_index; cfdIndex > 0; cfdIndex--){ - if(event->adcTrace[cfdIndex-1] < threshold && event->adcTrace[cfdIndex] >= threshold){ - // Fit the rise of the trace to a 2nd order polynomial. - calculateP2(cfdIndex-1, &event->adcTrace.data()[cfdIndex-1], cfdPar[4], cfdPar[5], cfdPar[6]); - - // Calculate the phase of the trace. - phase = (-cfdPar[5]+std::sqrt(cfdPar[5]*cfdPar[5] - 4*cfdPar[6]*(cfdPar[4] - threshold)))/(2*cfdPar[6]); - - break; - } - } - - return phase; -} - -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; -} - void ChannelEvent::Clear(){ phase = -9999; maximum = -9999; @@ -256,71 +116,14 @@ void ChannelEvent::Clear(){ hires_energy = -9999; hires_time = -9999; - + valid_chan = false; ignore = false; - + size = 0; if(cfdvals){ delete[] cfdvals; } if(event){ event->clear(); } - + event = NULL; cfdvals = NULL; -} - -float calculateP2(const short &x0, int *y, float &p0, float &p1, float &p2){ - double x1[3], x2[3]; - for(size_t i = 0; i < 3; i++){ - x1[i] = (x0+i); - x2[i] = std::pow(x0+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); - - p0 = (float)((y[0]*(x1[1]*x2[2]-x2[1]*x1[2]) - x1[0]*(y[1]*x2[2]-x2[1]*y[2]) + x2[0]*(y[1]*x1[2]-x1[1]*y[2]))/denom); - p1 = (float)(((y[1]*x2[2]-x2[1]*y[2]) - y[0]*(x2[2]-x2[1]*1) + x2[0]*(y[2]-y[1]*1))/denom); - p2 = (float)(((x1[1]*y[2]-y[1]*x1[2]) - x1[0]*(y[2]-y[1]*1) + y[0]*(x1[2]-x1[1]*1))/denom); - - // Calculate the maximum of the polynomial. - return (p0 - p1*p1/(4*p2)); -} - -float calculateP3(const short &x0, int *y, float &p0, float &p1, float &p2, float &p3){ - double x1[4], x2[4], x3[4]; - for(size_t i = 0; i < 4; i++){ - x1[i] = (x0+i); - x2[i] = std::pow(x0+i, 2); - x3[i] = std::pow(x0+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])); - - p0 = (float)((y[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])) - - y[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])) + - y[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])) - - y[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); - p1 = (float)(((y[1]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[1]*x3[3]-x2[3]*x3[1]) + y[3]*(x2[1]*x3[2]-x2[2]*x3[1])) - - (y[0]*(x2[2]*x3[3]-x2[3]*x3[2]) - y[2]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[2]-x2[2]*x3[0])) + - (y[0]*(x2[1]*x3[3]-x2[3]*x3[1]) - y[1]*(x2[0]*x3[3]-x2[3]*x3[0]) + y[3]*(x2[0]*x3[1]-x2[1]*x3[0])) - - (y[0]*(x2[1]*x3[2]-x2[2]*x3[1]) - y[1]*(x2[0]*x3[2]-x2[2]*x3[0]) + y[2]*(x2[0]*x3[1]-x2[1]*x3[0]))) / denom); - p2 = (float)(((x1[1]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[1]*x3[3]-y[3]*x3[1]) + x1[3]*(y[1]*x3[2]-y[2]*x3[1])) - - (x1[0]*(y[2]*x3[3]-y[3]*x3[2]) - x1[2]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[2]-y[2]*x3[0])) + - (x1[0]*(y[1]*x3[3]-y[3]*x3[1]) - x1[1]*(y[0]*x3[3]-y[3]*x3[0]) + x1[3]*(y[0]*x3[1]-y[1]*x3[0])) - - (x1[0]*(y[1]*x3[2]-y[2]*x3[1]) - x1[1]*(y[0]*x3[2]-y[2]*x3[0]) + x1[2]*(y[0]*x3[1]-y[1]*x3[0]))) / denom); - p3 = (float)(((x1[1]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[1]*y[3]-x2[3]*y[1]) + x1[3]*(x2[1]*y[2]-x2[2]*y[1])) - - (x1[0]*(x2[2]*y[3]-x2[3]*y[2]) - x1[2]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[2]-x2[2]*y[0])) + - (x1[0]*(x2[1]*y[3]-x2[3]*y[1]) - x1[1]*(x2[0]*y[3]-x2[3]*y[0]) + x1[3]*(x2[0]*y[1]-x2[1]*y[0])) - - (x1[0]*(x2[1]*y[2]-x2[2]*y[1]) - x1[1]*(x2[0]*y[2]-x2[2]*y[0]) + x1[2]*(x2[0]*y[1]-x2[1]*y[0]))) / denom); - - // Calculate the maximum of the polynomial. - float xmax1 = (-2*p2+std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); - float xmax2 = (-2*p2-std::sqrt(4*p2*p2-12*p3*p1))/(6*p3); - - if((2*p2+6*p3*xmax1) < 0) // The second derivative is negative (i.e. this is a maximum). - return (p0 + p1*xmax1 + p2*xmax1*xmax1 + p3*xmax1*xmax1*xmax1); - - return (p0 + p1*xmax2 + p2*xmax2*xmax2 + p3*xmax2*xmax2*xmax2); -} +} \ No newline at end of file diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index ebe82e660..273d0938b 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -2,7 +2,6 @@ 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 +30,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 diff --git a/Scan/utkscan/analyzers/CMakeLists.txt b/Scan/utkscan/analyzers/CMakeLists.txt index 26e716984..b7307a5f4 100644 --- a/Scan/utkscan/analyzers/CMakeLists.txt +++ b/Scan/utkscan/analyzers/CMakeLists.txt @@ -1,5 +1 @@ -add_subdirectory(source) - -if(BUILD_UTKSCAN_TESTS) - add_subdirectory(tests) -endif(BUILD_UTKSCAN_TESTS) \ No newline at end of file +add_subdirectory(source) \ No newline at end of file diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index cf080b92d..c66eb5beb 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -12,7 +12,7 @@ #include -#include "FitDriver.hpp" +#include "TimingAnalysisDriver.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" diff --git a/Scan/utkscan/analyzers/source/CMakeLists.txt b/Scan/utkscan/analyzers/source/CMakeLists.txt index f6862fdac..36e0e5517 100644 --- a/Scan/utkscan/analyzers/source/CMakeLists.txt +++ b/Scan/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/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp index 397e620c8..463149453 100644 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp @@ -16,7 +16,7 @@ #include #include "DammPlotIds.hpp" -#include "FitDriver.hpp" +#include "TimingAnalysisDriver.hpp" #include "FittingAnalyzer.hpp" #include "GslFitter.hpp" diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index 0f0f584b1..68db28f72 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -96,100 +96,4 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, 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); -} From 7dbdc4e4ca29ec018f08a05b3742f04f29d9fb9c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Thu, 15 Dec 2016 15:31:52 -0500 Subject: [PATCH 058/255] Updated helper functions to add the TailRatio calculation Former-commit-id: 53660cce9b5196d055d9a70ad9b4a915bf2b4b2f --- Scan/Resources/include/HelperFunctions.hpp | 66 +++++++++---------- .../tests/unittest-HelperFunctions.cpp | 30 +++++++-- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index 26a02f6a3..01c03fc45 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -371,6 +371,9 @@ namespace TraceFunctions { return val; } + ///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. inline double CalculateQdc(const vector &data, const pair &range) { stringstream msg; @@ -388,48 +391,39 @@ namespace TraceFunctions { vector(data.begin() + range.first, data.begin() + range.second)); } -/* - - 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_); - } - } - + 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."); - //Subtract the baseline from the full trace qdc - sum -= mean_ * trc_->size(); + return Statistics::CalculateIntegral( + vector(data.begin() + range.first, + data.begin() + range.second)) / qdc; - 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); - } + ///@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 { -*/ + + } } #endif //PIXIESUITE_HELPERFUNCTIONS_HPP diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index 670abeac8..b7f608ac6 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -24,7 +24,6 @@ static const vector data = { 446, 441, 440, 444, 456, 459, 451, 450, 447, 445, 449, 456, 456, 455 }; - //An empty data vector to test error checking. static const vector empty_data; //A data vector that contains constant data. @@ -44,8 +43,8 @@ static const double expected_maximum_value = 3816; //This is the expected position of the maximum static const unsigned int expected_max_position = 76; //This is the pair made from the expected maximum information -static const pair expected_max_info = - make_pair(expected_max_position, expected_maximum_value); +static const pair expected_max_info(expected_max_position, + expected_maximum_value); ///This tests that the TraceFunctions::CalculateBaseline function works as /// expected. This also verifies the Statistics functions CalculateAverage @@ -206,13 +205,32 @@ TEST(TestCalculateIntegral) { TEST(TestCalculateQdc) { static const double expected = 6; //Check that we are throwing an error when the data is empty - CHECK_THROW(TraceFunctions::CalculateQdc(empty_data, make_pair(0,4)), + CHECK_THROW(TraceFunctions::CalculateQdc(empty_data, make_pair(0, 4)), range_error); //Check that we are throwing an error when the range is too large - CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(0,1000)), + CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(0, 1000)), range_error); CHECK_EQUAL(expected, TraceFunctions::CalculateQdc - (integration_data, make_pair(2,5))); + (integration_data, make_pair(2, 5))); +} + +TEST(TestCalculateTailRatio) { + static const double expected_ratio = 0.2960894762; + //Check that we are throwing an error when the data is empty + CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_data, make_pair(0, 4), + 100.0), range_error); + //Check that the upper bound of the range is not too big + CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_data, + make_pair(0, 400), 100.0), + range_error); + //Check that the QDC we passed actually makes sense + CHECK_THROW(TraceFunctions::CalculateTailRatio(data, make_pair(0, 4), + 0.0), range_error); + + double qdc = TraceFunctions::CalculateQdc(data, make_pair(70, 91)); + pair range(80, 91); + double result = TraceFunctions::CalculateTailRatio(data, range, qdc); + CHECK_CLOSE(expected_ratio, result, 1e-6); } int main(int argv, char *argc[]) { From f73fdf0b63881013d938c8ca083ccd28c778882c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Thu, 15 Dec 2016 16:44:38 -0500 Subject: [PATCH 059/255] Templating the helper functions for more flexibility Former-commit-id: 2ae4fb67ba204761e39a0e62c1df7aad962fb0a0 --- Scan/Resources/include/HelperFunctions.hpp | 39 +++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index 01c03fc45..c4a7f6d38 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -162,9 +162,10 @@ namespace Polynomial { }//Polynomial namespace namespace Statistics { - inline double CalculateAverage(const vector &data) { + template + inline double CalculateAverage(const vector &data) { double sum = 0.0; - for (vector::const_iterator i = data.begin(); + for (typename vector::const_iterator i = data.begin(); i != data.end(); i++) sum += *i; sum /= data.size(); @@ -173,10 +174,11 @@ namespace Statistics { //This calculation for the standard deviation assumes that we are // analyzing the full population, which we are in this case. - inline double CalculateStandardDeviation(const vector &data, + template + inline double CalculateStandardDeviation(const vector &data, const double &mean) { double stddev = 0.0; - for (vector::const_iterator it = data.begin(); + for (typename vector::const_iterator it = data.begin(); it != data.end(); it++) stddev += pow(*it - mean, 2); stddev = sqrt(stddev / (double) data.size()); @@ -188,7 +190,8 @@ namespace Statistics { /// like that to keep things general. ///@param[in] data : The data that we want to integrate. ///@return The integrated value - inline double CalculateIntegral(const vector &data) { + 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 " @@ -215,7 +218,8 @@ namespace TraceFunctions { ///@return A pair with the first element being the average of the /// baseline and the second element being the standard deviation of the /// baseline. - inline pair CalculateBaseline(const vector + template + inline pair CalculateBaseline(const vector &data, const pair @@ -238,11 +242,11 @@ namespace TraceFunctions { " necessary range."); double baseline = Statistics::CalculateAverage( - vector(data.begin(), data.begin() + + vector(data.begin(), data.begin() + range.second)); double stddev = Statistics::CalculateStandardDeviation( - vector(data.begin(), data.begin() + + vector(data.begin(), data.begin() + range.second), baseline); return make_pair(baseline, stddev); @@ -258,8 +262,9 @@ namespace TraceFunctions { /// @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 &data, const pair &maxInfo) { if (data.size() < 4) throw range_error("TraceFunctions::ExtrapolateMaximum - " @@ -295,8 +300,9 @@ namespace TraceFunctions { /// 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 vector &data, const unsigned int &traceDelayInBins) { stringstream msg; if (data.size() == 0) @@ -324,7 +330,7 @@ namespace TraceFunctions { // 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. - vector::const_iterator itPos = + typename vector::const_iterator itPos = max_element(data.begin() + minimum_baseline_length, data.begin() + traceDelayInBins); @@ -374,7 +380,8 @@ namespace TraceFunctions { ///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. - inline double CalculateQdc(const vector &data, + template + inline double CalculateQdc(const vector &data, const pair &range) { stringstream msg; if (data.size() == 0) @@ -386,13 +393,13 @@ namespace TraceFunctions { << "," << range.second << "]."; throw range_error(msg.str()); } - vector tmp(); return Statistics::CalculateIntegral( - vector(data.begin() + range.first, + vector(data.begin() + range.first, data.begin() + range.second)); } - inline double CalculateTailRatio(const vector &data, + template + inline double CalculateTailRatio(const vector &data, const pair &range, const double &qdc) { stringstream msg; @@ -411,7 +418,7 @@ namespace TraceFunctions { "issues."); return Statistics::CalculateIntegral( - vector(data.begin() + range.first, + vector(data.begin() + range.first, data.begin() + range.second)) / qdc; } From f76d5082b7700e4c62c4256b8388cee9a3ba99e8 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Thu, 15 Dec 2016 16:45:00 -0500 Subject: [PATCH 060/255] Forgot to template the Polynomial functions Former-commit-id: fc89854b7e00f6029e57a7b80263a2c2d40f70f6 --- Scan/Resources/include/HelperFunctions.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index c4a7f6d38..5239a8dae 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -17,8 +17,9 @@ using namespace std; namespace Polynomial { + template static const pair > CalculatePoly2( - const vector &data, const unsigned int &startBin) { + const vector &data, const unsigned int &startBin) { double x1[3], x2[3]; for (size_t i = 0; i < 3; i++) { x1[i] = (startBin + i); @@ -52,8 +53,9 @@ namespace Polynomial { return make_pair(p0 - p1 * p1 / (4 * p2), coeffs); } + template static const pair > CalculatePoly3( - const vector &data, const unsigned int &startBin) { + 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()); From d7c0bf9d6ca97e74b903c1599775ac5ba3373d35 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sun, 18 Dec 2016 15:16:15 -0500 Subject: [PATCH 061/255] FitDriver is now TimingDriver. Adding and updating tests Former-commit-id: 298bc1fe526bebb1a0a40b1d6064f592fad8420c --- Scan/Resources/include/GslFitter.hpp | 58 ++++--- Scan/Resources/include/HelperFunctions.hpp | 3 +- Scan/Resources/include/PolynomialCfd.hpp | 24 +++ .../include/PolynomialCfdCalculator.hpp | 22 --- Scan/Resources/include/TimingDriver.hpp | 79 ++++----- Scan/Resources/source/CMakeLists.txt | 2 +- Scan/Resources/source/Gsl2Fitter.cpp | 161 +++++++++--------- Scan/Resources/source/PolynomialCfd.cpp | 44 +++++ .../source/PolynomialCfdCalculator.cpp | 38 ----- Scan/Resources/tests/CMakeLists.txt | 5 + Scan/Resources/tests/test_gslfitter.cpp | 35 ++-- .../tests/unittest-HelperFunctions.cpp | 4 +- .../tests/unittest-PolynomialCfd.cpp | 66 +++++++ 13 files changed, 314 insertions(+), 227 deletions(-) create mode 100644 Scan/Resources/include/PolynomialCfd.hpp delete mode 100644 Scan/Resources/include/PolynomialCfdCalculator.hpp create mode 100644 Scan/Resources/source/PolynomialCfd.cpp delete mode 100644 Scan/Resources/source/PolynomialCfdCalculator.cpp create mode 100644 Scan/Resources/tests/unittest-PolynomialCfd.cpp diff --git a/Scan/Resources/include/GslFitter.hpp b/Scan/Resources/include/GslFitter.hpp index 12a6ab0bf..bb7939963 100644 --- a/Scan/Resources/include/GslFitter.hpp +++ b/Scan/Resources/include/GslFitter.hpp @@ -1,9 +1,10 @@ -/// \file GslFitter.hpp -/// \brief Implementation of the GSL fitting routine for GSL v2+ -/// \author S. V. Paulauskas -/// \date August 8, 2016 +/// @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 @@ -17,29 +18,31 @@ class GslFitter : public TimingDriver { public: ///Default Constructor - GslFitter() : TimingDriver() {}; + GslFitter() : TimingDriver() { isFastSiPm_ = false; } + ///Default Destructor - ~GslFitter() {}; - - ///\return the phase from the GSL fit - double GetPhase(void){return phase_;} - ///\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 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 - void PerformFit(const std::vector &data, - const std::pair &pars, - const bool &isSipmFast = false, - const double &weight = 1., - const double &area = 1.); - - //! Structure necessary for the GSL fitting routines + ~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 data that we would like to try and fit + /// @param[in] pars The parameters for the fit + double CalculatePhase(const std::vector &data, + const std::pair &pars); + + ///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 @@ -49,10 +52,11 @@ class GslFitter : public TimingDriver { double qdc;//!< the QDC for the fit }; private: + bool isFastSiPm_; + double amp_; double chi_; double dof_; - double phase_; }; diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index 5239a8dae..c4aea9127 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -346,7 +346,8 @@ namespace TraceFunctions { return make_pair((unsigned int) (itPos - data.begin()), *itPos); } - inline unsigned int FindLeadingEdge(const vector &data, + template + inline unsigned int FindLeadingEdge(const vector &data, const double &threshold, const pair &maxInfo) { if (threshold <= 0) diff --git a/Scan/Resources/include/PolynomialCfd.hpp b/Scan/Resources/include/PolynomialCfd.hpp new file mode 100644 index 000000000..dd26a1ef0 --- /dev/null +++ b/Scan/Resources/include/PolynomialCfd.hpp @@ -0,0 +1,24 @@ +/// @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 + +#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 &maxInfo); +}; + +#endif //PIXIESUITE_POLYNOMIALCFD_HPP diff --git a/Scan/Resources/include/PolynomialCfdCalculator.hpp b/Scan/Resources/include/PolynomialCfdCalculator.hpp deleted file mode 100644 index ef794624d..000000000 --- a/Scan/Resources/include/PolynomialCfdCalculator.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Created by vincent on 12/6/16. -// - -#ifndef PIXIESUITE_POLYNOMIALCFDCALCULATOR_HPP -#define PIXIESUITE_POLYNOMIALCFDCALCULATOR_HPP - -#include - -class PolynomialCfdCalculator : public CfdDriver { -public: - PolynomialCfdCalculator(){}; - ~PolynomialCfdCalculator(){}; - - /// Perform CFD analysis on the waveform using the pol2 algorithm. - double AnalyzeCFD(const double &f = 0.5, - vector &trc, const - double &maximum, - const double &baseline); -}; - -#endif //PIXIESUITE_POLYNOMIALCFD_HPP diff --git a/Scan/Resources/include/TimingDriver.hpp b/Scan/Resources/include/TimingDriver.hpp index a6274b608..84e1ee76a 100644 --- a/Scan/Resources/include/TimingDriver.hpp +++ b/Scan/Resources/include/TimingDriver.hpp @@ -5,6 +5,7 @@ #ifndef PIXIESUITE_TIMINGDRIVER_HPP #define PIXIESUITE_TIMINGDRIVER_HPP + #include #include @@ -13,50 +14,50 @@ class TimingDriver { public: ///Default Constructor TimingDriver() {}; - ///Default destructor - virtual ~TimingDriver(){}; - - /// 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.;} + ///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. NOTE : The + /// value of the maximum for CFD based calculations should be the + /// extrapolated maximum. + ///@return The phase calculated by the algorithm. virtual double CalculatePhase(const std::vector &data, - const std::pair &pars, - const double &maxPosition) {} - - ///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 bool &isFastSipm, - const double &weight = 1., - const double &area = 1.) {} - - /// 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;} + const std::pair &pars, + const std::pair &maxInfo) { + return 0.0; + } + /// We set the information about the baseline. + /// @param[in] a : The baseline information in a pair + void SetBaseline(const std::pair &a) { baseline_ = a; } + + /// 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 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 + std::pair baseline_; //!< The baseline and stddev + std::vector results_; //!< Vector containing results double qdc_;//!< qdc of the waveform being fitted }; + #endif //PIXIESUITE_TIMINGDRIVER_HPP diff --git a/Scan/Resources/source/CMakeLists.txt b/Scan/Resources/source/CMakeLists.txt index 74f392fe7..a35a49c5f 100644 --- a/Scan/Resources/source/CMakeLists.txt +++ b/Scan/Resources/source/CMakeLists.txt @@ -1,5 +1,5 @@ #Set the utility sources that we will make a lib out of -set(UtilitySources PolynomialCfdCalculator.cpp) +set(UtilitySources PolynomialCfd.cpp) if(USE_GSL) if(${GSL_VERSION} GREATER 1.9) diff --git a/Scan/Resources/source/Gsl2Fitter.cpp b/Scan/Resources/source/Gsl2Fitter.cpp index 1629006d6..b27d3d90d 100644 --- a/Scan/Resources/source/Gsl2Fitter.cpp +++ b/Scan/Resources/source/Gsl2Fitter.cpp @@ -10,18 +10,21 @@ * \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 @@ -31,18 +34,15 @@ 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 bool & isSipmFast/*= false */, - const double &weight/* = 1.*/, - const double &area/* = 1.*/) { +double GslFitter::CalculatePhase(const std::vector &data, + const std::pair &pars) { gsl_multifit_function_fdf f; int info; const size_t n = data.size(); size_t p; double xInit[3]; - if(!isSipmFast) { + if (!isFastSiPm_) { p = 2; xInit[0] = 0.0; xInit[1] = 2.5; @@ -51,7 +51,7 @@ void GslFitter::PerformFit(const std::vector &data, f.df = &CalcPmtJacobian; } else { p = 1; - xInit[0] = (double)data.size()*0.5; + xInit[0] = (double) data.size() * 0.5; f.f = &SiPmtFunction; f.df = &CalcSiPmtJacobian; @@ -61,13 +61,13 @@ void GslFitter::PerformFit(const std::vector &data, 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); + gsl_matrix *jac = gsl_matrix_alloc(n, p); + gsl_matrix *covar = gsl_matrix_alloc(p, p); double y[n], weights[n]; struct 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); + 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; @@ -78,119 +78,126 @@ void GslFitter::PerformFit(const std::vector &data, f.p = p; f.params = &fitData; - for(unsigned int i = 0; i < n; i++) { - weights[i] = weight; - y[i] = data[i]; + for (unsigned int i = 0; i < n; i++) { + weights[i] = baseline_.second; + y[i] = data[i] - baseline_.first; } - gsl_multifit_fdfsolver_wset (s, &f, &x.vector, &w.vector); + 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_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(!isSipmFast) { - phase_ = gsl_vector_get(s->x,0); - amp_ = gsl_vector_get(s->x,1); + 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); + phase = gsl_vector_get(s->x, 0); amp_ = 0.0; } - gsl_multifit_fdfsolver_free (s); - gsl_matrix_free (covar); + + gsl_multifit_fdfsolver_free(s); + gsl_matrix_free(covar); gsl_matrix_free(jac); + + return phase; } -int PmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct TimingDriver::FitData *)FitData)->n; - double *y = ((struct TimingDriver::FitData *)FitData)->y; - double beta = ((struct TimingDriver::FitData *)FitData)->beta; - double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; - double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; +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); + double phi = gsl_vector_get(x, 0); + double alpha = gsl_vector_get(x, 1); - for(size_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { double t = i; - double diff = t-phi; + double diff = t - phi; double Yi = 0; - if(t < phi) + if (t < phi) Yi = 0; else - Yi = qdc * alpha * exp(-beta*diff) * (1-exp(-pow(gamma*diff,4.))); + Yi = qdc * alpha * exp(-beta * diff) * + (1 - exp(-pow(gamma * diff, 4.))); - gsl_vector_set (f, i, Yi - y[i]); + gsl_vector_set(f, i, Yi - y[i]); } - return(GSL_SUCCESS); + return (GSL_SUCCESS); } -int CalcPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct TimingDriver::FitData *)FitData)->n; - double beta = ((struct TimingDriver::FitData *)FitData)->beta; - double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; - double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; +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 phi = gsl_vector_get(x, 0); + double alpha = gsl_vector_get(x, 1); double dphi, dalpha; - for(size_t i = 0; i < n; i++) { + 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; + 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); + 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); + gsl_matrix_set(J, i, 0, dphi); + gsl_matrix_set(J, i, 1, dalpha); } - return(GSL_SUCCESS); + return (GSL_SUCCESS); } -int SiPmtFunction (const gsl_vector * x, void *FitData, gsl_vector * f) { - size_t n = ((struct TimingDriver::FitData *)FitData)->n; - double *y = ((struct TimingDriver::FitData *)FitData)->y; - double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; - double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; +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); + double phi = gsl_vector_get(x, 0); - for(size_t i = 0; i < n; i++) { + 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]); + 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); + return (GSL_SUCCESS); } -int CalcSiPmtJacobian (const gsl_vector * x, void *FitData, gsl_matrix * J) { - size_t n = ((struct TimingDriver::FitData *)FitData)->n; - double gamma = ((struct TimingDriver::FitData *)FitData)->gamma; - double qdc = ((struct TimingDriver::FitData *)FitData)->qdc; +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 phi = gsl_vector_get(x, 0); double dphi; for (size_t i = 0; i < n; i++) { double t = i; - double diff = t-phi; + double diff = t - phi; - dphi = (qdc*diff/(pow(gamma,3)*sqrt(2*M_PI))) * - exp(-diff*diff/(2*gamma*gamma)); + dphi = (qdc * diff / (pow(gamma, 3) * sqrt(2 * M_PI))) * + exp(-diff * diff / (2 * gamma * gamma)); - gsl_matrix_set (J,i,0, dphi); + gsl_matrix_set(J, i, 0, dphi); } - return(GSL_SUCCESS); + return (GSL_SUCCESS); } diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Scan/Resources/source/PolynomialCfd.cpp new file mode 100644 index 000000000..a04751630 --- /dev/null +++ b/Scan/Resources/source/PolynomialCfd.cpp @@ -0,0 +1,44 @@ +/// @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 &maxInfo) { + if (data.size() == 0) + throw range_error("PolynomialCfd::CalculatePhase - The data vector " + "was empty!"); + if (data.size() < maxInfo.first) + throw range_error("PolynomialCfd::CalculatePhase - The maximum " + "position is larger than the size of the " + "data vector."); + + double threshold = pars.first * maxInfo.second; + double phase = -9999; + + vector result; + + for (unsigned int cfdIndex = maxInfo.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. + phase = (-result[1] + std::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/Scan/Resources/source/PolynomialCfdCalculator.cpp b/Scan/Resources/source/PolynomialCfdCalculator.cpp deleted file mode 100644 index 5af8d995d..000000000 --- a/Scan/Resources/source/PolynomialCfdCalculator.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Created by vincent on 12/6/16. -// -#include - -#include "HelperFunctions.hpp" - -using namespace std; - -/// Perform CFD analysis on the waveform. -double PolynomialCfdCalculator::AnalyzeCFD(const double &f/*=0.5*/, - vector &trc, const - double &maximum, - const double &baseline) { - if (size == 0 || baseline < 0) { return -9999; } - - double threshold = f * maximum + baseline; - double phase = -9999; - vector coeffs; - for (unsigned int cfdIndex = max_index; cfdIndex > 0; cfdIndex--) { - if (event->adcTrace[cfdIndex - 1] < threshold && - event->adcTrace[cfdIndex] >= threshold) { - // Fit the rise of the trace to a 2nd order polynomial. - coeffs = Polynomial::CalculatePoly2(cfdIndex - 1, - &event->adcTrace.data()[cfdIndex - 1], - coeffs); - - // Calculate the phase of the trace. - phase = (-cfdPar[5] + std::sqrt(cfdPar[5] * cfdPar[5] - - 4 * cfdPar[6] * - (cfdPar[4] - threshold))) / - (2 * cfdPar[6]); - - break; - } - } - return phase; -} \ No newline at end of file diff --git a/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index ee7b444be..5ffc086ad 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -15,4 +15,9 @@ if(BUILD_UNITTESTS) add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) target_link_libraries(unittest-HelperFunctions UnitTest++) install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) + + add_executable(unittest-PolynomialCfd unittest-PolynomialCfd.cpp + ../source/PolynomialCfd.cpp) + target_link_libraries(unittest-PolynomialCfd UnitTest++) + install(TARGETS unittest-PolynomialCfd DESTINATION bin/unittests) endif(BUILD_UNITTESTS) \ No newline at end of file diff --git a/Scan/Resources/tests/test_gslfitter.cpp b/Scan/Resources/tests/test_gslfitter.cpp index 3900b0a64..caad00983 100644 --- a/Scan/Resources/tests/test_gslfitter.cpp +++ b/Scan/Resources/tests/test_gslfitter.cpp @@ -12,36 +12,31 @@ 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; + pair baseline(436.742857142857, 1.9761847389475); + //Set the for the fitting + pair pars(0.2659404170, 0.208054799179688); + //Qdc of the trace is necessary to initialization of the fit + double area = 21329.85714285; //Raw data that we want to fit - This is a VANDLE trace - vector data{ + 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; + fitter.SetBaseline(baseline); + fitter.SetQdc(area); + + double phase; //Actually perform the fitting + ///@TODO : We should never catch ALL throws using this syntax. It's bad + /// practice. Until we can figure out what to throw here then we'll leave + /// it. try { - fitter.PerformFit(data, pars, isSiPmTiming, weight, area); + phase = fitter.CalculatePhase(data, pars); } catch(...) { cerr << "Something went wrong with the fit" << endl; } @@ -51,5 +46,5 @@ int main(int argc, char *argv[]) { << "Amplitude from Gnuplot = 0.8565802" << endl << "Amplitude = " << fitter.GetAmplitude() << endl << "Phase from Gnuplot = -0.0826487" << endl - << "Phase = " << fitter.GetPhase() << endl; + << "Phase = " << phase << endl; } \ No newline at end of file diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index b7f608ac6..75eba24b5 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -118,12 +118,12 @@ TEST(TestFindLeadingEdge) { 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_data, 0.05, + CHECK_THROW(TraceFunctions::FindLeadingEdge(empty_data, 0.5, expected_max_info), 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(const_data, 0.05, + CHECK_THROW(TraceFunctions::FindLeadingEdge(const_data, 0.5, make_pair(2000, 3)), range_error); diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Scan/Resources/tests/unittest-PolynomialCfd.cpp new file mode 100644 index 000000000..13f63cadb --- /dev/null +++ b/Scan/Resources/tests/unittest-PolynomialCfd.cpp @@ -0,0 +1,66 @@ +///@file unittest-HelperFunctions.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include +#include +#include +#include + +#include + +#include "PolynomialCfd.hpp" + +using namespace std; + +//This is a trace taken from a medium VANDLE module. +static const vector data = { + 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 +}; + +//An empty data vector to test error checking. +static const vector empty_data; + +//The expected maximum from the poly3 fitting +static const double expected_poly3_val = 3818.0718412264; +//This is the expected position of the maximum +static const unsigned int expected_max_position = 76; +//This is the pair made from the expected maximum information +static const pair + expected_max_info(expected_max_position, expected_poly3_val); + +//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 expected_baseline = 436.7428571; +//The expected standard deviation was obtained using the STDEVP function in +// Google Sheets. +static const double expected_standard_deviation = 1.976184739; + +TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { + static const pair pars(0.5, 2.); + + //Checking that we throw a range_error when the data vector is zero + CHECK_THROW(CalculatePhase(empty_data, pars, expected_max_info), + range_error); + + //Checking that we throw a range_error when the max index is too large + // for the data + + static const pair tmp(1000, expected_poly3_val); + CHECK_THROW(CalculatePhase(data, pars, tmp), range_error); + + CHECK(-9999 != CalculatePhase(data, pars, expected_max_info)); + cout << CalculatePhase(data, pars, expected_max_info) << endl; +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file From 74ddec424fe05499568a29d50d23053b3abb6c04 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sun, 18 Dec 2016 15:31:18 -0500 Subject: [PATCH 062/255] Fixing variable length array warning. Former-commit-id: bad246a41d65ca648825b231c09399ff46f3e10a --- Scan/Resources/source/Gsl2Fitter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scan/Resources/source/Gsl2Fitter.cpp b/Scan/Resources/source/Gsl2Fitter.cpp index b27d3d90d..8f1ebcaf0 100644 --- a/Scan/Resources/source/Gsl2Fitter.cpp +++ b/Scan/Resources/source/Gsl2Fitter.cpp @@ -63,7 +63,8 @@ double GslFitter::CalculatePhase(const std::vector &data, 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]; + 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); @@ -103,6 +104,8 @@ double GslFitter::CalculatePhase(const std::vector &data, gsl_multifit_fdfsolver_free(s); gsl_matrix_free(covar); gsl_matrix_free(jac); + delete y; + delete weights; return phase; } From ba691f932158c93bd7ea2f19bc7b77076e54bd6c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sun, 18 Dec 2016 16:31:50 -0500 Subject: [PATCH 063/255] Moving Trace Information for Unittests to dedicated file This reduces the overall number of lines in the code since we do not have to constantly repeat the same information for the tests. Former-commit-id: ce724cbee027d9322b156cdce642262c9f31ffb9 --- .../include/UnitTestExampleTrace.hpp | 44 ++++++++++++ .../tests/unittest-HelperFunctions.cpp | 71 +------------------ .../tests/unittest-PolynomialCfd.cpp | 44 +++--------- 3 files changed, 55 insertions(+), 104 deletions(-) create mode 100644 Scan/Resources/include/UnitTestExampleTrace.hpp diff --git a/Scan/Resources/include/UnitTestExampleTrace.hpp b/Scan/Resources/include/UnitTestExampleTrace.hpp new file mode 100644 index 000000000..e3b89d62c --- /dev/null +++ b/Scan/Resources/include/UnitTestExampleTrace.hpp @@ -0,0 +1,44 @@ +// +// Created by vincent on 12/18/16. +// + +#ifndef PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP +#define PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP + +//This is a trace taken from a medium VANDLE module. +static const vector data = { + 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 +}; + +//An empty data vector to test error checking. +static const vector empty_data; +//A data vector that contains constant data. +static const vector const_data = {1000, 4}; +//A data vector to test the integration +static const vector integration_data = {0, 1, 2, 3, 4, 5}; +//The expected value from the CalculateIntegral function +static const double expected_integral = 12.5; + +//The expected maximum from the poly3 fitting +static const double expected_poly3_val = 3818.0718412264; +//The expected maximum from the pol2 fitting +static const double expected_poly2_val = 10737.0720588236; + +//This is the expected value of the maximum +static const double expected_maximum_value = 3816; +//This is the expected position of the maximum +static const unsigned int expected_max_position = 76; +//This is the pair made from the expected maximum information +static const pair expected_max_info(expected_max_position, + expected_maximum_value); + + +#endif //PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index 75eba24b5..063ee20c2 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -1,63 +1,18 @@ ///@file unittest-HelperFunctions.cpp ///@author S. V. Paulauskas ///@date December 12, 2016 -#include -#include -#include - #include #include "HelperFunctions.hpp" +#include "UnitTestExampleTrace.hpp" using namespace std; - -//This is a trace taken from a medium VANDLE module. -static const vector data = { - 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 -}; - -//An empty data vector to test error checking. -static const vector empty_data; -//A data vector that contains constant data. -static const vector const_data = {1000, 4}; -//A data vector to test the integration -static const vector integration_data = {0, 1, 2, 3, 4, 5}; -//The expected value from the CalculateIntegral function -static const double expected_integral = 12.5; - -//The expected maximum from the poly3 fitting -static const double expected_poly3_val = 3818.0718412264; -//The expected maximum from the pol2 fitting -static const double expected_poly2_val = 10737.0720588236; - -//This is the expected value of the maximum -static const double expected_maximum_value = 3816; -//This is the expected position of the maximum -static const unsigned int expected_max_position = 76; -//This is the pair made from the expected maximum information -static const pair expected_max_info(expected_max_position, - expected_maximum_value); +using namespace unittest_trace_variables; ///This tests that the TraceFunctions::CalculateBaseline function works as /// expected. This also verifies the Statistics functions CalculateAverage /// and CalculateStandardDeviation TEST(TestCalculateBaseline) { - //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 expected_baseline = 436.7428571; - //The expected standard deviation was obtained using the STDEVP function in - // Google Sheets. - static const double expected_standard_deviation = 1.976184739; - //Checking that we throw a range_error when the range is too small CHECK_THROW(TraceFunctions::CalculateBaseline(data, make_pair(0, 1)), range_error); @@ -83,8 +38,6 @@ TEST(TestCalculateBaseline) { } TEST(TestFindMaxiumum) { - static const unsigned int trace_delay = 80; - //Checking that we throw a range_error when the data vector is sized 0 CHECK_THROW(TraceFunctions::FindMaximum(empty_data, trace_delay), range_error); @@ -135,14 +88,6 @@ TEST(TestFindLeadingEdge) { } TEST(TestCalculatePoly3) { - //A data vector that contains only the four points for the Poly3 Fitting. - static const vector poly3_data(data.begin() + 74, - data.begin() + 78); - //A vector containing the coefficients obtained from gnuplot using the data - // from pol3_data with an x value starting at 0 - static const vector expected_poly3_coeffs = - {2358.0, 1635.66666666667, -516.0, 31.3333333333333}; - //Check that we throw an error when the passed data vector is too small. CHECK_THROW(Polynomial::CalculatePoly3(empty_data, 0), range_error); @@ -161,10 +106,6 @@ TEST(TestCalculatePoly3) { //For determination of the maximum value of the trace this traces favors the // left side since max+1 is less than max - 1 TEST(TestExtrapolateMaximum) { - static const vector expected_coeffs = - {-15641316.0007084, 592747.666694852, -7472.00000037373, - 31.3333333349849}; - //Check that we throw an error when the passed data vector is too small. CHECK_THROW(TraceFunctions::ExtrapolateMaximum(empty_data, expected_max_info), @@ -182,13 +123,6 @@ TEST(TestExtrapolateMaximum) { } TEST(TestCalculatePoly2) { - //A data vector containing only the three points for the Poly2 fitting - static const vector poly2_data(data.begin() + 73, - data.begin() + 75); - //Vector containing the expected coefficients from the poly 2 fit - static const vector expected_poly2_coeffs = - {1122.0, 1278.5, -42.4999999999999}; - pair > result = Polynomial::CalculatePoly2(poly2_data, 0); @@ -215,7 +149,6 @@ TEST(TestCalculateQdc) { } TEST(TestCalculateTailRatio) { - static const double expected_ratio = 0.2960894762; //Check that we are throwing an error when the data is empty CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_data, make_pair(0, 4), 100.0), range_error); diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Scan/Resources/tests/unittest-PolynomialCfd.cpp index 13f63cadb..3261c3043 100644 --- a/Scan/Resources/tests/unittest-PolynomialCfd.cpp +++ b/Scan/Resources/tests/unittest-PolynomialCfd.cpp @@ -2,53 +2,27 @@ ///@author S. V. Paulauskas ///@date December 12, 2016 #include -#include #include #include #include #include "PolynomialCfd.hpp" +#include "UnitTestExampleTrace.hpp" using namespace std; +using namespace unittest_trace_variables; -//This is a trace taken from a medium VANDLE module. -static const vector data = { - 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 -}; - -//An empty data vector to test error checking. -static const vector empty_data; - -//The expected maximum from the poly3 fitting -static const double expected_poly3_val = 3818.0718412264; -//This is the expected position of the maximum -static const unsigned int expected_max_position = 76; -//This is the pair made from the expected maximum information -static const pair - expected_max_info(expected_max_position, expected_poly3_val); - -//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 expected_baseline = 436.7428571; -//The expected standard deviation was obtained using the STDEVP function in -// Google Sheets. -static const double expected_standard_deviation = 1.976184739; +//This pair provides us with the expected extrapolated maximum and the +// position of the maximum. +static const pair max_info(expected_max_position, + expected_poly3_val); TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { static const pair pars(0.5, 2.); //Checking that we throw a range_error when the data vector is zero - CHECK_THROW(CalculatePhase(empty_data, pars, expected_max_info), + CHECK_THROW(CalculatePhase(empty_data, pars, max_info), range_error); //Checking that we throw a range_error when the max index is too large @@ -57,8 +31,8 @@ TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { static const pair tmp(1000, expected_poly3_val); CHECK_THROW(CalculatePhase(data, pars, tmp), range_error); - CHECK(-9999 != CalculatePhase(data, pars, expected_max_info)); - cout << CalculatePhase(data, pars, expected_max_info) << endl; + CHECK(-9999 != CalculatePhase(data, pars, max_info)); + cout << CalculatePhase(data, pars, max_info) << endl; } int main(int argv, char *argc[]) { From f1a9cf577419760fc42e680fe8d955c8cc8e3086 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 19 Dec 2016 08:30:14 -0500 Subject: [PATCH 064/255] Updating example trace and TimingDriver Former-commit-id: d575f1a911e615c97f018540ce157ed28373255b --- Scan/Resources/include/PolynomialCfd.hpp | 2 - Scan/Resources/include/TimingDriver.hpp | 17 +-- .../include/UnitTestExampleTrace.hpp | 138 +++++++++++++----- 3 files changed, 111 insertions(+), 46 deletions(-) diff --git a/Scan/Resources/include/PolynomialCfd.hpp b/Scan/Resources/include/PolynomialCfd.hpp index dd26a1ef0..32b3c70c9 100644 --- a/Scan/Resources/include/PolynomialCfd.hpp +++ b/Scan/Resources/include/PolynomialCfd.hpp @@ -5,8 +5,6 @@ #ifndef PIXIESUITE_POLYNOMIALCFD_HPP #define PIXIESUITE_POLYNOMIALCFD_HPP -#include - #include "TimingDriver.hpp" class PolynomialCfd : public TimingDriver { diff --git a/Scan/Resources/include/TimingDriver.hpp b/Scan/Resources/include/TimingDriver.hpp index 84e1ee76a..633447bb6 100644 --- a/Scan/Resources/include/TimingDriver.hpp +++ b/Scan/Resources/include/TimingDriver.hpp @@ -36,26 +36,23 @@ class TimingDriver { ///@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. NOTE : The - /// value of the maximum for CFD based calculations should be the - /// extrapolated maximum. + /// @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 &maxInfo) { + const std::pair + &maxInfo, + std::pair baseline) { return 0.0; } - /// We set the information about the baseline. - /// @param[in] a : The baseline information in a pair - void SetBaseline(const std::pair &a) { baseline_ = a; } - /// 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::pair baseline_; //!< The baseline and stddev std::vector results_; //!< Vector containing results double qdc_;//!< qdc of the waveform being fitted }; diff --git a/Scan/Resources/include/UnitTestExampleTrace.hpp b/Scan/Resources/include/UnitTestExampleTrace.hpp index e3b89d62c..0484089b3 100644 --- a/Scan/Resources/include/UnitTestExampleTrace.hpp +++ b/Scan/Resources/include/UnitTestExampleTrace.hpp @@ -5,40 +5,110 @@ #ifndef PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP #define PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP -//This is a trace taken from a medium VANDLE module. -static const vector data = { - 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 -}; - -//An empty data vector to test error checking. -static const vector empty_data; -//A data vector that contains constant data. -static const vector const_data = {1000, 4}; -//A data vector to test the integration -static const vector integration_data = {0, 1, 2, 3, 4, 5}; -//The expected value from the CalculateIntegral function -static const double expected_integral = 12.5; - -//The expected maximum from the poly3 fitting -static const double expected_poly3_val = 3818.0718412264; -//The expected maximum from the pol2 fitting -static const double expected_poly2_val = 10737.0720588236; - -//This is the expected value of the maximum -static const double expected_maximum_value = 3816; -//This is the expected position of the maximum -static const unsigned int expected_max_position = 76; -//This is the pair made from the expected maximum information -static const pair expected_max_info(expected_max_position, - expected_maximum_value); +#include +#include +#include +namespace unittest_trace_variables { + //This is a trace taken from a medium VANDLE module. + static const std::vector data = { + 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 waveform(data.begin() + 71, + data.begin() + 86); + + //An empty data vector to test error checking. + static const std::vector empty_data; + //A data vector that contains constant data. + static const std::vector const_data = {1000, 4}; + + //-------------------------------------------------------------------------- + // Variables related to Testing the integral + //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 expected_integral = 12.5; + + //-------------------------------------------------------------------------- + // Variables related to Polynomial::CalculatePoly3 + + //The expected maximum from the poly3 fitting + static const double expected_poly3_val = 3818.0718412264; + + //A data vector that contains only the four points for the Poly3 Fitting. + static const std::vector poly3_data(data.begin() + 74, + data.begin() + 78); + //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 expected_poly3_coeffs = + {2358.0, 1635.66666666667, -516.0, 31.3333333333333}; + + //-------------------------------------------------------------------------- + // Variables related to Polynomial::CalculatePoly2 + //The expected maximum from the pol2 fitting + static const double expected_poly2_val = 10737.0720588236; + + //A data vector containing only the three points for the Poly2 fitting + static const std::vector poly2_data(data.begin() + 73, + data.begin() + 75); + //Vector containing the expected coefficients from the poly 2 fit + static const std::vector expected_poly2_coeffs = + {1122.0, 1278.5, -42.4999999999999}; + + //------------------------------------------------------------------------------ + // Variables related to calculation of the maximum of a trace + /// This is the expected value of the maximum + static const double expected_maximum_value = 3816; + /// This is the expected position of the maximum + static const unsigned int expected_max_position = 76; + /// This is the pair made from the expected maximum information + static const std::pair expected_max_info( + expected_max_position, + expected_maximum_value); + + //-------------------------------------------------------------------------- + // Variables related to the calculation of the extrapolated maximum + static const std::vector expected_coeffs = + {-15641316.0007084, 592747.666694852, -7472.00000037373, + 31.3333333349849}; + + //-------------------------------------------------------------------------- + // Variables related to calculation of the baseline of the trace + + //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 expected_baseline = 436.7428571; + //The expected standard deviation was obtained using the STDEVP function in + // Google Sheets. + static const double expected_standard_deviation = 1.976184739; + //Pair of these results to test with and use in other places + static const std::pair expected_baseline_pair + (expected_baseline, expected_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 expected_ratio = 0.2960894762; + + //-------------------------------------------------------------------------- + //Variables related to fitting the above trace + //Set the for the fitting from the results of a gnuplot script + std::pair expected_trace_pars(0.2659404170, + 0.208054799179688); + +} #endif //PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP From cf42ae1a8b2550f36cd8a64f22f01aebafe103e6 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 19 Dec 2016 15:39:11 -0500 Subject: [PATCH 065/255] Updating utkscan to use the new HelperFunctions. The WaveformAnalyzer has been rewritten to use the helper functions. This has precipitated changes in the FittingAnalyzer, and the GslFitters. There is some additional cleanup that needs to be addressed, but these things are otherwise ready to rock. I tested the fitters with the data taken for the Pixie Workshop (pulser_003.ldf), and the svp/pixieworkshop.xml configuration file. Former-commit-id: 4bb770749aa5195e647835202de1bbbe425ddf83 --- Scan/Resources/include/GslFitter.hpp | 8 +- Scan/Resources/include/RootFitter.hpp | 24 +++++ Scan/Resources/include/TimingDriver.hpp | 5 +- .../include/UnitTestExampleTrace.hpp | 2 +- .../include/VandleTimingFunction.hpp | 17 ++++ Scan/Resources/source/CMakeLists.txt | 41 +++++--- Scan/Resources/source/Gsl1Fitter.cpp | 23 +++-- Scan/Resources/source/Gsl2Fitter.cpp | 8 +- Scan/Resources/source/RootFitter.cpp | 51 ++++++++++ .../Resources/source/VandleTimingFunction.cpp | 23 +++++ Scan/Resources/tests/CMakeLists.txt | 8 ++ Scan/Resources/tests/test_gslfitter.cpp | 16 +-- Scan/Resources/tests/unittest-RootFitter.cpp | 31 ++++++ Scan/utkscan/CMakeLists.txt | 2 +- .../analyzers/include/FittingAnalyzer.hpp | 4 +- .../analyzers/include/WaveformAnalyzer.hpp | 38 +------ .../analyzers/source/FittingAnalyzer.cpp | 56 ++++++----- .../analyzers/source/WaveformAnalyzer.cpp | 98 +++++++++---------- Scan/utkscan/core/include/Trace.hpp | 17 +++- 19 files changed, 308 insertions(+), 164 deletions(-) create mode 100644 Scan/Resources/include/RootFitter.hpp create mode 100644 Scan/Resources/include/VandleTimingFunction.hpp create mode 100644 Scan/Resources/source/RootFitter.cpp create mode 100644 Scan/Resources/source/VandleTimingFunction.cpp create mode 100644 Scan/Resources/tests/unittest-RootFitter.cpp diff --git a/Scan/Resources/include/GslFitter.hpp b/Scan/Resources/include/GslFitter.hpp index bb7939963..dc114e514 100644 --- a/Scan/Resources/include/GslFitter.hpp +++ b/Scan/Resources/include/GslFitter.hpp @@ -33,10 +33,14 @@ class GslFitter : public TimingDriver { double GetChiSqPerDof(void) { return GetChiSq() / dof_; } ///The ever important phase calculation - /// @param[in] data The data that we would like to try and fit + /// @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 &pars, + const std::pair &max, + const std::pair baseline); ///Sets the isFastSiPm_ flag ///@param[in] a : The value that we are going to set diff --git a/Scan/Resources/include/RootFitter.hpp b/Scan/Resources/include/RootFitter.hpp new file mode 100644 index 000000000..18d6bb6ec --- /dev/null +++ b/Scan/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/Scan/Resources/include/TimingDriver.hpp b/Scan/Resources/include/TimingDriver.hpp index 633447bb6..d98efea63 100644 --- a/Scan/Resources/include/TimingDriver.hpp +++ b/Scan/Resources/include/TimingDriver.hpp @@ -43,9 +43,8 @@ class TimingDriver { ///@return The phase calculated by the algorithm. virtual double CalculatePhase(const std::vector &data, const std::pair &pars, - const std::pair - &maxInfo, - std::pair baseline) { + const std::pair &max, + const std::pair baseline) { return 0.0; } diff --git a/Scan/Resources/include/UnitTestExampleTrace.hpp b/Scan/Resources/include/UnitTestExampleTrace.hpp index 0484089b3..20f3ba0be 100644 --- a/Scan/Resources/include/UnitTestExampleTrace.hpp +++ b/Scan/Resources/include/UnitTestExampleTrace.hpp @@ -66,7 +66,7 @@ namespace unittest_trace_variables { static const std::vector expected_poly2_coeffs = {1122.0, 1278.5, -42.4999999999999}; - //------------------------------------------------------------------------------ + //-------------------------------------------------------------------------- // Variables related to calculation of the maximum of a trace /// This is the expected value of the maximum static const double expected_maximum_value = 3816; diff --git a/Scan/Resources/include/VandleTimingFunction.hpp b/Scan/Resources/include/VandleTimingFunction.hpp new file mode 100644 index 000000000..7d7f68984 --- /dev/null +++ b/Scan/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/Scan/Resources/source/CMakeLists.txt b/Scan/Resources/source/CMakeLists.txt index a35a49c5f..2b63a23d5 100644 --- a/Scan/Resources/source/CMakeLists.txt +++ b/Scan/Resources/source/CMakeLists.txt @@ -1,28 +1,39 @@ #Set the utility sources that we will make a lib out of -set(UtilitySources PolynomialCfd.cpp) +set(ResourceSources PolynomialCfd.cpp) -if(USE_GSL) - if(${GSL_VERSION} GREATER 1.9) - set(UtilitySources ${UtilitySources} Gsl2Fitter.cpp) - else(${GSL_VERSION} LESS 2.0) - set(UtilitySources ${UtilitySources} Gsl1Fitter.cpp) - endif(${GSL_VERSION} GREATER 1.9) -endif(USE_GSL) +if (USE_GSL) + if (${GSL_VERSION} GREATER 1.9) + set(ResourceSources ${ResourceSources} Gsl2Fitter.cpp) + else (${GSL_VERSION} LESS 2.0) + set(ResourceSources ${ResourceSources} Gsl1Fitter.cpp) + endif (${GSL_VERSION} GREATER 1.9) +endif (USE_GSL) + +if (USE_ROOT) + set(ResourceSources ${ResourceSources} RootFitter.cpp + VandleTimingFunction.cpp) +endif (USE_ROOT) #Add the sources to the library -add_library(UtilityObjects OBJECT ${UtilitySources}) +add_library(ResourceObjects OBJECT ${ResourceSources}) -if(BUILD_SHARED_LIBS) +if (BUILD_SHARED_LIBS) message(STATUS "Building Utility Shared Objects") - add_library(UtilityLibrary SHARED $) + add_library(UtilityLibrary SHARED $) target_link_libraries(UtilityLibrary PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) + if (USE_ROOT) + target_link_libraries(UtilityLibrary ${ROOT_LIBRARIES}) + endif (USE_ROOT) if (${CURSES_FOUND}) target_link_libraries(UtilityLibrary ${CURSES_LIBRARIES}) - endif() + endif () install(TARGETS UtilityLibrary DESTINATION lib) -endif(BUILD_SHARED_LIBS) +endif (BUILD_SHARED_LIBS) #Create Utility static library and add ncurses if we have it -add_library(UtilityStatic STATIC $) -target_link_libraries(UtilityStatic ${CMAKE_THREAD_LIBS_INIT}) \ No newline at end of file +add_library(ResourceStatic STATIC $) +target_link_libraries(ResourceStatic ${CMAKE_THREAD_LIBS_INIT}) +if (USE_ROOT) + target_link_libraries(ResourceStatic ${ROOT_LIBRARIES}) +endif (USE_ROOT) \ No newline at end of file diff --git a/Scan/Resources/source/Gsl1Fitter.cpp b/Scan/Resources/source/Gsl1Fitter.cpp index 45d9a1c8a..618fd3668 100644 --- a/Scan/Resources/source/Gsl1Fitter.cpp +++ b/Scan/Resources/source/Gsl1Fitter.cpp @@ -47,21 +47,21 @@ 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 bool & isSipmFast/*= false */, - const double &weight/* = 1.*/, - const double &area/* = 1.*/) { +void GslFitter::PerformFit(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; + y[i] = data.at(i) - baseline.first; + sigma[i] = baseline.second; } struct FitDriver::FitData fitData = @@ -93,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 maxIter = 1e8; + static const 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; } diff --git a/Scan/Resources/source/Gsl2Fitter.cpp b/Scan/Resources/source/Gsl2Fitter.cpp index 8f1ebcaf0..e0066551c 100644 --- a/Scan/Resources/source/Gsl2Fitter.cpp +++ b/Scan/Resources/source/Gsl2Fitter.cpp @@ -35,7 +35,9 @@ 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 &pars, + const std::pair &max, + const std::pair baseline) { gsl_multifit_function_fdf f; int info; const size_t n = data.size(); @@ -80,8 +82,8 @@ double GslFitter::CalculatePhase(const std::vector &data, f.params = &fitData; for (unsigned int i = 0; i < n; i++) { - weights[i] = baseline_.second; - y[i] = data[i] - baseline_.first; + weights[i] = baseline.second; + y[i] = data[i] - baseline.first; } gsl_multifit_fdfsolver_wset(s, &f, &x.vector, &w.vector); diff --git a/Scan/Resources/source/RootFitter.cpp b/Scan/Resources/source/RootFitter.cpp new file mode 100644 index 000000000..2163bb20d --- /dev/null +++ b/Scan/Resources/source/RootFitter.cpp @@ -0,0 +1,51 @@ +/// @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); + + //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/Scan/Resources/source/VandleTimingFunction.cpp b/Scan/Resources/source/VandleTimingFunction.cpp new file mode 100644 index 000000000..7f3bd51e0 --- /dev/null +++ b/Scan/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/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index 5ffc086ad..2d7e757bd 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -20,4 +20,12 @@ if(BUILD_UNITTESTS) ../source/PolynomialCfd.cpp) target_link_libraries(unittest-PolynomialCfd UnitTest++) install(TARGETS unittest-PolynomialCfd 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) endif(BUILD_UNITTESTS) \ No newline at end of file diff --git a/Scan/Resources/tests/test_gslfitter.cpp b/Scan/Resources/tests/test_gslfitter.cpp index caad00983..d70ab4f49 100644 --- a/Scan/Resources/tests/test_gslfitter.cpp +++ b/Scan/Resources/tests/test_gslfitter.cpp @@ -5,29 +5,21 @@ #include #include "GslFitter.hpp" +#include "UnitTestExampleTrace.hpp" using namespace std; +using namespace unittest_trace_variables; int main(int argc, char *argv[]) { cout << "Testing functionality of FitDriver and GslFitter" << endl; - //Baseline for the trace we're going to fit - pair baseline(436.742857142857, 1.9761847389475); - //Set the for the fitting - pair pars(0.2659404170, 0.208054799179688); //Qdc of the trace is necessary to initialization of the fit double area = 21329.85714285; - //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 - }; - //Instance the fitter and pass in the flag for the SiPm GslFitter fitter; - fitter.SetBaseline(baseline); + fitter.SetBaseline(expected_baseline_pair); fitter.SetQdc(area); double phase; @@ -36,7 +28,7 @@ int main(int argc, char *argv[]) { /// practice. Until we can figure out what to throw here then we'll leave /// it. try { - phase = fitter.CalculatePhase(data, pars); + phase = fitter.CalculatePhase(waveform, expected_trace_pars); } catch(...) { cerr << "Something went wrong with the fit" << endl; } diff --git a/Scan/Resources/tests/unittest-RootFitter.cpp b/Scan/Resources/tests/unittest-RootFitter.cpp new file mode 100644 index 000000000..a072e1c1c --- /dev/null +++ b/Scan/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 "UnitTestExampleTrace.hpp" + +using namespace std; +using namespace unittest_trace_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, expected_trace_pars, expected_max_info, + expected_baseline_pair); + + + //return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index 273d0938b..be406c30e 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -72,7 +72,7 @@ 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} ScanStatic ResourceStatic) #If we have GSL installed link if(USE_GSL) diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index c66eb5beb..5a90a0c13 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -12,7 +12,7 @@ #include -#include "TimingAnalysisDriver.hpp" +#include "TimingDriver.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" @@ -35,7 +35,7 @@ class FittingAnalyzer : public TraceAnalyzer { const std::string &detSubtype, const std::map & tagMap); private: - FitDriver *driver_; + TimingDriver *driver_; }; #endif // __FITTINGANALYZER_HPP_ // David is awesome. diff --git a/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp b/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp index 60061b16d..b8be4abb3 100644 --- a/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp @@ -17,50 +17,22 @@ class WaveformAnalyzer : public TraceAnalyzer { WaveformAnalyzer(); /** Default destructor */ - ~WaveformAnalyzer() {} + ~WaveformAnalyzer() { delete messenger_; } /** 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] 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); + 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/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp index 463149453..d9a196d87 100644 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp @@ -8,6 +8,10 @@ * * \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 @@ -16,7 +20,6 @@ #include #include "DammPlotIds.hpp" -#include "TimingAnalysisDriver.hpp" #include "FittingAnalyzer.hpp" #include "GslFitter.hpp" @@ -25,7 +28,8 @@ 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_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"); @@ -34,7 +38,7 @@ void FittingAnalyzer::DeclarePlots(void) { FittingAnalyzer::FittingAnalyzer(const std::string &s) { name = "FittingAnalyzer"; - if(s == "GSL" || s == "gsl") { + if (s == "GSL" || s == "gsl") { driver_ = new GslFitter(); } else { driver_ = NULL; @@ -47,54 +51,52 @@ FittingAnalyzer::~FittingAnalyzer() { void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, const std::string &detSubtype, - const std::map & tagMap) { + const std::map &tagMap) { TraceAnalyzer::Analyze(trace, detType, detSubtype, tagMap); - if(!driver_) { + if (!driver_) { EndAnalyze(); return; } - if(trace.HasValue("saturation") || trace.empty() || - trace.GetWaveform().size() == 0) { - EndAnalyze(); - return; + 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(); + const pair baseline(trace.GetValue("baseline"), + trace.GetValue("sigmaBaseline")); + const pair max(trace.GetValue("maxpos"), + trace.GetValue("maxval")); bool isDblBeta = detType == "beta" && detSubtype == "double"; bool isDblBetaT = isDblBeta && tagMap.find("timing") != tagMap.end(); - trace.plot(D_SIGMA, sigmaBaseline*100); + trace.plot(D_SIGMA, baseline.second * 100); - if(!isDblBetaT) { - if(sigmaBaseline > globals->sigmaBaselineThresh()) { + if (!isDblBetaT) { + if (baseline.second > globals->sigmaBaselineThresh()) { EndAnalyze(); return; } } else { - if(sigmaBaseline > globals->siPmtSigmaBaselineThresh()) { + if (baseline.second > globals->siPmtSigmaBaselineThresh()) { EndAnalyze(); return; } } - pair pars = globals->fitPars(detType+":"+detSubtype); - if(isDblBetaT) - pars = globals->fitPars(detType+":"+detSubtype+":timing"); + pair pars = globals->fitPars(detType + ":" + detSubtype); + if (isDblBetaT) + pars = globals->fitPars(detType + ":" + detSubtype + ":timing"); + + driver_->SetQdc(trace.GetValue("qdc")); + double phase = driver_->CalculatePhase(trace.GetWaveformWithBaseline(), + pars, max, baseline); - driver_->PerformFit(waveform, pars, isDblBetaT, 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()); + trace.InsertValue("phase", phase + max.first); EndAnalyze(); } \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index 68db28f72..f345bc6e8 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -9,19 +9,15 @@ */ #include #include +#include #include +#include "HelperFunctions.hpp" #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(); @@ -31,69 +27,63 @@ 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(); + Globals *globals = Globals::get(); pair range = - g_->waveformRange(type + ":" + subtype); - + globals->waveformRange(type + ":" + subtype); if (type == "beta" && subtype == "double" && tags.find("timing") != tags.end()) - range = g_->waveformRange(type + ":" + subtype + ":timing"); + range = globals->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; + //First we calculate the position of the maximum. + pair max = + TraceFunctions::FindMaximum(trace, globals->traceDelay() / + (globals->adcClockInSeconds() * + 1e9)); + + //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)); + + //Finally, we calculate the QDC in the waveform range and subtract + // the baseline from it. + pair qdcRange(max.first - range.first, + max.first + range.second); + double qdc = TraceFunctions::CalculateQdc(trace, qdcRange) - + (qdcRange.second - qdcRange.first) * baseline.first; + + //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("maxpos", (int)max.first); + + vector waveform; + vector waveformWithBaseline; + for(unsigned int i = qdcRange.first; i < qdcRange.second; i++) { + waveform.push_back(trace[i] - baseline.first); + waveformWithBaseline.push_back(trace[i]); } + trace.SetWaveform(waveform); + trace.SetWaveformWithBaseline(waveformWithBaseline); + } catch (range_error &ex) { + cerr << "WaveformAnalyzer::Analyze - " << ex.what() << endl; EndAnalyze(); } - EndAnalyze(); } diff --git a/Scan/utkscan/core/include/Trace.hpp b/Scan/utkscan/core/include/Trace.hpp index ad4d3a8ab..0dd097d53 100644 --- a/Scan/utkscan/core/include/Trace.hpp +++ b/Scan/utkscan/core/include/Trace.hpp @@ -85,6 +85,11 @@ class Trace : public std::vector { /** \return Returns the waveform found inside the trace */ std::vector GetWaveform() {return(waveform_);} + ///@return Returns the waveform that still has the baseline + std::vector GetWaveformWithBaseline() { + return waveformWithBaseline_; + } + /*! \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 @@ -146,7 +151,14 @@ class Trace : public std::vector { /** 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 + + ///@brief sets the waveform that has the baseline in it + ///@param[in] a : The vector that we are going to assign. + void SetWaveformWithBaseline(const std::vector &a){ + waveformWithBaseline_ = 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 @@ -155,8 +167,11 @@ class Trace : public std::vector { private: std::vector waveform_; //!< The waveform inside the trace +//!< without baseline subtraction std::vector trigFilter_; //!< The trigger filter for the trace std::vector esums_; //!< The Energy sums calculated from the trace + std::vector waveformWithBaseline_; ///! Waveform with +/// baseline. std::map doubleTraceData; //!< Trace data stored as doubles std::map intTraceData;//!< Trace data stored as ints From c0881a7296c947ad6f0c7b27a18759d256193670 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 19 Dec 2016 17:11:39 -0500 Subject: [PATCH 066/255] Fixing errors in CalculatePoly2 and updating tests Former-commit-id: f38a0eb07102dce215da62bb68244bf49f978f9b --- Scan/Resources/include/HelperFunctions.hpp | 69 +++++++++---------- .../include/UnitTestExampleTrace.hpp | 2 +- .../tests/unittest-HelperFunctions.cpp | 7 ++ 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index c4aea9127..f38641fc0 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -17,9 +17,13 @@ using namespace std; namespace Polynomial { - template + 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); @@ -30,30 +34,25 @@ namespace Polynomial { (x1[1] * x2[2] - x2[1] * x1[2]) - x1[0] * (x2[2] - x2[1] * 1) + x2[0] * (x1[2] - x1[1] * 1); - double p0 = (double) ((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 = (double) ( - ((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 = (double) ( - ((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); + 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}; - // Calculate the maximum of the polynomial. - //@TODO Is this actually the maximum of the polynomial?? - return make_pair(p0 - p1 * p1 / (4 * p2), coeffs); + return make_pair(p0 - ((p1 * p1) / (4 * p2)), coeffs); } - template + template static const pair > CalculatePoly3( const vector &data, const unsigned int &startBin) { if (data.size() < 4) @@ -164,7 +163,7 @@ namespace Polynomial { }//Polynomial namespace namespace Statistics { - template + template inline double CalculateAverage(const vector &data) { double sum = 0.0; for (typename vector::const_iterator i = data.begin(); @@ -176,7 +175,7 @@ namespace Statistics { //This calculation for the standard deviation assumes that we are // analyzing the full population, which we are in this case. - template + template inline double CalculateStandardDeviation(const vector &data, const double &mean) { double stddev = 0.0; @@ -192,7 +191,7 @@ namespace Statistics { /// like that to keep things general. ///@param[in] data : The data that we want to integrate. ///@return The integrated value - template + template inline double CalculateIntegral(const vector &data) { if (data.size() < 2) throw range_error("Statistical::CalculateIntegral - The data " @@ -220,7 +219,7 @@ namespace TraceFunctions { ///@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 + template inline pair CalculateBaseline(const vector &data, const pair(data.begin(), data.begin() + - range.second)); + range.second)); double stddev = Statistics::CalculateStandardDeviation( vector(data.begin(), data.begin() + - range.second), + range.second), baseline); return make_pair(baseline, stddev); } @@ -264,7 +263,7 @@ namespace TraceFunctions { /// @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 + template inline pair > ExtrapolateMaximum( const vector &data, const pair &maxInfo) { @@ -302,7 +301,7 @@ namespace TraceFunctions { /// set for this particular trace. /// @return A STL pair containing the bin and value of the maximum found /// in the trace. - template + template inline pair FindMaximum( const vector &data, const unsigned int &traceDelayInBins) { @@ -346,7 +345,7 @@ namespace TraceFunctions { return make_pair((unsigned int) (itPos - data.begin()), *itPos); } - template + template inline unsigned int FindLeadingEdge(const vector &data, const double &threshold, const pair &maxInfo) { @@ -383,7 +382,7 @@ namespace TraceFunctions { ///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 + template inline double CalculateQdc(const vector &data, const pair &range) { stringstream msg; @@ -398,17 +397,18 @@ namespace TraceFunctions { } return Statistics::CalculateIntegral( vector(data.begin() + range.first, - data.begin() + range.second)); + data.begin() + range.second)); } - template + 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."); + 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 @@ -422,7 +422,7 @@ namespace TraceFunctions { return Statistics::CalculateIntegral( vector(data.begin() + range.first, - data.begin() + range.second)) / qdc; + data.begin() + range.second)) / qdc; } @@ -433,7 +433,6 @@ namespace TraceFunctions { namespace Validation { - } } #endif //PIXIESUITE_HELPERFUNCTIONS_HPP diff --git a/Scan/Resources/include/UnitTestExampleTrace.hpp b/Scan/Resources/include/UnitTestExampleTrace.hpp index 20f3ba0be..b9e6c9bee 100644 --- a/Scan/Resources/include/UnitTestExampleTrace.hpp +++ b/Scan/Resources/include/UnitTestExampleTrace.hpp @@ -61,7 +61,7 @@ namespace unittest_trace_variables { //A data vector containing only the three points for the Poly2 fitting static const std::vector poly2_data(data.begin() + 73, - data.begin() + 75); + data.begin() + 76); //Vector containing the expected coefficients from the poly 2 fit static const std::vector expected_poly2_coeffs = {1122.0, 1278.5, -42.4999999999999}; diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index 063ee20c2..fbd947b71 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -123,9 +123,16 @@ TEST(TestExtrapolateMaximum) { } TEST(TestCalculatePoly2) { + //Check that we throw an error when the passed data vector is too small. + CHECK_THROW(Polynomial::CalculatePoly2(empty_data, 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(expected_poly2_coeffs, result.second, 3, 1e-3); + CHECK_CLOSE(expected_poly2_val, result.first, 1e-4); } From 24445e9db6ff12d01101abf63e5b19f3c01b468b Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 20 Dec 2016 11:40:01 -0500 Subject: [PATCH 067/255] Fixing issue in the GetPhase method of HighResTimingData Former-commit-id: 14eb3a63bff28f5148ea4c50e07f0502671f8060 --- Scan/utkscan/core/include/HighResTimingData.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/utkscan/core/include/HighResTimingData.hpp b/Scan/utkscan/core/include/HighResTimingData.hpp index 6d83349b9..fd2a10b27 100644 --- a/Scan/utkscan/core/include/HighResTimingData.hpp +++ b/Scan/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()); } From da954c58fa675b7984ec759d82bff68a88f0f546 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 20 Dec 2016 16:25:10 -0500 Subject: [PATCH 068/255] PolynomialCfd is now implemented. I had to change the Trace class so that it was derived from a vector instead of vector. This broke some other code that needed to be updated. I have commented out the baseline and QDC calculations in the scope, as well as the CFD portions until such time as they can be updated. Globals has been updated to read the Cfd node to obtain the desired fraction and delay for the CFD. Analysis of PixieWorkshop::pulser_003.ldf provides using the Polynomial CFD provides satisifactory results. The configuration file used for these tests is included in svp/pixieworkshop-cfd.xml. Former-commit-id: c814b57b79bc1819ac05e4f8a5d2c9aa9b3fa619 --- Scan/Resources/include/PolynomialCfd.hpp | 3 +- Scan/Resources/source/PolynomialCfd.cpp | 27 ++- Scan/ScanLib/include/XiaData.hpp | 2 +- Scan/util/source/scope.cpp | 8 +- .../utkscan/analyzers/include/CfdAnalyzer.hpp | 16 +- Scan/utkscan/analyzers/source/CfdAnalyzer.cpp | 84 ++++----- Scan/utkscan/core/include/Globals.hpp | 8 + Scan/utkscan/core/include/Trace.hpp | 6 +- Scan/utkscan/core/source/Globals.cpp | 14 ++ .../include/TwoChanTimingProcessor.hpp | 7 +- .../source/TwoChanTimingProcessor.cpp | 11 +- .../processors/source/PspmtProcessor.cpp | 3 +- .../utkscan/cfgs/svp/pixieworkshop-cfd.xml | 172 ++++++++++++++++++ 13 files changed, 279 insertions(+), 82 deletions(-) create mode 100644 Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml diff --git a/Scan/Resources/include/PolynomialCfd.hpp b/Scan/Resources/include/PolynomialCfd.hpp index 32b3c70c9..91082a16e 100644 --- a/Scan/Resources/include/PolynomialCfd.hpp +++ b/Scan/Resources/include/PolynomialCfd.hpp @@ -16,7 +16,8 @@ class PolynomialCfd : public TimingDriver { /// Perform CFD analysis on the waveform using the pol2 algorithm. double CalculatePhase(const std::vector &data, const std::pair &pars, - const std::pair &maxInfo); + const std::pair &max, + const std::pair baseline); }; #endif //PIXIESUITE_POLYNOMIALCFD_HPP diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Scan/Resources/source/PolynomialCfd.cpp index a04751630..8446dc0cf 100644 --- a/Scan/Resources/source/PolynomialCfd.cpp +++ b/Scan/Resources/source/PolynomialCfd.cpp @@ -13,30 +13,41 @@ using namespace std; /// Perform CFD analysis on the waveform. double PolynomialCfd::CalculatePhase(const std::vector &data, const std::pair &pars, - const std::pair &maxInfo) { + 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() < maxInfo.first) + 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 * maxInfo.second; + double threshold = pars.first * max.second; double phase = -9999; vector result; - - for (unsigned int cfdIndex = maxInfo.first; cfdIndex > 0; cfdIndex--) { + 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; + //We want to stop things here so that the user can do some + // debugging of potential issues. + if (result[2] > 0) + throw range_error("PolynomialCfd::CalculatePhase : The " + "calculated coefficients were for a" + " concave-upward parabola. Try " + "increasing your fraction to " + "improve quality."); + // Calculate the phase of the trace. - phase = (-result[1] + std::sqrt(result[1] * result[1] - - 4 * result[2] * - (result[0] - threshold))) / + phase = (-result[1] + + sqrt(result[1] * result[1] - + 4 * result[2] * + (result[0] - threshold))) / (2 * result[2]); + break; } } diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index c7514c437..b86a89fb3 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -21,7 +21,7 @@ class XiaData{ 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. + std::vector adcTrace; /// ADC trace capture. static const int numQdcs = 8; /// Number of QDCs onboard. unsigned int qdcValue[numQdcs]; /// QDCs from onboard. diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index 3f04353e0..501e47fb0 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -234,6 +234,8 @@ void scopeScanner::Plot(){ 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(); @@ -262,6 +264,7 @@ void scopeScanner::Plot(){ cfdPol2->SetRange((evt->cfdIndex - 1)*ADC_TIME_STEP, (evt->cfdIndex + 1)*ADC_TIME_STEP); cfdPol2->Draw("SAME"); } + */ if(performFit_){ paulauskasFunc->SetRange(lowVal, highVal); @@ -395,8 +398,9 @@ bool scopeScanner::AddEvent(XiaData *event_){ ChannelEvent *channel_event = new ChannelEvent(event_); //Process the waveform. - channel_event->ComputeBaseline(); - 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); diff --git a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp b/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp index b43e0c689..1ef82f0d4 100644 --- a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp @@ -6,7 +6,7 @@ #ifndef __CFDANALYZER_HPP_ #define __CFDANALYZER_HPP_ -#include "HighResTimingData.hpp" +#include "TimingDriver.hpp" #include "Trace.hpp" #include "TraceAnalyzer.hpp" @@ -14,18 +14,24 @@ class CfdAnalyzer : public TraceAnalyzer { public: /** Default constructor */ - CfdAnalyzer(); + 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/source/CfdAnalyzer.cpp b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp index 0f928bb32..82aeef6fb 100644 --- a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp @@ -9,71 +9,53 @@ * \author S. V. Paulauskas * \date 22 July 2011 */ -#include #include -#include -#include #include +#include #include "CfdAnalyzer.hpp" +#include "HelperFunctions.hpp" +#include "PolynomialCfd.hpp" using namespace std; -CfdAnalyzer::CfdAnalyzer() : TraceAnalyzer() { +CfdAnalyzer::CfdAnalyzer(const std::string &s) : TraceAnalyzer() { name = "CfdAnalyzer"; + if (s == "polynomial" || s == "poly") { + driver_ = new PolynomialCfd(); + } else { + driver_ = NULL; + } } void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, const std::string &detSubtype, - const std::map & tagMap) { + 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)); + + if (!driver_) { + EndAnalyze(); + return; } - 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); + + if (trace.HasValue("saturation") || trace.empty() || + trace.GetWaveform().size() == 0) { + EndAnalyze(); + return; } - 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); + + const pair baseline(trace.GetValue("baseline"), + trace.GetValue("sigmaBaseline")); + pair max(trace.GetValue("maxpos"), + trace.GetValue("maxval")); + + //For the CFD we need to obtain the extrapolated maximum value + max.second = TraceFunctions::ExtrapolateMaximum(trace, max).first; + + pair pars = + Globals::get()->cfdPars(detType + ":" + detSubtype); + + trace.InsertValue("phase", + driver_->CalculatePhase(trace, pars, max, baseline)); EndAnalyze(); } diff --git a/Scan/utkscan/core/include/Globals.hpp b/Scan/utkscan/core/include/Globals.hpp index c86941e20..804e9c42d 100644 --- a/Scan/utkscan/core/include/Globals.hpp +++ b/Scan/utkscan/core/include/Globals.hpp @@ -247,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()) @@ -329,6 +336,7 @@ 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_; //! { +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 diff --git a/Scan/utkscan/core/source/Globals.cpp b/Scan/utkscan/core/source/Globals.cpp index 43fb00d07..cf62b2e66 100644 --- a/Scan/utkscan/core/source/Globals.cpp +++ b/Scan/utkscan/core/source/Globals.cpp @@ -197,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/experiment/include/TwoChanTimingProcessor.hpp b/Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp index fd1cb48c7..6e6a0ada8 100644 --- a/Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp +++ b/Scan/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/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp b/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp index f18955fd9..a4de54715 100644 --- a/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp +++ b/Scan/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/Scan/utkscan/processors/source/PspmtProcessor.cpp b/Scan/utkscan/processors/source/PspmtProcessor.cpp index c5414efcc..1b272f235 100644 --- a/Scan/utkscan/processors/source/PspmtProcessor.cpp +++ b/Scan/utkscan/processors/source/PspmtProcessor.cpp @@ -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/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml b/Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml new file mode 100644 index 000000000..36f53986d --- /dev/null +++ b/Scan/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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5c6e9bbb5daa02509f1f9f67027483ca67cda337 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 20 Dec 2016 18:33:53 -0500 Subject: [PATCH 069/255] Implementing TraditionalCfd This CFD performs like a traditional CFD does. It applies a delay to the signal, inverts it and then subtracts it. It uses a linear interpolation between the max and min to find the zero crossing. it works just as well as expected. Former-commit-id: f7cadc503432d17d7d9be68d300639d145ee91a9 --- Scan/Resources/include/TraditionalCfd.hpp | 24 ++++++++ Scan/Resources/source/CMakeLists.txt | 2 +- Scan/Resources/source/TraditionalCfd.cpp | 58 +++++++++++++++++++ Scan/Resources/tests/CMakeLists.txt | 5 ++ .../tests/unittest-PolynomialCfd.cpp | 18 +++--- .../tests/unittest-TraditionalCfd.cpp | 42 ++++++++++++++ Scan/utkscan/analyzers/source/CfdAnalyzer.cpp | 9 ++- 7 files changed, 146 insertions(+), 12 deletions(-) create mode 100644 Scan/Resources/include/TraditionalCfd.hpp create mode 100644 Scan/Resources/source/TraditionalCfd.cpp create mode 100644 Scan/Resources/tests/unittest-TraditionalCfd.cpp diff --git a/Scan/Resources/include/TraditionalCfd.hpp b/Scan/Resources/include/TraditionalCfd.hpp new file mode 100644 index 000000000..1860264e9 --- /dev/null +++ b/Scan/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/Scan/Resources/source/CMakeLists.txt b/Scan/Resources/source/CMakeLists.txt index 2b63a23d5..5395f7351 100644 --- a/Scan/Resources/source/CMakeLists.txt +++ b/Scan/Resources/source/CMakeLists.txt @@ -1,5 +1,5 @@ #Set the utility sources that we will make a lib out of -set(ResourceSources PolynomialCfd.cpp) +set(ResourceSources PolynomialCfd.cpp TraditionalCfd.cpp) if (USE_GSL) if (${GSL_VERSION} GREATER 1.9) diff --git a/Scan/Resources/source/TraditionalCfd.cpp b/Scan/Resources/source/TraditionalCfd.cpp new file mode 100644 index 000000000..0a1542667 --- /dev/null +++ b/Scan/Resources/source/TraditionalCfd.cpp @@ -0,0 +1,58 @@ +///@file TraditionalCfd.cpp +///@brief Traditional CFD implemented digitally +///@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 * ((double) data[i] - (double) data[i + delay] - + baseline.first)); + + //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/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index 2d7e757bd..9a0cd2123 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -21,6 +21,11 @@ if(BUILD_UNITTESTS) 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) diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Scan/Resources/tests/unittest-PolynomialCfd.cpp index 3261c3043..138163e0c 100644 --- a/Scan/Resources/tests/unittest-PolynomialCfd.cpp +++ b/Scan/Resources/tests/unittest-PolynomialCfd.cpp @@ -1,4 +1,4 @@ -///@file unittest-HelperFunctions.cpp +///@file unittest-PolynomialCfd.cpp ///@author S. V. Paulauskas ///@date December 12, 2016 #include @@ -19,20 +19,22 @@ static const pair max_info(expected_max_position, expected_poly3_val); TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { - static const pair pars(0.5, 2.); + static const pair pars(0.5, 2.); //Checking that we throw a range_error when the data vector is zero - CHECK_THROW(CalculatePhase(empty_data, pars, max_info), - range_error); + CHECK_THROW(CalculatePhase(empty_data, pars, max_info, + expected_baseline_pair), range_error); //Checking that we throw a range_error when the max index is too large // for the data - static const pair tmp(1000, expected_poly3_val); - CHECK_THROW(CalculatePhase(data, pars, tmp), range_error); + CHECK_THROW(CalculatePhase(data, pars, tmp, + expected_baseline_pair), range_error); - CHECK(-9999 != CalculatePhase(data, pars, max_info)); - cout << CalculatePhase(data, pars, max_info) << endl; + double result = CalculatePhase(data, pars, max_info, + expected_baseline_pair); + CHECK(-9999 != result); + cout << "PolynomialCfd result is " << result << endl; } int main(int argv, char *argc[]) { diff --git a/Scan/Resources/tests/unittest-TraditionalCfd.cpp b/Scan/Resources/tests/unittest-TraditionalCfd.cpp new file mode 100644 index 000000000..4f5b29053 --- /dev/null +++ b/Scan/Resources/tests/unittest-TraditionalCfd.cpp @@ -0,0 +1,42 @@ +///@file unittest-TraditionalCfd.cpp +///@author S. V. Paulauskas +///@date December 12, 2016 +#include +#include +#include + +#include + +#include "TraditionalCfd.hpp" +#include "UnitTestExampleTrace.hpp" + +using namespace std; +using namespace unittest_trace_variables; + +//This pair provides us with the expected extrapolated maximum and the +// position of the maximum. +static const pair max_info(expected_max_position, + expected_poly3_val); + +TEST_FIXTURE(TraditionalCfd, TestTraditionalCfd) { + static const pair pars(0.5, 2.); + + //Checking that we throw a range_error when the data vector is zero + CHECK_THROW(CalculatePhase(empty_data, pars, max_info, + expected_baseline_pair), range_error); + + //Checking that we throw a range_error when the max index is too large + // for the data + static const pair tmp(1000, expected_poly3_val); + CHECK_THROW(CalculatePhase(data, pars, tmp, + expected_baseline_pair), range_error); + + double result = CalculatePhase(data, pars, max_info, + expected_baseline_pair); + CHECK(-9999 != result); + cout << "TraditionalCfd result is " << result << endl; +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp index 82aeef6fb..c266955a5 100644 --- a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp @@ -16,16 +16,19 @@ #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") { + if (s == "polynomial" || s == "poly") driver_ = new PolynomialCfd(); - } else { + else if(s == "traditional" || s == "trad") + driver_ = new TraditionalCfd(); + else driver_ = NULL; - } + } void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, From 9336b654d2d880f5eeb46b6e6133bcb5d4fa8913 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 20 Dec 2016 19:35:56 -0500 Subject: [PATCH 070/255] Adding baseline subtraction to the trace The baseline subtraction produces more accurate results for the delay, but at a slight cost in the resolution. Former-commit-id: 7c5950a930c2903fdb28ba1cbe238a7f83223276 --- Scan/Resources/source/PolynomialCfd.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Scan/Resources/source/PolynomialCfd.cpp index 8446dc0cf..0a9b05676 100644 --- a/Scan/Resources/source/PolynomialCfd.cpp +++ b/Scan/Resources/source/PolynomialCfd.cpp @@ -23,14 +23,20 @@ double PolynomialCfd::CalculatePhase(const std::vector &data, "position is larger than the size of the " "data vector."); - double threshold = pars.first * max.second; + vector tmp; + for(unsigned int i = 0; i < data.size(); i++) + tmp.push_back(data[i] - baseline.first); + + double threshold = pars.first * (max.second - baseline.first); double phase = -9999; vector result; for (unsigned int cfdIndex = max.first; cfdIndex > 0; cfdIndex--) { - if (data[cfdIndex - 1] < threshold && data[cfdIndex] >= threshold) { + if (tmp[cfdIndex - 1] < threshold && tmp[cfdIndex] >= threshold) { // Fit the rise of the trace to a 2nd order polynomial. - result = Polynomial::CalculatePoly2(data, cfdIndex - 1).second; + ///@TODO Fix this so that we do not need to baseline subtract the + /// whole trace. + result = Polynomial::CalculatePoly2(tmp, cfdIndex - 1).second; //We want to stop things here so that the user can do some // debugging of potential issues. From 9b793d00a4d2f330138bc230feb0705afa704b5a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 21 Dec 2016 16:47:48 -0500 Subject: [PATCH 071/255] Set the CFDs to only work on baseline subtracted traces. I have also updated the WaveformAnalyzer and Trace classes to handle things a litlte differently. This has increased the efficiency of the software since we're only calculating the baseline subtraction on the trace once, instead of every time somebody needs it. Former-commit-id: 62d0cbcfa3c55d2bfb0b6655dcfc0a4f45a4a84a --- Scan/Resources/include/PolynomialCfd.hpp | 2 +- Scan/Resources/include/TimingDriver.hpp | 10 +++ Scan/Resources/include/TraditionalCfd.hpp | 2 +- Scan/Resources/source/PolynomialCfd.cpp | 18 ++--- Scan/Resources/source/TraditionalCfd.cpp | 5 +- Scan/utkscan/analyzers/source/CfdAnalyzer.cpp | 8 +- .../analyzers/source/WaveformAnalyzer.cpp | 37 +++++---- Scan/utkscan/core/include/Trace.hpp | 78 ++++++++++++------- 8 files changed, 92 insertions(+), 68 deletions(-) diff --git a/Scan/Resources/include/PolynomialCfd.hpp b/Scan/Resources/include/PolynomialCfd.hpp index 91082a16e..661b799ab 100644 --- a/Scan/Resources/include/PolynomialCfd.hpp +++ b/Scan/Resources/include/PolynomialCfd.hpp @@ -14,7 +14,7 @@ class PolynomialCfd : public TimingDriver { ~PolynomialCfd() {}; /// Perform CFD analysis on the waveform using the pol2 algorithm. - double CalculatePhase(const std::vector &data, + double CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline); diff --git a/Scan/Resources/include/TimingDriver.hpp b/Scan/Resources/include/TimingDriver.hpp index d98efea63..2d5396776 100644 --- a/Scan/Resources/include/TimingDriver.hpp +++ b/Scan/Resources/include/TimingDriver.hpp @@ -48,6 +48,16 @@ class TimingDriver { 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; } diff --git a/Scan/Resources/include/TraditionalCfd.hpp b/Scan/Resources/include/TraditionalCfd.hpp index 1860264e9..d266c3241 100644 --- a/Scan/Resources/include/TraditionalCfd.hpp +++ b/Scan/Resources/include/TraditionalCfd.hpp @@ -16,7 +16,7 @@ class TraditionalCfd : public TimingDriver { /// Default destructor ~TraditionalCfd() {}; - double CalculatePhase(const std::vector &data, + double CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline); diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Scan/Resources/source/PolynomialCfd.cpp index 0a9b05676..f53dc97a9 100644 --- a/Scan/Resources/source/PolynomialCfd.cpp +++ b/Scan/Resources/source/PolynomialCfd.cpp @@ -11,7 +11,7 @@ using namespace std; /// Perform CFD analysis on the waveform. -double PolynomialCfd::CalculatePhase(const std::vector &data, +double PolynomialCfd::CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline) { @@ -23,28 +23,22 @@ double PolynomialCfd::CalculatePhase(const std::vector &data, "position is larger than the size of the " "data vector."); - vector tmp; - for(unsigned int i = 0; i < data.size(); i++) - tmp.push_back(data[i] - baseline.first); - - double threshold = pars.first * (max.second - baseline.first); + double threshold = pars.first * max.second; double phase = -9999; vector result; for (unsigned int cfdIndex = max.first; cfdIndex > 0; cfdIndex--) { - if (tmp[cfdIndex - 1] < threshold && tmp[cfdIndex] >= threshold) { + if (data[cfdIndex - 1] < threshold && data[cfdIndex] >= threshold) { // Fit the rise of the trace to a 2nd order polynomial. - ///@TODO Fix this so that we do not need to baseline subtract the - /// whole trace. - result = Polynomial::CalculatePoly2(tmp, cfdIndex - 1).second; + result = Polynomial::CalculatePoly2(data, cfdIndex - 1).second; //We want to stop things here so that the user can do some // debugging of potential issues. if (result[2] > 0) throw range_error("PolynomialCfd::CalculatePhase : The " "calculated coefficients were for a" - " concave-upward parabola. Try " - "increasing your fraction to " + " concave-upward parabola. " + "Increase your fraction to " "improve quality."); // Calculate the phase of the trace. diff --git a/Scan/Resources/source/TraditionalCfd.cpp b/Scan/Resources/source/TraditionalCfd.cpp index 0a1542667..1e4694d36 100644 --- a/Scan/Resources/source/TraditionalCfd.cpp +++ b/Scan/Resources/source/TraditionalCfd.cpp @@ -8,7 +8,7 @@ using namespace std; -double TraditionalCfd::CalculatePhase(const std::vector &data, +double TraditionalCfd::CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline) { @@ -26,8 +26,7 @@ double TraditionalCfd::CalculatePhase(const std::vector &data, //We are going to calculate the CFD here. for (unsigned int i = 0; i < data.size() - delay; i++) - cfd.push_back(fraction * ((double) data[i] - (double) data[i + delay] - - baseline.first)); + 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()); diff --git a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp index c266955a5..b97422a75 100644 --- a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp @@ -50,15 +50,13 @@ void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, const pair baseline(trace.GetValue("baseline"), trace.GetValue("sigmaBaseline")); pair max(trace.GetValue("maxpos"), - trace.GetValue("maxval")); - - //For the CFD we need to obtain the extrapolated maximum value - max.second = TraceFunctions::ExtrapolateMaximum(trace, max).first; + trace.GetValue("extrapolatedMaxVal")); pair pars = Globals::get()->cfdPars(detType + ":" + detSubtype); trace.InsertValue("phase", - driver_->CalculatePhase(trace, pars, max, baseline)); + driver_->CalculatePhase(trace.GetBaselineSubtractedTrace() + , pars, max, baseline)); EndAnalyze(); } diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index f345bc6e8..419004c5a 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -54,32 +54,35 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, //Next we calculate the baseline and its standard deviation pair baseline = - TraceFunctions::CalculateBaseline(trace, - make_pair(0, max.first - - range.first)); + 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 qdcRange(max.first - range.first, - max.first + range.second); - double qdc = TraceFunctions::CalculateQdc(trace, qdcRange) - - (qdcRange.second - qdcRange.first) * baseline.first; + pair waveformRange(max.first - range.first, + max.first + + range.second); + double qdc = TraceFunctions::CalculateQdc(traceNoBaseline, + waveformRange) - + (waveformRange.second - waveformRange.first) * + baseline.first; //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("maxpos", (int)max.first); - - vector waveform; - vector waveformWithBaseline; - for(unsigned int i = qdcRange.first; i < qdcRange.second; i++) { - waveform.push_back(trace[i] - baseline.first); - waveformWithBaseline.push_back(trace[i]); - } - trace.SetWaveform(waveform); - trace.SetWaveformWithBaseline(waveformWithBaseline); + 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(); diff --git a/Scan/utkscan/core/include/Trace.hpp b/Scan/utkscan/core/include/Trace.hpp index dbdfad59a..131d80389 100644 --- a/Scan/utkscan/core/include/Trace.hpp +++ b/Scan/utkscan/core/include/Trace.hpp @@ -33,34 +33,34 @@ class Trace : public std::vector { * \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,26 +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 waveformWithBaseline_; + 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); } @@ -104,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); } @@ -118,66 +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 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 waveform that has the baseline in it + ///@brief sets the baseline subtracted trace for use. ///@param[in] a : The vector that we are going to assign. - void SetWaveformWithBaseline(const std::vector &a){ - waveformWithBaseline_ = a; + 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 -//!< without baseline subtraction + //!< 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::vector waveformWithBaseline_; ///! Waveform with -/// baseline. 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_ From 75de86979c648c7de89fba9074f4c0b427d7249f Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 21 Dec 2016 17:34:54 -0500 Subject: [PATCH 072/255] Adding some TODOs to the Unpacker Former-commit-id: 46a10ac5294dab30d8a27fade9ac04531321a994 --- Scan/ScanLib/source/Unpacker.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Scan/ScanLib/source/Unpacker.cpp index 7668425fa..a348d531e 100644 --- a/Scan/ScanLib/source/Unpacker.cpp +++ b/Scan/ScanLib/source/Unpacker.cpp @@ -230,8 +230,10 @@ int Unpacker::ReadBuffer(unsigned int *buf, unsigned long &bufLen){ while( buf < bufStart + bufLen ){ XiaData *currentEvt = new XiaData(); - // decoding event data... see pixie16app.c + // decoding event data... // buf points to the start of channel data + ///@TODO we need to update this so that we are decoding the data + /// properly unsigned int chanNum = (buf[0] & 0x0000000F); unsigned int slotNum = (buf[0] & 0x000000F0) >> 4; unsigned int crateNum = (buf[0] & 0x00000F00) >> 8; @@ -306,6 +308,8 @@ int Unpacker::ReadBuffer(unsigned int *buf, unsigned long &bufLen){ channel_counts[modNum][chanNum]++; currentEvt->energy = energy; + ///@TODO Update this so that it takes into account both 12 and 14 + /// bit modules. if(currentEvt->saturatedBit){ currentEvt->energy = 16383; } currentEvt->trigTime = lowTime; From 3bd0de10687194926081becdf30f3e41e1c08659 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 3 Jan 2017 13:26:18 -0500 Subject: [PATCH 073/255] Making changes to address issues raised by @ksmith0 Former-commit-id: de2d609366044a1ad259dec5db9c75134a6f5a4b --- Scan/Resources/CMakeLists.txt | 1 - Scan/Resources/include/HelperFunctions.hpp | 8 +++++++ Scan/Resources/source/CMakeLists.txt | 7 +----- Scan/Resources/source/RootFitter.cpp | 2 ++ Scan/Resources/source/TraditionalCfd.cpp | 3 ++- Scan/Resources/source/XiaCfd.cpp | 9 ++++---- Scan/Resources/tests/CMakeLists.txt | 2 +- .../tests/unittest-HelperFunctions.cpp | 23 +++++++++++-------- .../utkscan/analyzers/include/CfdAnalyzer.hpp | 2 +- Scan/utkscan/analyzers/source/CfdAnalyzer.cpp | 6 ++--- .../analyzers/source/WaveformAnalyzer.cpp | 2 +- Scan/utkscan/core/source/DetectorDriver.cpp | 3 ++- 12 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Scan/Resources/CMakeLists.txt b/Scan/Resources/CMakeLists.txt index ae30a4f0f..d2031f51f 100644 --- a/Scan/Resources/CMakeLists.txt +++ b/Scan/Resources/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(source) if(BUILD_TESTS OR BUILD_UNITTESTS) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index f38641fc0..5630a5ac2 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -345,6 +345,7 @@ namespace TraceFunctions { 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 &threshold, @@ -395,6 +396,12 @@ namespace TraceFunctions { << "," << 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)); @@ -415,6 +422,7 @@ namespace TraceFunctions { << "," << 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 " diff --git a/Scan/Resources/source/CMakeLists.txt b/Scan/Resources/source/CMakeLists.txt index 5395f7351..ebc50df5a 100644 --- a/Scan/Resources/source/CMakeLists.txt +++ b/Scan/Resources/source/CMakeLists.txt @@ -20,20 +20,15 @@ add_library(ResourceObjects OBJECT ${ResourceSources}) if (BUILD_SHARED_LIBS) message(STATUS "Building Utility Shared Objects") add_library(UtilityLibrary SHARED $) - target_link_libraries(UtilityLibrary PixieCoreStatic - ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(UtilityLibrary PixieCoreStatic) if (USE_ROOT) target_link_libraries(UtilityLibrary ${ROOT_LIBRARIES}) endif (USE_ROOT) - if (${CURSES_FOUND}) - target_link_libraries(UtilityLibrary ${CURSES_LIBRARIES}) - endif () install(TARGETS UtilityLibrary DESTINATION lib) endif (BUILD_SHARED_LIBS) #Create Utility static library and add ncurses if we have it add_library(ResourceStatic STATIC $) -target_link_libraries(ResourceStatic ${CMAKE_THREAD_LIBS_INIT}) if (USE_ROOT) target_link_libraries(ResourceStatic ${ROOT_LIBRARIES}) endif (USE_ROOT) \ No newline at end of file diff --git a/Scan/Resources/source/RootFitter.cpp b/Scan/Resources/source/RootFitter.cpp index 2163bb20d..360b4bd78 100644 --- a/Scan/Resources/source/RootFitter.cpp +++ b/Scan/Resources/source/RootFitter.cpp @@ -36,6 +36,8 @@ double RootFitter::CalculatePhase(const std::vector &data, 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; diff --git a/Scan/Resources/source/TraditionalCfd.cpp b/Scan/Resources/source/TraditionalCfd.cpp index 1e4694d36..f36388141 100644 --- a/Scan/Resources/source/TraditionalCfd.cpp +++ b/Scan/Resources/source/TraditionalCfd.cpp @@ -1,5 +1,6 @@ ///@file TraditionalCfd.cpp -///@brief Traditional CFD implemented digitally +///@brief Traditional CFD implemented digitally, similar behavior to a NIM +/// Module. ///@author S. V. Paulauskas ///@date July 22, 2011 diff --git a/Scan/Resources/source/XiaCfd.cpp b/Scan/Resources/source/XiaCfd.cpp index 3ae25c1c1..a68e26d46 100644 --- a/Scan/Resources/source/XiaCfd.cpp +++ b/Scan/Resources/source/XiaCfd.cpp @@ -1,10 +1,11 @@ -// -// Created by vincent on 12/6/16. -// +///@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. +/// Perform CFD analysis on the waveform double XiaCfd::CalculatePhase(const double &F_/*=0.5*/, const size_t &D_/*=1*/, const size_t &L_/*=1*/) { diff --git a/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index 9a0cd2123..fe35e6f57 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -8,7 +8,7 @@ if(USE_GSL AND BUILD_TESTS) #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} UnitTest++) + target_link_libraries(test_gslfitter ${GSL_LIBRARIES}) endif(USE_GSL AND BUILD_TESTS) if(BUILD_UNITTESTS) diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index fbd947b71..d5c0031bf 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -61,6 +61,7 @@ TEST(TestFindMaxiumum) { CHECK_EQUAL(expected_maximum_value, result.second); } + TEST(TestFindLeadingEdge) { //This is the expected position of the leading edge of signal. static const unsigned int expected_leading_edge_position = 72; @@ -97,14 +98,15 @@ TEST(TestCalculatePoly3) { //Check that we are returning the correct coefficients for the data being // passed. - CHECK_ARRAY_CLOSE(expected_poly3_coeffs, result.second, 4, 1e-6); + CHECK_ARRAY_CLOSE(expected_poly3_coeffs, result.second, + expected_poly3_coeffs.size(), 1e-6); //Check that the calculated maximum value is accurate CHECK_CLOSE(expected_poly3_val, result.first, 1e-6); } -//For determination of the maximum value of the trace this traces favors the -// left side since max+1 is less than max - 1 +//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_data, @@ -119,7 +121,8 @@ TEST(TestExtrapolateMaximum) { //Check that we are returning the correct coefficients for the data being // passed. - CHECK_ARRAY_CLOSE(expected_coeffs, result.second, 4, 1e-3); + CHECK_ARRAY_CLOSE(expected_coeffs, result.second, + expected_coeffs.size(), 1e-3); } TEST(TestCalculatePoly2) { @@ -131,7 +134,8 @@ TEST(TestCalculatePoly2) { //Check that we are returning the correct coefficients for the data being // passed. - CHECK_ARRAY_CLOSE(expected_poly2_coeffs, result.second, 3, 1e-3); + CHECK_ARRAY_CLOSE(expected_poly2_coeffs, result.second, + expected_poly2_coeffs.size(), 1e-3); CHECK_CLOSE(expected_poly2_val, result.first, 1e-4); } @@ -151,6 +155,8 @@ TEST(TestCalculateQdc) { //Check that we are throwing an error when the range is too large CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(0, 1000)), range_error); + CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(1000, 0)), + range_error); CHECK_EQUAL(expected, TraceFunctions::CalculateQdc (integration_data, make_pair(2, 5))); } @@ -159,14 +165,13 @@ TEST(TestCalculateTailRatio) { //Check that we are throwing an error when the data is empty CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_data, make_pair(0, 4), 100.0), range_error); - //Check that the upper bound of the range is not too big - CHECK_THROW(TraceFunctions::CalculateTailRatio(empty_data, + //Check that the upper bound of the range is not bigger than the data size + CHECK_THROW(TraceFunctions::CalculateTailRatio(data, make_pair(0, 400), 100.0), range_error); - //Check that the QDC we passed actually makes sense + //Check that the QDC is not zero CHECK_THROW(TraceFunctions::CalculateTailRatio(data, make_pair(0, 4), 0.0), range_error); - double qdc = TraceFunctions::CalculateQdc(data, make_pair(70, 91)); pair range(80, 91); double result = TraceFunctions::CalculateTailRatio(data, range, qdc); diff --git a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp b/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp index 1ef82f0d4..20b6c7547 100644 --- a/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/CfdAnalyzer.hpp @@ -13,7 +13,7 @@ //! Class to analyze traces using a digital CFD class CfdAnalyzer : public TraceAnalyzer { public: - /** Default constructor */ + /** Default constructor taking an argument*/ CfdAnalyzer(const std::string &s); /** Default Destructor */ diff --git a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp index b97422a75..c9af60cbd 100644 --- a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp @@ -42,17 +42,17 @@ void CfdAnalyzer::Analyze(Trace &trace, const std::string &detType, } if (trace.HasValue("saturation") || trace.empty() || - trace.GetWaveform().size() == 0) { + trace.GetWaveform().empty()) { EndAnalyze(); return; } const pair baseline(trace.GetValue("baseline"), trace.GetValue("sigmaBaseline")); - pair max(trace.GetValue("maxpos"), + const pair max(trace.GetValue("maxpos"), trace.GetValue("extrapolatedMaxVal")); - pair pars = + const pair pars = Globals::get()->cfdPars(detType + ":" + detSubtype); trace.InsertValue("phase", diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index 419004c5a..d7a3b55a5 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -28,7 +28,7 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, const std::map &tags) { TraceAnalyzer::Analyze(trace, type, subtype, tags); - if (trace.HasValue("saturation") || trace.size() == 0) { + if (trace.HasValue("saturation") || trace.empty()) { EndAnalyze(); return; } diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index 311a335db..ba377c0c6 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -256,7 +256,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") { From 4b80ee587671a15e5ed3b2b287490b6d7ceb1b6a Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Mon, 12 Dec 2016 17:09:25 -0600 Subject: [PATCH 074/255] Updated terminal to handle ASCII codes for BS/DEL. ncurses.h does not have the ASCII codes fro backspace and delete. Added a check for those in addition to the codes in ncurses.h to handle these keys. This resolves issue #70. Former-commit-id: 1c13ce2ef7feb7aac6cdd480559047ff844e0a08 --- Core/source/CTerminal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/source/CTerminal.cpp b/Core/source/CTerminal.cpp index 1b53bb771..5b96a1ae7 100644 --- a/Core/source/CTerminal.cpp +++ b/Core/source/CTerminal.cpp @@ -961,14 +961,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 From 54891c36cca6e948a23462068775e589333e1b03 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 27 Dec 2016 09:05:10 -0500 Subject: [PATCH 075/255] Adding unit tests for the new Decoder Creating new decoder for Xia data and adding a unit test for this. Former-commit-id: daf45c6d32f3f5b2af044ffd0c3e64758c0a1155 --- Scan/ScanLib/CMakeLists.txt | 4 + .../include/XiaListModeDataDecoder.hpp | 22 +++ .../ScanLib/source/XiaListModeDataDecoder.cpp | 180 ++++++++++++++++++ Scan/ScanLib/tests/CMakeLists.txt | 6 + .../tests/unittest-XiaListModeDataDecoder.cpp | 128 +++++++++++++ 5 files changed, 340 insertions(+) create mode 100644 Scan/ScanLib/include/XiaListModeDataDecoder.hpp create mode 100644 Scan/ScanLib/source/XiaListModeDataDecoder.cpp create mode 100644 Scan/ScanLib/tests/CMakeLists.txt create mode 100644 Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp diff --git a/Scan/ScanLib/CMakeLists.txt b/Scan/ScanLib/CMakeLists.txt index 33d664731..4c37c6273 100644 --- a/Scan/ScanLib/CMakeLists.txt +++ b/Scan/ScanLib/CMakeLists.txt @@ -4,3 +4,7 @@ if(BUILD_SHARED_LIBS) endif(BUILD_SHARED_LIBS) add_subdirectory(source) + +if(BUILD_UNITTESTS) + add_subdirectory(tests) +endif(BUILD_UNITTESTS) diff --git a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp new file mode 100644 index 000000000..d86356e1c --- /dev/null +++ b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp @@ -0,0 +1,22 @@ +/// @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" + +class XiaListModeDataDecoder { +public: + XiaListModeDataDecoder(){}; + ~XiaListModeDataDecoder(){}; + + std::vector DecodeBuffer(unsigned int *buf); +private: + +}; + +#endif //PIXIESUITE_XIALISTMODEDATADECODER_HPP diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp new file mode 100644 index 000000000..53ce0a9e8 --- /dev/null +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -0,0 +1,180 @@ +/// @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 "XiaListModeDataDecoder.hpp" + +using namespace std; + +enum HEADER_CODES { + STATS_BLOCK = 1, HEADER = 4, HEADER_W_TS = 6, HEADER_W_ESUMS = 8, + HEADER_W_QDC = 12, HEADER_W_TS_ESUM = 10, HEADER_W_ESUM_QDC = 14, + HEADER_W_TS_QDC_ESUM = 16 +}; + +vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { + 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). Do these technically belong here? They + /// are not part of decoding the XIA data. In addition, we are passing in + /// the bufLen, but not using is in ReadSpill. + ///@TODO : Reevaluate where these two things go. + 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; + XiaData *lastVirtualChannel = NULL; + + while (buf < bufStart + bufLen) { + XiaData currentEvt; + bool hasExternalTimestamp = false; + bool hasQdc = false; + bool hasEnergySums = false; + + 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); + + 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_TS : + hasExternalTimestamp = true; + break; + case HEADER_W_QDC : + hasQdc = true; + break; + case HEADER_W_ESUMS : + hasEnergySums = true; + break; + case HEADER_W_TS_ESUM : + hasExternalTimestamp = hasEnergySums = true; + break; + case HEADER_W_ESUM_QDC : + hasEnergySums = hasQdc = true; + break; + case HEADER_W_TS_QDC_ESUM : + hasEnergySums = hasExternalTimestamp = hasQdc = true; + default: + msg << "XiaListModeDataDecoder::ReadBuffer : We encountered an " + "unrecognized header length (" + << headerLength << "). Skipping the remaining buffer." + << endl << "ReadBuffer: Unexpected header length: " + << headerLength << endl << "ReadBuffer: Buffer " + << modNum << " of length " << bufLen << endl + << "ReadBuffer: CHAN:SLOT:CRATE " << chanNum << ":" + << slotNum << ":" << crateNum << endl; + throw length_error(msg.str()); + } + + 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(hasExternalTimestamp) { + //Do nothing for now + } + + if (hasEnergySums) { + // Skip the onboard partial sums for now + // trailing, leading, gap, baseline + } + + if (hasQdc) { + int offset = headerLength - 8; + for (int i = 0; i < currentEvt.numQdcs; i++) { + currentEvt.qdcValue[i] = buf[offset + i]; + } + } + + currentEvt.chanNum = chanNum; + currentEvt.modNum = modNum += 100 * crateNum; + currentEvt.slotNum = slotNum; + + /*if(currentEvt.virtualChannel){ + DetectorLibrary* modChan = DetectorLibrary::get(); + + currentEvt.modNum += modChan->GetPhysicalModules(); + if(modChan->at(modNum, chanNum).HasTag("construct_trace")){ + lastVirtualChannel = currentEvt; + } + }*/ + + ///@TODO Figure out where to put this... + //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 * pow(2., 32.) + lowTime; + + // One last check + if (traceLength / 2 + headerLength != eventLength) { + msg << "ReadBuffer: Bad event length (" << eventLength + << ") does not correspond with length of header (" + << headerLength << ") and length of trace (" << traceLength + << ")"; + throw length_error(msg.str()); + } + + buf += headerLength; + if (traceLength > 0) { + // sbuf points to the beginning of trace data + unsigned short *sbuf = (unsigned short *) buf; + + currentEvt.reserve(traceLength); + + 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; + } // if(traceLength > 0) + events.push_back(currentEvt); + } + return events; +} \ No newline at end of file diff --git a/Scan/ScanLib/tests/CMakeLists.txt b/Scan/ScanLib/tests/CMakeLists.txt new file mode 100644 index 000000000..823ce2396 --- /dev/null +++ b/Scan/ScanLib/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(unittest-XiaListModeDataDecoder + unittest-XiaListModeDataDecoder.cpp + ../source/XiaData.cpp + ../source/XiaListModeDataDecoder.cpp) +target_link_libraries(unittest-XiaListModeDataDecoder UnitTest++ ${LIBS}) +install(TARGETS unittest-XiaListModeDataDecoder DESTINATION bin/unittests) \ No newline at end of file diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp new file mode 100644 index 000000000..fee590e43 --- /dev/null +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -0,0 +1,128 @@ +///@file unittest-XiaListModeDataDecoder.cpp +///@brief Unit tests for the XiaListModeDataDecoder class +///@author S. V. Paulauskas +///@author December 25, 2016 +#include +#include + +#include "XiaListModeDataDecoder.hpp" + +using namespace std; + +///We have added in the first to elements for the pixie module data header. +/// It contains the information about how many words are in the buffer and +/// the module VSN (number). +///This 4 word header has the following characteristics: +/// 1. Word 0 +/// * Channel Number [3:0] : 13 +/// * Slot ID [7:4] : 2 +/// * CrateID [11:8] : 0 +/// * Header Length[16:12] : 4 +/// * Event Length [30:17] : 4 +/// * Finish Code [31] : 0 +/// 2. Word 1 +/// * EVTTIME_LO [0:31] : 123456789 +/// 3. Word 2 +/// * EVTTIME_HI [0:15] : 26001 +/// * CFD Fractional Time [30:16] : 0 +/// * CFD Trigger source bit [31] : 0 +/// 4. Word 3 +/// * Event Energy [0:14] : 2345 +/// * Trace Out-of-Range Flag [15] : 0 +/// * Trace Length [31:16] : 0 +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 +}; + +unsigned int header_N_qdc[14] = { + 12, 0, 1622061, 123456789, 26001, 2345, + 123, 456, 789, 987, 654, 321, 135, 791 +}; + +//Here is all of the expected data for the above header. +static const unsigned int expected_chan = 13; +static const unsigned int expected_size = 1; +static const unsigned int expected_ts_high = 26001; +static const unsigned int expected_ts_low = 123456789; +static const unsigned int expected_slot = 2; +static const unsigned int expected_energy = 2345; +static const double expected_ts = 111673568120085; +static const vector expected_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 vector expected_qdc = {123, 456, 789, 987, 654, + 321, 135, 791}; + +TEST_FIXTURE(XiaListModeDataDecoder, TestBufferLengthChecks) { + //Check for a length_error when the buffer length is zero + unsigned int buffer_len_zero[6] = {0, 0}; + CHECK_THROW(DecodeBuffer(&buffer_len_zero[0]), length_error); + //Check for an empty vector when the buffer length is 2 (empty module) + unsigned int buffer_len_two[6] = {2, 0}; + unsigned int expected_size = 0; + CHECK_EQUAL(expected_size, DecodeBuffer(&buffer_len_two[0]).size()); +} +///Test fixture testing if we can decode a simple 4 word +/// header that includes the Pixie Module Data Header. +TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { + //Check for length_error when the header has an impossible size. + ///A header with a header length 20 instead of the true header length 4 + unsigned int header_w_bad_len[6] = {4, 0, 3887149, 123456789, 26001, 2345}; + CHECK_THROW(DecodeBuffer(&header_w_bad_len[0]), length_error); + + //Check that we can decode a simple 4-word header. + vector result = DecodeBuffer(&header[0]); + XiaData result_data = result.front(); + + CHECK_EQUAL(expected_size, result.size()); + CHECK_EQUAL(expected_slot, result_data.slotNum); + CHECK_EQUAL(expected_chan, result_data.chanNum); + CHECK_EQUAL(expected_energy, result_data.energy); + CHECK_EQUAL(expected_ts_high, result_data.eventTimeHi); + CHECK_EQUAL(expected_ts_low, result_data.eventTimeLo); + CHECK_EQUAL(expected_ts, result_data.time); + CHECK_EQUAL(expected_ts_low, result_data.trigTime); +} + +//Test fixture testing if we can decode a trace properly +TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { + unsigned int badlen[6] = { + 59, 0, 7749677, 123456789, 26001, 8128809}; + //Check that we throw length_error when the event length doesn't match. + CHECK_THROW(DecodeBuffer(&badlen[0]), length_error); + + XiaData result = DecodeBuffer(&header_N_trace[0]).front(); + CHECK_ARRAY_EQUAL(expected_trace, result.adcTrace, expected_trace.size()); +} + +//Test fixture testing if we can decode the qdc properly +TEST_FIXTURE(XiaListModeDataDecoder, TestQdcDecoding) { + XiaData result = DecodeBuffer(&header_N_qdc[0]).front(); + CHECK_ARRAY_EQUAL(expected_qdc, result.qdcValue, expected_qdc.size()); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file From 6c2e272dc21b46d8e492f1ed0b8d0607b686b78a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 30 Dec 2016 17:15:34 -0500 Subject: [PATCH 076/255] Creating class that provides XIA bit masks and bit shifts f These bit masks change depending on the firmware and clock frequency of the Pixie-16 modules. This class automatically picks the appropriate mask and bit for the specified firmware and frequency. Former-commit-id: b45391ed1fa9272ac767c3786fc66b3c12949067 --- Scan/ScanLib/include/XiaListModeDataMask.hpp | 154 +++++++++++ Scan/ScanLib/source/XiaListModeDataMask.cpp | 244 ++++++++++++++++++ Scan/ScanLib/tests/CMakeLists.txt | 9 +- .../tests/unittest-XiaListModeDataMask.cpp | 181 +++++++++++++ 4 files changed, 587 insertions(+), 1 deletion(-) create mode 100644 Scan/ScanLib/include/XiaListModeDataMask.hpp create mode 100644 Scan/ScanLib/source/XiaListModeDataMask.cpp create mode 100644 Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp new file mode 100644 index 000000000..9626aaa66 --- /dev/null +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -0,0 +1,154 @@ +/// @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 + +///An enum for the different firmware revisions for the Pixie-16 modules. +/// * R29432 is valid from 02/15/2014 and 07/28/2014 +/// * R30474, R30980, R30981 is valid from 07/28/2014 and 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 { + R29432, R30474, R30980, R30981, R34688, UNKNOWN +}; + +///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_ = UNKNOWN; + } + + ///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() { + 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() { + 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() { + 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() { + 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() { + return std::make_pair(0x1FFE0000, 17); + }; + + ///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() { + 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() { + 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(); + + ///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(); + + ///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(); + + ///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(); + + ///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(); + + ///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(); + + ///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. + FIRMWARE GetFirmware() { 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() { return frequency_; } + + ///Sets the firmware version + ///@param[in] firmware : The string that we are going to convert to the + /// more useful FIRMWARE enum. + void SetFirmware(const std::string &firmware) { + firmware_ = ConvertStringToFirmware(firmware); + } + + ///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; } + +private: + ///The firmware version that we are using. + FIRMWARE firmware_; + ///The frequency of the module that we want to decode. + unsigned int frequency_; + + std::string BadMaskErrorMessage(const std::string &func); + + ///Method that converts the given string to the FIRMWARE enum + ///@param[in] type : A string that we want to convert to the + /// equivalent FIRMWARE enum type. + ///@throws invalid_argument when given a string it cannot convert + ///@return The firmware enum type that we found + FIRMWARE ConvertStringToFirmware(const std::string &type); +}; + +#endif //PIXIESUITE_XIALISTMODEDATAMASK_HPP diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp new file mode 100644 index 000000000..70c4174e5 --- /dev/null +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -0,0 +1,244 @@ +/// @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 "XiaListModeDataMask.hpp" + +using namespace std; + +FIRMWARE XiaListModeDataMask::ConvertStringToFirmware( + const std::string &type) { + FIRMWARE firmware = UNKNOWN; + stringstream msg; + if (type == "R29432") + firmware = R29432; + else if (type == "R30474") + firmware = R30474; + else if (type == "R30980") + firmware = R30980; + else if (type == "R30981") + firmware = R30981; + else if (type == "R34688") + 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() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R29432: + mask = 0xFFFF0000; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x7FFF0000; + break; + case UNKNOWN: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R29432: + mask = 0x7FFF0000; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x3FFF0000; + break; + case UNKNOWN: + break; + } + } else if (frequency_ == 500) { + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x1FFF0000; + break; + case UNKNOWN: + break; + } + } + return make_pair(mask, 16); +} + +pair +XiaListModeDataMask::GetCfdForcedTriggerBitMask() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + unsigned int bit = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R29432: + mask = 0; + bit = 0; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x80000000; + bit = 31; + break; + case UNKNOWN: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x80000000; + bit = 31; + break; + case R29432: + case UNKNOWN: + break; + } + } + return make_pair(mask, bit); +} + +pair +XiaListModeDataMask::GetCfdTriggerSourceMask() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + unsigned int bit = 0; + if (frequency_ == 250) { + switch (firmware_) { + case R29432: + mask = 0x80000000; + bit = 31; + break; + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0x40000000; + bit = 30; + break; + case UNKNOWN: + break; + } + } else if (frequency_ == 500) { + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + case R34688: + mask = 0xE0000000; + bit = 29; + break; + case UNKNOWN: + 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() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0x00007FFF; + break; + case R34688: + mask = 0x0000FFFF; + break; + case UNKNOWN: + 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() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + + unsigned int mask = 0; + unsigned int bit = 0; + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0x00008000; + bit = 15; + break; + case R34688: + mask = 0x80000000; + bit = 31; + break; + case UNKNOWN: + break; + } + return make_pair(mask, bit); +} + +//Trace Length always starts on bit 16 of Word 3. +pair XiaListModeDataMask::GetTraceLengthMask() { + if (firmware_ == UNKNOWN || frequency_ == 0) + throw invalid_argument(BadMaskErrorMessage + ("GetCfdFractionalTimeMask")); + unsigned int mask = 0; + switch (firmware_) { + case R29432: + case R30474: + case R30980: + case R30981: + mask = 0xFFFF0000; + break; + case R34688: + mask = 0x7FFF0000; + break; + case UNKNOWN: + break; + } + return make_pair(mask, 16); +} + +string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) { + stringstream msg; + msg << "XiaListModeDataMask::" << func << " : " + << "Could not obtain a mask for firmware code " << firmware_ + << " and frequency " << frequency_ << ". Check your settings."; + return msg.str(); +} \ No newline at end of file diff --git a/Scan/ScanLib/tests/CMakeLists.txt b/Scan/ScanLib/tests/CMakeLists.txt index 823ce2396..72d8da701 100644 --- a/Scan/ScanLib/tests/CMakeLists.txt +++ b/Scan/ScanLib/tests/CMakeLists.txt @@ -3,4 +3,11 @@ add_executable(unittest-XiaListModeDataDecoder ../source/XiaData.cpp ../source/XiaListModeDataDecoder.cpp) target_link_libraries(unittest-XiaListModeDataDecoder UnitTest++ ${LIBS}) -install(TARGETS unittest-XiaListModeDataDecoder DESTINATION bin/unittests) \ No newline at end of file +install(TARGETS unittest-XiaListModeDataDecoder 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) \ No newline at end of file diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp new file mode 100644 index 000000000..2a09dd24f --- /dev/null +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -0,0 +1,181 @@ +///@file unittest-XiaListModeDataMask.cpp +///@brief Unit testing of the XiaListModeDataMask class +///@author S. V. Paulauskas +///@date December 29, 2016 +#include +#include + +#include + +#include "XiaListModeDataMask.hpp" + +using namespace std; + +TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { + //Check that we throw an invalid argument when we put in an unrecognized + // option. + CHECK_THROW(SetFirmware("test"), invalid_argument); + + //Checking that the if statement works as expected when converting to the + // different firmware revisions. + SetFirmware("R29432"); + CHECK_EQUAL(R29432, GetFirmware()); + + SetFirmware("R30474"); + CHECK_EQUAL(R30474, GetFirmware()); + + SetFirmware("R30980"); + CHECK_EQUAL(R30980, GetFirmware()); + + SetFirmware("R30981"); + CHECK_EQUAL(R30981, GetFirmware()); + + SetFirmware("R34688"); + CHECK_EQUAL(R34688, GetFirmware()); + + //We do not need to test more than on version of these since they are + // identical across all firmware versions. + 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) 0x1FFE0000, GetEventLengthMask().first); + CHECK_EQUAL((unsigned int) 17, GetEventLengthMask().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); + } +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file From c05bd1e43614653aaed8ca458f16e53b9f929160 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sat, 31 Dec 2016 11:59:25 -0500 Subject: [PATCH 077/255] Updating XiaData, adding unit tests, Updating XiaListModeDataMask I have reworked XiaData and broken it up into the two separate classes. This makes the class much more useable and makes comparisons easier. In addition, I've added the additional information from the XIa List Mode Data buffer that were not included. I have updated the XiaListModeDataMask class to better make use of the enum. Former-commit-id: f21c0c475c0cd94114812decaa40657c18b2328f --- Scan/ScanLib/CMakeLists.txt | 4 +- Scan/ScanLib/include/ChannelEvent.hpp | 62 ++++ Scan/ScanLib/include/XiaData.hpp | 343 +++++++++++++----- Scan/ScanLib/include/XiaListModeDataMask.hpp | 56 +-- Scan/ScanLib/source/CMakeLists.txt | 3 +- Scan/ScanLib/source/ChannelEvent.cpp | 184 ++++++++++ Scan/ScanLib/source/XiaData.cpp | 168 +++------ Scan/ScanLib/source/XiaListModeDataMask.cpp | 19 +- Scan/ScanLib/tests/CMakeLists.txt | 6 +- Scan/ScanLib/tests/unittest-XiaData.cpp | 205 +++++++++++ .../tests/unittest-XiaListModeDataMask.cpp | 46 +-- Scan/util/source/scope.cpp | 1 + 12 files changed, 806 insertions(+), 291 deletions(-) create mode 100644 Scan/ScanLib/include/ChannelEvent.hpp create mode 100644 Scan/ScanLib/source/ChannelEvent.cpp create mode 100644 Scan/ScanLib/tests/unittest-XiaData.cpp diff --git a/Scan/ScanLib/CMakeLists.txt b/Scan/ScanLib/CMakeLists.txt index 4c37c6273..a82afe023 100644 --- a/Scan/ScanLib/CMakeLists.txt +++ b/Scan/ScanLib/CMakeLists.txt @@ -3,8 +3,8 @@ if(BUILD_SHARED_LIBS) install(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX}) endif(BUILD_SHARED_LIBS) -add_subdirectory(source) - if(BUILD_UNITTESTS) add_subdirectory(tests) endif(BUILD_UNITTESTS) + +add_subdirectory(source) diff --git a/Scan/ScanLib/include/ChannelEvent.hpp b/Scan/ScanLib/include/ChannelEvent.hpp new file mode 100644 index 000000000..9d6604867 --- /dev/null +++ b/Scan/ScanLib/include/ChannelEvent.hpp @@ -0,0 +1,62 @@ +///@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 "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(); + + /// 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/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index b86a89fb3..b4c6162ea 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -1,11 +1,14 @@ +///@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 -#include -#include #include -#include + +#include +#include /*! \brief A pixie16 channel event * @@ -16,101 +19,255 @@ * 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{ +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). - int getID(){ return(modNum*16+chanNum); } - + 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 (cfdTime_ / pow(2., 14)) + eventTimeLow_ + + (eventTimeHigh_ * pow(2., 32)) - cfdTrigSource_; + } + + ///@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. + unsigned int GetId() const { + return crateNum_ * 208 + moduleNum_ * 16 + chanNum_; + } + + ///@brief This method returns the module number. + ///@return The module number + unsigned int GetModuleNumber() const { return moduleNum_; } + + ///@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 the module number + ///@param[in] a : The value to set + void SetModuleNumber(const unsigned int &a) { moduleNum_ = 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 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; } + /// Reserve specified number of bins for the channel trace. - void reserve(const size_t &size_); - + //void reserve(const size_t &size); + /// Fill the trace vector with a specified value. - void assign(const size_t &size_, const int &input_); - + //void assign(const size_t &size, const unsigned 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(); -}; + //void push_back(const unsigned int &input); -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 *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). - size_t cfdIndex; /// The index in the trace just above the CFD threshold. - - float cfdPar[7]; /// Array of floats for storing cfd polynomial fits. - - 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(); - - /// Clear all variables and clear the trace vector and arrays. + ///@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 + + 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 moduleNum_; ///Module number set from the data stream + 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 +#endif \ No newline at end of file diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index 9626aaa66..890b140c6 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -40,8 +40,8 @@ class XiaListModeDataMask { ///@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); + XiaListModeDataMask(const FIRMWARE &firmware, const unsigned int &freq) { + firmware_ = firmware; frequency_ = freq; } @@ -50,104 +50,106 @@ class 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() { + 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() { + 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() { + 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() { + 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() { + std::pair GetEventLengthMask() const { return std::make_pair(0x1FFE0000, 17); }; ///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() { + 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() { + 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(); + 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(); + 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(); + std::pair GetCfdTriggerSourceMask() 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(); + 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(); + 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(); + std::pair GetTraceLengthMask() const; ///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. - FIRMWARE GetFirmware() { return firmware_; } + 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() { return frequency_; } + unsigned int GetFrequency() const { return frequency_; } ///Sets the firmware version - ///@param[in] firmware : The string that we are going to convert to the - /// more useful FIRMWARE enum. - void SetFirmware(const std::string &firmware) { - firmware_ = ConvertStringToFirmware(firmware); + ///@param[in] firmware : The firmware type that we would like to set. + void SetFirmware(const 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; } + private: ///The firmware version that we are using. FIRMWARE firmware_; ///The frequency of the module that we want to decode. unsigned int frequency_; - std::string BadMaskErrorMessage(const std::string &func); + std::string BadMaskErrorMessage(const std::string &func) const; - ///Method that converts the given string to the FIRMWARE enum - ///@param[in] type : A string that we want to convert to the - /// equivalent FIRMWARE enum type. - ///@throws invalid_argument when given a string it cannot convert - ///@return The firmware enum type that we found FIRMWARE ConvertStringToFirmware(const std::string &type); }; diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt index f86d78fcf..a35620b73 100644 --- a/Scan/ScanLib/source/CMakeLists.txt +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -1,5 +1,6 @@ #Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp RootScanner.cpp) +set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp + ChannelEvent.cpp) #Add the sources to the library add_library(ScanObjects OBJECT ${ScanSources}) diff --git a/Scan/ScanLib/source/ChannelEvent.cpp b/Scan/ScanLib/source/ChannelEvent.cpp new file mode 100644 index 000000000..06d1c3fc8 --- /dev/null +++ b/Scan/ScanLib/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->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; +} \ No newline at end of file diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index e0d482439..4221b0d3d 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -1,129 +1,45 @@ -#include - -#include "HelperFunctions.hpp" +///@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" -///////////////////////////////////////////////////////////////////// -// 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; - cfdvals = NULL; - Clear(); -} - -/// Constructor from a XiaData. ChannelEvent will take ownership of the XiaData. -ChannelEvent::ChannelEvent(XiaData *event_){ - event = NULL; - cfdvals = NULL; - Clear(); - event = event_; - size = event->adcTrace.size(); -} - -ChannelEvent::~ChannelEvent(){ - if(event){ delete event; } - if(cfdvals){ delete[] cfdvals; } -} - -void ChannelEvent::Clear(){ - phase = -9999; - maximum = -9999; - baseline = -9999; - stddev = -9999; - qdc = -9999; - cfdCrossing = -9999; - max_index = 0; - cfdIndex = 0; - - hires_energy = -9999; - hires_time = -9999; - - valid_chan = false; - ignore = false; - - size = 0; - if(cfdvals){ delete[] cfdvals; } - if(event){ event->clear(); } - - event = NULL; - cfdvals = NULL; +///@TODO These methods are commented out since I'm not sure that we need them +/// . This should be verified at some point. +//void XiaData::reserve(const size_t &size){ +// if(size == 0){ return; } +// trace_.reserve(size); +//} +// +//void XiaData::assign(const size_t &size, const unsigned int &input){ +// trace_.assign(size, input); +//} +// +//void XiaData::push_back(const unsigned int &input){ +// trace_.push_back(input); +//} + +///Clears all of the varaibles. For values where 0 is a valid option +/// (crateNum_, chanNum_, etc.) the values are set to 9999. The vectors +/// are all cleared using the clear() method. This method is called when the +/// class is first initiatlized so that it has some default values for the +/// software to use in the event that they are needed. +void XiaData::Clear(){ + cfdForceTrig_ = false; + cfdTrigSource_ = false; + isPileup_ = false; + isSaturated_ = false; + isVirtualChannel_ = false; + + energy_ = 0.0; + + chanNum_ = 9999; + cfdTime_ = 0; + crateNum_ = 9999; + eventTimeHigh_ = 0; + eventTimeLow_ = 0; + slotNum_ = 9999; + + qdc_.clear(); + trace_.clear(); } \ No newline at end of file diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 70c4174e5..1564bb7f0 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -8,8 +8,7 @@ using namespace std; -FIRMWARE XiaListModeDataMask::ConvertStringToFirmware( - const std::string &type) { +FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { FIRMWARE firmware = UNKNOWN; stringstream msg; if (type == "R29432") @@ -33,7 +32,7 @@ FIRMWARE XiaListModeDataMask::ConvertStringToFirmware( ///The CFD Fractional Time always starts on bit 16 of Word 2. The range of /// this value changes. pair -XiaListModeDataMask::GetCfdFractionalTimeMask() { +XiaListModeDataMask::GetCfdFractionalTimeMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -83,7 +82,7 @@ XiaListModeDataMask::GetCfdFractionalTimeMask() { } pair -XiaListModeDataMask::GetCfdForcedTriggerBitMask() { +XiaListModeDataMask::GetCfdForcedTriggerBitMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -123,7 +122,7 @@ XiaListModeDataMask::GetCfdForcedTriggerBitMask() { } pair -XiaListModeDataMask::GetCfdTriggerSourceMask() { +XiaListModeDataMask::GetCfdTriggerSourceMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -164,7 +163,8 @@ XiaListModeDataMask::GetCfdTriggerSourceMask() { /// 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() { +pair XiaListModeDataMask::GetEventEnergyMask() +const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -188,7 +188,7 @@ pair XiaListModeDataMask::GetEventEnergyMask() { //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() { +XiaListModeDataMask::GetTraceOutOfRangeFlagMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -214,7 +214,8 @@ XiaListModeDataMask::GetTraceOutOfRangeFlagMask() { } //Trace Length always starts on bit 16 of Word 3. -pair XiaListModeDataMask::GetTraceLengthMask() { +pair XiaListModeDataMask::GetTraceLengthMask() +const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); @@ -235,7 +236,7 @@ pair XiaListModeDataMask::GetTraceLengthMask() { return make_pair(mask, 16); } -string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) { +string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) const { stringstream msg; msg << "XiaListModeDataMask::" << func << " : " << "Could not obtain a mask for firmware code " << firmware_ diff --git a/Scan/ScanLib/tests/CMakeLists.txt b/Scan/ScanLib/tests/CMakeLists.txt index 72d8da701..1bd0ade71 100644 --- a/Scan/ScanLib/tests/CMakeLists.txt +++ b/Scan/ScanLib/tests/CMakeLists.txt @@ -10,4 +10,8 @@ add_executable(unittest-XiaListModeDataMask ../source/XiaData.cpp ../source/XiaListModeDataMask.cpp) target_link_libraries(unittest-XiaListModeDataMask UnitTest++ ${LIBS}) -install(TARGETS unittest-XiaListModeDataMask DESTINATION bin/unittests) \ No newline at end of file +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/Scan/ScanLib/tests/unittest-XiaData.cpp b/Scan/ScanLib/tests/unittest-XiaData.cpp new file mode 100644 index 000000000..518a5b261 --- /dev/null +++ b/Scan/ScanLib/tests/unittest-XiaData.cpp @@ -0,0 +1,205 @@ +///@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 "XiaData.hpp" + +using namespace std; + +static const bool test_bool = true; +static const double test_baseline = 32.2; +static const double test_energy = 123.4; +static const unsigned int test_cfd_time = 124; +static const unsigned int test_channel_number = 13; +static const unsigned int test_crate_number = 0; +static const unsigned int test_event_time_high = 1234; +static const unsigned int test_event_time_low = 123456789; +static const unsigned int test_external_time_high = 4321; +static const unsigned int test_external_time_low = 987654321; +static const unsigned int test_slot_number = 3; +static const unsigned int test_module_number = 1; +static const vector test_energy_sums = {12, 13, 14}; +static const vector test_qdc = {12, 13, 14, 78, 23, 34, 35, 6}; +static const vector test_trace = {12, 12, 12, 12, 12, 75, 90, 54, + 32, 12, 12}; +XiaData lhs, rhs; + +TEST_FIXTURE(XiaData, Test_GetBaseline) { + SetBaseline(test_baseline); + CHECK_EQUAL(test_baseline, GetBaseline()); +} + +TEST_FIXTURE(XiaData, Test_GetId) { + SetSlotNumber(test_slot_number); + SetChannelNumber(test_channel_number); + SetCrateNumber(test_crate_number); + SetModuleNumber(test_module_number); + CHECK_EQUAL(test_crate_number * 208 + test_module_number * 16 + + test_channel_number, GetId()); +} + +TEST_FIXTURE(XiaData, Test_ModuleNumber) { + SetModuleNumber(test_module_number); + CHECK_EQUAL(test_module_number, GetModuleNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdForcedTrig) { + SetCfdForcedTriggerBit(test_bool); + CHECK(GetCfdForcedTriggerBit()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdFractionalTime) { + SetCfdFractionalTime(test_cfd_time); + CHECK_EQUAL(test_cfd_time, GetCfdFractionalTime()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCfdTriggerSourceBit) { + SetCfdTriggerSourceBit(test_bool); + CHECK(GetCfdTriggerSourceBit()); +} + +TEST_FIXTURE(XiaData, Test_GetSetChannelNumber) { + SetChannelNumber(test_channel_number); + CHECK_EQUAL(test_channel_number, GetChannelNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetCrateNumber) { + SetCrateNumber(test_crate_number); + CHECK_EQUAL(test_crate_number, GetCrateNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEnergy) { + SetEnergy(test_energy); + CHECK_EQUAL(test_energy, GetEnergy()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEnergySums) { + SetEnergySums(test_energy_sums); + CHECK_ARRAY_EQUAL(test_energy_sums, GetEnergySums(), + test_energy_sums.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEventTimeHigh) { + SetEventTimeHigh(test_event_time_high); + CHECK_EQUAL(test_event_time_high, GetEventTimeHigh()); +} + +TEST_FIXTURE(XiaData, Test_GetSetEventTimeLow) { + SetEventTimeLow(test_event_time_low); + CHECK_EQUAL(test_event_time_low, GetEventTimeLow()); +} + +TEST_FIXTURE(XiaData, Test_GetSetExternalTimeHigh) { + SetExternalTimeHigh(test_external_time_high); + CHECK_EQUAL(test_external_time_high, GetExternalTimeHigh()); +} + +TEST_FIXTURE(XiaData, Test_GetSetExternalTimeLow) { + SetExternalTimeLow(test_external_time_low); + CHECK_EQUAL(test_external_time_low, GetExternalTimeLow()); +} + +TEST_FIXTURE(XiaData, Test_GetSetPileup) { + SetPileup(test_bool); + CHECK(IsPileup()); +} + +TEST_FIXTURE(XiaData, Test_GetSetQdc) { + SetQdc(test_qdc); + CHECK_ARRAY_EQUAL(test_qdc, GetQdc(), test_qdc.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetSaturation) { + SetSaturation(test_bool); + CHECK(IsSaturated()); +} + +TEST_FIXTURE(XiaData, Test_GetSetSlotNumber) { + SetSlotNumber(test_slot_number); + CHECK_EQUAL(test_slot_number, GetSlotNumber()); +} + +TEST_FIXTURE(XiaData, Test_GetSetTrace) { + SetTrace(test_trace); + CHECK_ARRAY_EQUAL(test_trace, GetTrace(), test_trace.size()); +} + +TEST_FIXTURE(XiaData, Test_GetSetVirtualChannel) { + SetVirtualChannel(test_bool); + CHECK(IsVirtualChannel()); +} + +TEST_FIXTURE(XiaData, Test_GetTime) { + SetCfdFractionalTime(test_cfd_time); + SetEventTimeHigh(test_event_time_high); + SetEventTimeLow(test_event_time_low); + SetCfdTriggerSourceBit(test_bool); + CHECK_EQUAL(test_cfd_time / pow(2., 14) + test_event_time_low + + test_event_time_high * pow(2., 32) - test_bool, GetTime()); +} + +///This will test that the Time for the rhs is greater than the lhs +TEST(Test_CompareTime){ + lhs.Clear(); rhs.Clear(); + + lhs.SetCfdFractionalTime(test_cfd_time); + lhs.SetEventTimeHigh(test_event_time_high); + lhs.SetEventTimeLow(test_event_time_low); + lhs.SetCfdTriggerSourceBit(test_bool); + + rhs.SetCfdFractionalTime(test_cfd_time+12); + rhs.SetEventTimeHigh(test_event_time_high); + rhs.SetEventTimeLow(test_event_time_low+36); + rhs.SetCfdTriggerSourceBit(test_bool); + + 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(test_channel_number); + lhs.SetSlotNumber(test_slot_number); + lhs.SetCrateNumber(test_crate_number); + lhs.SetModuleNumber(test_module_number); + + rhs.SetChannelNumber(test_channel_number); + rhs.SetSlotNumber(test_slot_number+2); + rhs.SetCrateNumber(test_crate_number); + rhs.SetModuleNumber(test_module_number+2); + + CHECK(lhs.CompareId(&lhs, &rhs)); +} + +TEST(Test_Equality) { + lhs.Clear(); rhs.Clear(); + lhs.SetChannelNumber(test_channel_number); + lhs.SetSlotNumber(test_slot_number); + lhs.SetCrateNumber(test_crate_number); + rhs = lhs; + CHECK(lhs == rhs); +} + +TEST(Test_LessThanOperator) { + lhs.Clear(); rhs.Clear(); + lhs.SetCfdFractionalTime(test_cfd_time); + lhs.SetEventTimeHigh(test_event_time_high); + lhs.SetEventTimeLow(test_event_time_low); + lhs.SetCfdTriggerSourceBit(test_bool); + + rhs = lhs; + rhs.SetEventTimeLow(test_event_time_low+100); + + CHECK(lhs < rhs); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} + diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index 2a09dd24f..e912195aa 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -12,29 +12,9 @@ using namespace std; TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { - //Check that we throw an invalid argument when we put in an unrecognized - // option. - CHECK_THROW(SetFirmware("test"), invalid_argument); - - //Checking that the if statement works as expected when converting to the - // different firmware revisions. - SetFirmware("R29432"); - CHECK_EQUAL(R29432, GetFirmware()); - - SetFirmware("R30474"); - CHECK_EQUAL(R30474, GetFirmware()); - - SetFirmware("R30980"); - CHECK_EQUAL(R30980, GetFirmware()); - - SetFirmware("R30981"); - CHECK_EQUAL(R30981, GetFirmware()); - - SetFirmware("R34688"); - CHECK_EQUAL(R34688, GetFirmware()); - //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); @@ -61,7 +41,7 @@ TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { TEST_FIXTURE(XiaListModeDataMask, Test_100MSps_Word2) { SetFrequency(100); - SetFirmware("R29432"); + SetFirmware(R29432); CHECK_EQUAL((unsigned int) 0xFFFF0000, GetCfdFractionalTimeMask().first); CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); @@ -71,8 +51,8 @@ TEST_FIXTURE(XiaListModeDataMask, Test_100MSps_Word2) { 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++) { + 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); @@ -91,7 +71,7 @@ TEST_FIXTURE(XiaListModeDataMask, Test_100MSps_Word2) { TEST_FIXTURE(XiaListModeDataMask, Test_250Msps_Word2) { SetFrequency(250); - SetFirmware("R29432"); + SetFirmware(R29432); CHECK_EQUAL((unsigned int) 0x7FFF0000, GetCfdFractionalTimeMask().first); CHECK_EQUAL((unsigned int) 16, GetCfdFractionalTimeMask().second); @@ -101,8 +81,8 @@ TEST_FIXTURE(XiaListModeDataMask, Test_250Msps_Word2) { 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++) { + 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); @@ -121,9 +101,9 @@ TEST_FIXTURE(XiaListModeDataMask, Test_250Msps_Word2) { TEST_FIXTURE(XiaListModeDataMask, Test_500MSps_Word2) { SetFrequency(500); - vector firm = {"R29432", "R30474", "R30980", "R30981", "R34688"}; + vector firm = {R29432, R30474, R30980, R30981, R34688}; - for (vector::iterator it = firm.begin(); it != firm.end(); it++) { + for (vector::iterator it = firm.begin(); it != firm.end(); it++) { SetFirmware(*it); CHECK_EQUAL((unsigned int) 0x1FFF0000, GetCfdFractionalTimeMask().first); @@ -139,8 +119,10 @@ TEST_FIXTURE(XiaListModeDataMask, Test_500MSps_Word2) { 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++) { + + 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++) { @@ -159,7 +141,7 @@ TEST_FIXTURE(XiaListModeDataMask, Test_R29432_To_R30981_Word3) { } TEST_FIXTURE(XiaListModeDataMask, Test_R34688_Word3) { - SetFirmware("R34688"); + SetFirmware(R34688); vector freq = {100, 250, 500}; for (vector::iterator it = freq.begin(); it != freq.end(); it++) { diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index 501e47fb0..6f0583d2a 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -2,6 +2,7 @@ #include // PixieCore libraries +#include "ChannelEvent.hpp" #include "XiaData.hpp" // Local files From 831bdee5015ba30b2c40fd35b1bacdbf4a8e92e3 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sat, 31 Dec 2016 14:47:08 -0500 Subject: [PATCH 078/255] The encoder class is now complete enough to deploy. Former-commit-id: 4c6fd5569fae5e44691f4817b813535ee1fbb7f8 --- .../include/XiaListModeDataEncoder.hpp | 78 +++++++++ Scan/ScanLib/include/XiaListModeDataMask.hpp | 6 + Scan/ScanLib/source/XiaData.cpp | 25 ++- .../ScanLib/source/XiaListModeDataEncoder.cpp | 151 ++++++++++++++++++ Scan/ScanLib/tests/CMakeLists.txt | 8 + .../tests/unittest-XiaListModeDataEncoder.cpp | 118 ++++++++++++++ 6 files changed, 370 insertions(+), 16 deletions(-) create mode 100644 Scan/ScanLib/include/XiaListModeDataEncoder.hpp create mode 100644 Scan/ScanLib/source/XiaListModeDataEncoder.cpp create mode 100644 Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp diff --git a/Scan/ScanLib/include/XiaListModeDataEncoder.hpp b/Scan/ScanLib/include/XiaListModeDataEncoder.hpp new file mode 100644 index 000000000..89fb97964 --- /dev/null +++ b/Scan/ScanLib/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 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/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index 890b140c6..97ee2ce19 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -114,6 +114,12 @@ class XiaListModeDataMask { ///@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. diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 4221b0d3d..270f27cea 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -19,27 +19,20 @@ // trace_.push_back(input); //} -///Clears all of the varaibles. For values where 0 is a valid option -/// (crateNum_, chanNum_, etc.) the values are set to 9999. The vectors -/// are all cleared using the clear() method. This method is called when the -/// class is first initiatlized so that it has some default values for the -/// software to use in the event that they are needed. +///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_ = false; - cfdTrigSource_ = false; - isPileup_ = false; - isSaturated_ = false; + cfdForceTrig_ = cfdTrigSource_ = isPileup_ = isSaturated_ = false; isVirtualChannel_ = false; - energy_ = 0.0; + energy_ = baseline_ = 0.0; - chanNum_ = 9999; - cfdTime_ = 0; - crateNum_ = 9999; - eventTimeHigh_ = 0; - eventTimeLow_ = 0; - slotNum_ = 9999; + chanNum_ = crateNum_ = moduleNum_ = slotNum_ = cfdTime_ = 0; + eventTimeHigh_ = eventTimeLow_ = externalTimeLow_ = externalTimeHigh_ = 0; + eSums_.clear(); qdc_.clear(); trace_.clear(); } \ No newline at end of file diff --git a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp new file mode 100644 index 000000000..4e8085071 --- /dev/null +++ b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp @@ -0,0 +1,151 @@ +/// @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 "XiaListModeDataEncoder.hpp" + +using namespace std; + +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/Scan/ScanLib/tests/CMakeLists.txt b/Scan/ScanLib/tests/CMakeLists.txt index 1bd0ade71..d72b706f9 100644 --- a/Scan/ScanLib/tests/CMakeLists.txt +++ b/Scan/ScanLib/tests/CMakeLists.txt @@ -5,6 +5,14 @@ add_executable(unittest-XiaListModeDataDecoder 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 diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp new file mode 100644 index 000000000..448307a19 --- /dev/null +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp @@ -0,0 +1,118 @@ +///@file unittest-XiaListModeDataEncoder.cpp +///@brief Unit tests for the XiaListModeDataDecoder class +///@author S. V. Paulauskas +///@author December 25, 2016 +#include + +#include + +#include "XiaListModeDataEncoder.hpp" + +using namespace std; + +//Here is all of the expected data for the XiaData. +static const unsigned int chan = 13; +static const unsigned int slot = 2; +static const unsigned int crate = 0; +static const unsigned int ts_high = 26001; +static const unsigned int ts_low = 123456789; +static const unsigned int ex_ts_high = 26001; +static const unsigned int ex_ts_low = 123456789; +static const unsigned int energy = 2345; +static const 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 vector qdc = {123, 456, 789, 987, 654, + 321, 135, 791}; + +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) { + vector expected_header = + {540717, 123456789, 26001, 2345}; + vector expected_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 + }; + vector expected_w_qdc = { + 1622061, 123456789, 26001, 2345, + 123, 456, 789, 987, 654, 321, 135, 791 + }; + vector expected_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 + }; + + XiaData data; + data.SetEnergy(energy); + data.SetSlotNumber(slot); + data.SetChannelNumber(chan); + data.SetCrateNumber(crate); + data.SetEventTimeLow(ts_low); + data.SetEventTimeHigh(ts_high); + + //Check that we can handle just a simple 4 word header + CHECK_ARRAY_EQUAL(expected_header, EncodeXiaData(data, R30474, 250), + expected_header.size()); + + //Check that we can handle a header with a trace + data.SetTrace(trace); + CHECK_ARRAY_EQUAL(expected_w_trc, EncodeXiaData(data, R30474, 250), + expected_w_trc.size()); + + //Check that we can handle a QDC + data.SetQdc(qdc); + data.SetTrace(vector()); + CHECK_ARRAY_EQUAL(expected_w_qdc, EncodeXiaData(data, R30474, 250), + expected_w_qdc.size()); + + //Check that we can handle a QDC and a Trace + data.SetQdc(qdc); + data.SetTrace(trace); + CHECK_ARRAY_EQUAL(expected_w_qdc_n_trc, EncodeXiaData(data, R30474, 250), + expected_w_qdc_n_trc.size()); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file From 67444943077304caefbd9e349750313c0d23c765 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 2 Jan 2017 09:18:36 -0500 Subject: [PATCH 079/255] Updating Decoder and Mask to handle CFD info and Time Calculations We now calculate the times appropriately. The decoding works as expected. The DataMask has been updated to include information about the size of the CFD. The size is used when calculating the arrival time of the event. Former-commit-id: 15c842bab70002337baa02662262274be0f8c16b --- Scan/ScanLib/include/XiaData.hpp | 10 +- .../include/XiaListModeDataDecoder.hpp | 66 +++++- Scan/ScanLib/include/XiaListModeDataMask.hpp | 6 + .../ScanLib/source/XiaListModeDataDecoder.cpp | 216 ++++++++++++------ Scan/ScanLib/source/XiaListModeDataMask.cpp | 41 ++++ Scan/ScanLib/tests/CMakeLists.txt | 3 +- .../tests/unittest-XiaListModeDataDecoder.cpp | 62 +++-- .../tests/unittest-XiaListModeDataMask.cpp | 34 +++ 8 files changed, 333 insertions(+), 105 deletions(-) diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index b4c6162ea..8890b40ff 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -107,10 +107,7 @@ class XiaData { /// 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 (cfdTime_ / pow(2., 14)) + eventTimeLow_ + - (eventTimeHigh_ * pow(2., 32)) - cfdTrigSource_; - } + double GetTime() const { return time_; } ///@return The CFD fractional time in clockticks unsigned int GetCfdFractionalTime() const { return cfdTime_; } @@ -225,6 +222,10 @@ class XiaData { ///@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; } @@ -254,6 +255,7 @@ class XiaData { 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. diff --git a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp index d86356e1c..ae684e3d1 100644 --- a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp +++ b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp @@ -5,18 +5,78 @@ /// @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: - XiaListModeDataDecoder(){}; - ~XiaListModeDataDecoder(){}; + ///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); - std::vector DecodeBuffer(unsigned int *buf); 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); + + ///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 + ///@TODO This method needs to be moved to Resources so that it + /// can be taken advantage of by other classes. + 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 + ///@TODO This method needs to be moved to Resources so that it + /// can be taken advantage of by other classes. + double CalculateTimeInNs(const XiaListModeDataMask &mask, + const XiaData &data); }; #endif //PIXIESUITE_XIALISTMODEDATADECODER_HPP diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index 97ee2ce19..cdaadf3ca 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -102,6 +102,12 @@ class XiaListModeDataMask { ///@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; diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 53ce0a9e8..6e92448aa 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -13,19 +13,18 @@ using namespace std; enum HEADER_CODES { - STATS_BLOCK = 1, HEADER = 4, HEADER_W_TS = 6, HEADER_W_ESUMS = 8, - HEADER_W_QDC = 12, HEADER_W_TS_ESUM = 10, HEADER_W_ESUM_QDC = 14, - HEADER_W_TS_QDC_ESUM = 16 + 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 }; -vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { +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). Do these technically belong here? They - /// are not part of decoding the XIA data. In addition, we are passing in - /// the bufLen, but not using is in ReadSpill. - ///@TODO : Reevaluate where these two things go. + /// of the module (module number). unsigned int bufLen = *buf++; unsigned int modNum = *buf++; @@ -41,24 +40,30 @@ vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { stringstream msg; vector events; - XiaData *lastVirtualChannel = NULL; while (buf < bufStart + bufLen) { - XiaData currentEvt; + XiaData data; bool hasExternalTimestamp = false; bool hasQdc = false; bool hasEnergySums = false; - 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; + pair lengths = + DecodeWordZero(buf[0], data, mask); + unsigned int headerLength = lengths.first; + unsigned int eventLength = lengths.second; + + //This will handles the possibilty of up to 100 crates + data.SetModuleNumber(modNum += 100 * data.GetCrateNumber()); - currentEvt.virtualChannel = ((buf[0] & 0x20000000) != 0); - currentEvt.saturatedBit = ((buf[0] & 0x40000000) != 0); - currentEvt.pileupBit = ((buf[0] & 0x80000000) != 0); + 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 @@ -68,23 +73,27 @@ vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { continue; case HEADER : break; - case HEADER_W_TS : + case HEADER_W_ETS : hasExternalTimestamp = true; break; case HEADER_W_QDC : hasQdc = true; break; - case HEADER_W_ESUMS : + case HEADER_W_ESUM : hasEnergySums = true; break; - case HEADER_W_TS_ESUM : + case HEADER_W_ESUM_ETS : hasExternalTimestamp = hasEnergySums = true; break; case HEADER_W_ESUM_QDC : hasEnergySums = hasQdc = true; break; - case HEADER_W_TS_QDC_ESUM : + case HEADER_W_ESUM_QDC_ETS : hasEnergySums = hasExternalTimestamp = hasQdc = true; + break; + case HEADER_W_QDC_ETS : + hasQdc = hasExternalTimestamp = true; + break; default: msg << "XiaListModeDataDecoder::ReadBuffer : We encountered an " "unrecognized header length (" @@ -92,18 +101,14 @@ vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { << endl << "ReadBuffer: Unexpected header length: " << headerLength << endl << "ReadBuffer: Buffer " << modNum << " of length " << bufLen << endl - << "ReadBuffer: CHAN:SLOT:CRATE " << chanNum << ":" - << slotNum << ":" << crateNum << endl; + << "ReadBuffer: CHAN:SLOT:CRATE " + << data.GetChannelNumber() << ":" + << data.GetSlotNumber() << ":" + << data.GetCrateNumber() << endl; throw length_error(msg.str()); } - 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(hasExternalTimestamp) { + if (hasExternalTimestamp) { //Do nothing for now } @@ -113,36 +118,26 @@ vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { } if (hasQdc) { - int offset = headerLength - 8; - for (int i = 0; i < currentEvt.numQdcs; i++) { - currentEvt.qdcValue[i] = buf[offset + i]; + 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); } - currentEvt.chanNum = chanNum; - currentEvt.modNum = modNum += 100 * crateNum; - currentEvt.slotNum = slotNum; - - /*if(currentEvt.virtualChannel){ - DetectorLibrary* modChan = DetectorLibrary::get(); - - currentEvt.modNum += modChan->GetPhysicalModules(); - if(modChan->at(modNum, chanNum).HasTag("construct_trace")){ - lastVirtualChannel = currentEvt; - } - }*/ - ///@TODO Figure out where to put this... //channel_counts[modNum][chanNum]++; - currentEvt.energy = energy; - if (currentEvt.saturatedBit) { currentEvt.energy = 16383; } + ///@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); - currentEvt.trigTime = lowTime; - currentEvt.cfdTime = cfdTime; - currentEvt.eventTimeHi = highTime; - currentEvt.eventTimeLo = lowTime; - currentEvt.time = highTime * pow(2., 32.) + lowTime; + //We set the time according to the revision and firmware. + data.SetTime(CalculateTimeInSamples(mask, data)); // One last check if (traceLength / 2 + headerLength != eventLength) { @@ -151,30 +146,101 @@ vector XiaListModeDataDecoder::DecodeBuffer(unsigned int *buf) { << headerLength << ") and length of trace (" << traceLength << ")"; throw length_error(msg.str()); - } + } else //Advance the buffer past the header and to the trace + buf += headerLength; - buf += headerLength; if (traceLength > 0) { - // sbuf points to the beginning of trace data - unsigned short *sbuf = (unsigned short *) buf; + 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); + + 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); + data.SetSaturation((bool) (word & mask.GetTraceOutOfRangeFlagMask().first)); + + 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(); + } - currentEvt.reserve(traceLength); + if (mask.GetFrequency() == 500) { + multiplier = 10; + cfdTime = data.GetCfdFractionalTime() / mask.GetCfdSize() + + data.GetCfdTriggerSourceBit() - 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]); + return filterTime * multiplier + cfdTime; +} - if (lastVirtualChannel != NULL) { - lastVirtualChannel->adcTrace[k] += sbuf[k]; - } - } - buf += traceLength / 2; - } // if(traceLength > 0) - events.push_back(currentEvt); - } - return events; +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/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 1564bb7f0..853dfcfe2 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -242,4 +242,45 @@ string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) const { << "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 + ("GetCfdFractionalTimeMask")); + if(frequency_ == 500) + return 8192.; + + double val = 0; + if (frequency_ == 100) { + switch (firmware_) { + case R29432: + val = 65536; + break; + case R30474: + case R30980: + case R30981: + case R34688: + val = 32768; + break; + case UNKNOWN: + break; + } + } else if (frequency_ == 250) { + switch (firmware_) { + case R29432: + val = 32768; + break; + case R30980: + case R30981: + case R34688: + case R30474: + val = 16384; + break; + case UNKNOWN: + break; + } + } + + return val; } \ No newline at end of file diff --git a/Scan/ScanLib/tests/CMakeLists.txt b/Scan/ScanLib/tests/CMakeLists.txt index d72b706f9..f4ac7581a 100644 --- a/Scan/ScanLib/tests/CMakeLists.txt +++ b/Scan/ScanLib/tests/CMakeLists.txt @@ -1,7 +1,8 @@ add_executable(unittest-XiaListModeDataDecoder unittest-XiaListModeDataDecoder.cpp ../source/XiaData.cpp - ../source/XiaListModeDataDecoder.cpp) + ../source/XiaListModeDataDecoder.cpp + ../source/XiaListModeDataMask.cpp) target_link_libraries(unittest-XiaListModeDataDecoder UnitTest++ ${LIBS}) install(TARGETS unittest-XiaListModeDataDecoder DESTINATION bin/unittests) diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index fee590e43..dc9f003de 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -9,9 +9,13 @@ using namespace std; +///@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); + ///We have added in the first to elements for the pixie module data header. /// It contains the information about how many words are in the buffer and -/// the module VSN (number). +/// the module VSN (number). This header is for firmware R30474 ///This 4 word header has the following characteristics: /// 1. Word 0 /// * Channel Number [3:0] : 13 @@ -53,15 +57,20 @@ unsigned int header_N_qdc[14] = { 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}; + //Here is all of the expected data for the above header. static const unsigned int expected_chan = 13; static const unsigned int expected_size = 1; static const unsigned int expected_ts_high = 26001; static const unsigned int expected_ts_low = 123456789; +static const unsigned int expected_cfd_fractional_time = 1234; static const unsigned int expected_slot = 2; static const unsigned int expected_energy = 2345; static const double expected_ts = 111673568120085; -static const vector expected_trace = { +static const double expected_ts_w_cfd = 223347136240170.075317; +static const vector expected_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, @@ -75,54 +84,63 @@ static const vector expected_trace = { static const vector expected_qdc = {123, 456, 789, 987, 654, 321, 135, 791}; +//Test the error handling in the class TEST_FIXTURE(XiaListModeDataDecoder, TestBufferLengthChecks) { //Check for a length_error when the buffer length is zero unsigned int buffer_len_zero[6] = {0, 0}; - CHECK_THROW(DecodeBuffer(&buffer_len_zero[0]), length_error); + CHECK_THROW(DecodeBuffer(&buffer_len_zero[0], mask), length_error); //Check for an empty vector when the buffer length is 2 (empty module) unsigned int buffer_len_two[6] = {2, 0}; unsigned int expected_size = 0; - CHECK_EQUAL(expected_size, DecodeBuffer(&buffer_len_two[0]).size()); + CHECK_EQUAL(expected_size, DecodeBuffer(&buffer_len_two[0], mask).size()); } -///Test fixture testing if we can decode a simple 4 word -/// header that includes the Pixie Module Data Header. +///Test if we can decode a simple 4 word header that includes the Pixie +/// Module Data Header. TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { //Check for length_error when the header has an impossible size. ///A header with a header length 20 instead of the true header length 4 unsigned int header_w_bad_len[6] = {4, 0, 3887149, 123456789, 26001, 2345}; - CHECK_THROW(DecodeBuffer(&header_w_bad_len[0]), length_error); + CHECK_THROW(DecodeBuffer(&header_w_bad_len[0], mask), length_error); //Check that we can decode a simple 4-word header. - vector result = DecodeBuffer(&header[0]); + vector result = DecodeBuffer(&header[0], mask); XiaData result_data = result.front(); CHECK_EQUAL(expected_size, result.size()); - CHECK_EQUAL(expected_slot, result_data.slotNum); - CHECK_EQUAL(expected_chan, result_data.chanNum); - CHECK_EQUAL(expected_energy, result_data.energy); - CHECK_EQUAL(expected_ts_high, result_data.eventTimeHi); - CHECK_EQUAL(expected_ts_low, result_data.eventTimeLo); - CHECK_EQUAL(expected_ts, result_data.time); - CHECK_EQUAL(expected_ts_low, result_data.trigTime); + CHECK_EQUAL(expected_slot, result_data.GetSlotNumber()); + CHECK_EQUAL(expected_chan, result_data.GetChannelNumber()); + CHECK_EQUAL(expected_energy, result_data.GetEnergy()); + CHECK_EQUAL(expected_ts_high, result_data.GetEventTimeHigh()); + CHECK_EQUAL(expected_ts_low, result_data.GetEventTimeLow()); + CHECK_EQUAL(expected_ts, result_data.GetTime()); } -//Test fixture testing if we can decode a trace properly +//Test if we can decode a trace properly TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { unsigned int badlen[6] = { 59, 0, 7749677, 123456789, 26001, 8128809}; //Check that we throw length_error when the event length doesn't match. - CHECK_THROW(DecodeBuffer(&badlen[0]), length_error); + CHECK_THROW(DecodeBuffer(&badlen[0], mask), length_error); - XiaData result = DecodeBuffer(&header_N_trace[0]).front(); - CHECK_ARRAY_EQUAL(expected_trace, result.adcTrace, expected_trace.size()); + XiaData result = DecodeBuffer(&header_N_trace[0], mask).front(); + CHECK_ARRAY_EQUAL(expected_trace, result.GetTrace(), expected_trace.size()); } -//Test fixture testing if we can decode the qdc properly +//Test if we can decode the qdc properly TEST_FIXTURE(XiaListModeDataDecoder, TestQdcDecoding) { - XiaData result = DecodeBuffer(&header_N_qdc[0]).front(); - CHECK_ARRAY_EQUAL(expected_qdc, result.qdcValue, expected_qdc.size()); + XiaData result = DecodeBuffer(&header_N_qdc[0], mask).front(); + CHECK_ARRAY_EQUAL(expected_qdc, result.GetQdc(), expected_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(expected_cfd_fractional_time, result.GetCfdFractionalTime()); + CHECK_CLOSE(expected_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/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index e912195aa..b673f4c70 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -158,6 +158,40 @@ TEST_FIXTURE(XiaListModeDataMask, Test_R34688_Word3) { } } +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 From 0300d799b9401dad5fcfa1681c82a3ac588a81af Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 2 Jan 2017 11:52:25 -0500 Subject: [PATCH 080/255] Updating decoder to return a vector of pointers to the newed data This reimplements the old behavior that the Unpacker::ReadBuffer method had. The hope is that this will now minimize the number of changes necessary to the Unpacker class. Former-commit-id: 231ecfe6b60236704ed207beb468779081ee2423 --- .../include/XiaListModeDataDecoder.hpp | 4 +-- .../ScanLib/source/XiaListModeDataDecoder.cpp | 34 +++++++++---------- .../tests/unittest-XiaListModeDataDecoder.cpp | 11 +++--- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp index ae684e3d1..31be9f2f2 100644 --- a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp +++ b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp @@ -24,8 +24,8 @@ class XiaListModeDataDecoder { ///@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); + std::vector DecodeBuffer(unsigned int *buf, + const XiaListModeDataMask &mask); private: ///Method to decode word zero from the header. diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 6e92448aa..161890d21 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -18,7 +18,7 @@ enum HEADER_CODES { HEADER_W_ESUM_QDC = 16, HEADER_W_ESUM_QDC_ETS = 18 }; -vector XiaListModeDataDecoder::DecodeBuffer( +vector XiaListModeDataDecoder::DecodeBuffer( unsigned int *buf, const XiaListModeDataMask &mask) { unsigned int *bufStart = buf; @@ -36,28 +36,28 @@ vector XiaListModeDataDecoder::DecodeBuffer( //For empty buffers we just return an empty vector. static const unsigned int emptyBufferLength = 2; if (bufLen == emptyBufferLength) - return vector(); + return vector(); stringstream msg; - vector events; + vector events; while (buf < bufStart + bufLen) { - XiaData data; + XiaData* data = new XiaData(); bool hasExternalTimestamp = false; bool hasQdc = false; bool hasEnergySums = false; pair lengths = - DecodeWordZero(buf[0], data, mask); + DecodeWordZero(buf[0], *data, mask); unsigned int headerLength = lengths.first; unsigned int eventLength = lengths.second; //This will handles the possibilty of up to 100 crates - data.SetModuleNumber(modNum += 100 * data.GetCrateNumber()); + data->SetModuleNumber(modNum += 100 * data->GetCrateNumber()); - data.SetEventTimeLow(buf[1]); - DecodeWordTwo(buf[2], data, mask); - unsigned int traceLength = DecodeWordThree(buf[3], data, mask); + 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 @@ -102,9 +102,9 @@ vector XiaListModeDataDecoder::DecodeBuffer( << headerLength << endl << "ReadBuffer: Buffer " << modNum << " of length " << bufLen << endl << "ReadBuffer: CHAN:SLOT:CRATE " - << data.GetChannelNumber() << ":" - << data.GetSlotNumber() << ":" - << data.GetCrateNumber() << endl; + << data->GetChannelNumber() << ":" + << data->GetSlotNumber() << ":" + << data->GetCrateNumber() << endl; throw length_error(msg.str()); } @@ -124,7 +124,7 @@ vector XiaListModeDataDecoder::DecodeBuffer( for (unsigned int i = 0; i < numQdcs; i++) { tmp.push_back(buf[offset + i]); } - data.SetQdc(tmp); + data->SetQdc(tmp); } ///@TODO Figure out where to put this... @@ -133,11 +133,11 @@ vector XiaListModeDataDecoder::DecodeBuffer( ///@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); + if (data->IsSaturated()) + data->SetEnergy(65536); //We set the time according to the revision and firmware. - data.SetTime(CalculateTimeInSamples(mask, data)); + data->SetTime(CalculateTimeInSamples(mask, *data)); // One last check if (traceLength / 2 + headerLength != eventLength) { @@ -150,7 +150,7 @@ vector XiaListModeDataDecoder::DecodeBuffer( buf += headerLength; if (traceLength > 0) { - DecodeTrace(buf, data, traceLength); + DecodeTrace(buf, *data, traceLength); buf += traceLength / 2; } events.push_back(data); diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index dc9f003de..d12533e4d 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -103,8 +103,8 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { CHECK_THROW(DecodeBuffer(&header_w_bad_len[0], mask), length_error); //Check that we can decode a simple 4-word header. - vector result = DecodeBuffer(&header[0], mask); - XiaData result_data = result.front(); + vector result = DecodeBuffer(&header[0], mask); + XiaData result_data = *result.front(); CHECK_EQUAL(expected_size, result.size()); CHECK_EQUAL(expected_slot, result_data.GetSlotNumber()); @@ -122,20 +122,19 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { //Check that we throw length_error when the event length doesn't match. CHECK_THROW(DecodeBuffer(&badlen[0], mask), length_error); - XiaData result = DecodeBuffer(&header_N_trace[0], mask).front(); + XiaData result = *DecodeBuffer(&header_N_trace[0], mask).front(); CHECK_ARRAY_EQUAL(expected_trace, result.GetTrace(), expected_trace.size()); } //Test if we can decode the qdc properly TEST_FIXTURE(XiaListModeDataDecoder, TestQdcDecoding) { - XiaData result = DecodeBuffer(&header_N_qdc[0], mask).front(); + XiaData result = *DecodeBuffer(&header_N_qdc[0], mask).front(); CHECK_ARRAY_EQUAL(expected_qdc, result.GetQdc(), expected_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(); - + XiaData result = *DecodeBuffer(&header_N_Cfd[0], mask).front(); CHECK_EQUAL(expected_cfd_fractional_time, result.GetCfdFractionalTime()); CHECK_CLOSE(expected_ts_w_cfd, result.GetTime(), 1e-5); } From 9ad218b9b81d45ea757385bd6c7253783b24740a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 2 Jan 2017 12:09:40 -0500 Subject: [PATCH 081/255] Data can be scanned properly with utkscan. Updated files for changes The new unpacking routine accurately reproduces results from data sets using utkscan. Various classes were updated to take into account changes in the Unpacker and XiaData classes. Former-commit-id: 0658cb6dee39da1b1d1c00a4a45b3d4a0dc85849 --- Scan/ScanLib/include/Unpacker.hpp | 16 +- Scan/ScanLib/source/CMakeLists.txt | 3 +- Scan/ScanLib/source/ChannelData.cpp | 4 +- Scan/ScanLib/source/ChannelEvent.cpp | 12 +- Scan/ScanLib/source/ScanInterface.cpp | 52 ++-- Scan/ScanLib/source/Unpacker.cpp | 272 +++++------------- Scan/utkscan/core/include/ChanEvent.hpp | 26 +- Scan/utkscan/core/source/ChanEvent.cpp | 12 +- Scan/utkscan/core/source/UtkUnpacker.cpp | 12 +- .../source/TwoChanTimingProcessor.cpp | 2 +- .../processors/source/PspmtProcessor.cpp | 4 +- 11 files changed, 152 insertions(+), 263 deletions(-) diff --git a/Scan/ScanLib/include/Unpacker.hpp b/Scan/ScanLib/include/Unpacker.hpp index 0714809e0..82103ea6d 100644 --- a/Scan/ScanLib/include/Unpacker.hpp +++ b/Scan/ScanLib/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/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt index a35620b73..fd5b29515 100644 --- a/Scan/ScanLib/source/CMakeLists.txt +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -1,6 +1,7 @@ #Set the scan sources that we will make a lib out of set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp - ChannelEvent.cpp) + ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp + XiaListModeDataEncoder.cpp) #Add the sources to the library add_library(ScanObjects OBJECT ${ScanSources}) diff --git a/Scan/ScanLib/source/ChannelData.cpp b/Scan/ScanLib/source/ChannelData.cpp index 0158cd70b..1b94125c1 100644 --- a/Scan/ScanLib/source/ChannelData.cpp +++ b/Scan/ScanLib/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/Scan/ScanLib/source/ChannelEvent.cpp b/Scan/ScanLib/source/ChannelEvent.cpp index 06d1c3fc8..e4bbb25ca 100644 --- a/Scan/ScanLib/source/ChannelEvent.cpp +++ b/Scan/ScanLib/source/ChannelEvent.cpp @@ -23,7 +23,7 @@ ChannelEvent::ChannelEvent(XiaData *event_){ cfdvals = NULL; Clear(); event = event_; - size = event->adcTrace.size(); + size = event->GetTrace().size(); if(size != 0){ xvals = new float[size]; yvals = new float[size]; @@ -44,22 +44,22 @@ float ChannelEvent::CorrectBaseline(){ 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 += (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->adcTrace[i] - baseline)*((float)event->adcTrace[i] - baseline); + 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->adcTrace.size(); i++){ + for(size_t i = 0; i < event->GetTrace().size(); i++){ xvals[i] = i; - yvals[i] = event->adcTrace[i]-baseline; + yvals[i] = event->GetTrace()[i]-baseline; if(yvals[i] > maximum){ maximum = yvals[i]; max_index = i; @@ -175,7 +175,7 @@ void ChannelEvent::Clear(){ if(xvals){ delete[] xvals; } if(yvals){ delete[] yvals; } if(cfdvals){ delete[] cfdvals; } - if(event){ event->clear(); } + if(event){ event->Clear(); } event = NULL; xvals = NULL; diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp index 94bd47e7b..1b591f0d9 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -396,22 +396,25 @@ 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"), + 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 +464,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 +835,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 +877,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) atoi(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 +903,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 +950,12 @@ 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. + std::cout << firmware << " " << samplingFrequency << std::endl; + core->InitializeDataMask(firmware, samplingFrequency); + if(debug_mode) core->SetDebugMode(); diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Scan/ScanLib/source/Unpacker.cpp index a348d531e..ac9464231 100644 --- a/Scan/ScanLib/source/Unpacker.cpp +++ b/Scan/ScanLib/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 #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,166 +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... - // buf points to the start of channel data - ///@TODO we need to update this so that we are decoding the data - /// properly - 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; - ///@TODO Update this so that it takes into account both 12 and 14 - /// bit modules. - 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. @@ -390,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 @@ -427,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; @@ -446,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 @@ -454,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; @@ -482,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; @@ -494,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; } @@ -514,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 @@ -544,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; } @@ -570,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/Scan/utkscan/core/include/ChanEvent.hpp b/Scan/utkscan/core/include/ChanEvent.hpp index 55a9c0cda..f4909bfa2 100644 --- a/Scan/utkscan/core/include/ChanEvent.hpp +++ b/Scan/utkscan/core/include/ChanEvent.hpp @@ -26,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 @@ -56,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 */ @@ -73,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 */ @@ -82,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 */ @@ -91,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 */ @@ -109,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/source/ChanEvent.cpp b/Scan/utkscan/core/source/ChanEvent.cpp index 6aa85f1e7..0850322c0 100644 --- a/Scan/utkscan/core/source/ChanEvent.cpp +++ b/Scan/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/UtkUnpacker.cpp b/Scan/utkscan/core/source/UtkUnpacker.cpp index 1e5919380..bd57fbcc6 100644 --- a/Scan/utkscan/core/source/UtkUnpacker.cpp +++ b/Scan/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,14 +99,14 @@ 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. @@ -134,13 +134,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/experiment/source/TwoChanTimingProcessor.cpp b/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp index a4de54715..2515bfb3f 100644 --- a/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp +++ b/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp @@ -98,7 +98,7 @@ bool TwoChanTimingProcessor::Process(RawEvent &event) { static int trcCounter = 0; int bin; for(vector::const_iterator it = start.GetTrace()->begin(); - it != start.GetTrace()->end(); it++) { + 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/Scan/utkscan/processors/source/PspmtProcessor.cpp b/Scan/utkscan/processors/source/PspmtProcessor.cpp index 1b272f235..908845904 100644 --- a/Scan/utkscan/processors/source/PspmtProcessor.cpp +++ b/Scan/utkscan/processors/source/PspmtProcessor.cpp @@ -302,8 +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 From 4677b8e04e1922bb1ce87331d96a0cb7c82bfb68 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 2 Jan 2017 13:09:34 -0500 Subject: [PATCH 082/255] Updating scope to handle new access to traces. Former-commit-id: 7595e17f1b1db428b3ed85d459defd441c77653a --- Scan/ScanLib/source/CMakeLists.txt | 2 +- Scan/util/source/scope.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt index fd5b29515..b015abde2 100644 --- a/Scan/ScanLib/source/CMakeLists.txt +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -1,7 +1,7 @@ #Set the scan sources that we will make a lib out of set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp - XiaListModeDataEncoder.cpp) + XiaListModeDataEncoder.cpp RootScanner.cpp) #Add the sources to the library add_library(ScanObjects OBJECT ${ScanSources}) diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index 6f0583d2a..b391f5d6b 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -91,14 +91,14 @@ void scopeUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ 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_){ + int maximum = *std::max_element(current_event->GetTrace().begin(), current_event->GetTrace().end()); + if(current_event->GetModuleNumber() == mod_ && current_event->GetChannelNumber() == chan_){ //Check threhsold. if (maximum < threshLow_) { delete current_event; @@ -224,7 +224,7 @@ void scopeScanner::Plot(){ 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++; } @@ -278,8 +278,8 @@ 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 < histAxis[1][0]) histAxis[1][0] = evtMin; @@ -296,7 +296,7 @@ void scopeScanner::Plot(){ 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]); } } From 749abd2937114643217ec3e651d72f2f45ba3f38 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 4 Jan 2017 17:13:25 -0500 Subject: [PATCH 083/255] Rearranging location of Unit Test Test data to make it more useful The GslFitter is now Unit Tested. --- Scan/Resources/include/HelperEnumerations.hpp | 42 ++- .../include/UnitTestExampleTrace.hpp | 114 ------- Scan/Resources/include/UnitTestSampleData.hpp | 280 ++++++++++++++++++ Scan/Resources/tests/CMakeLists.txt | 24 +- Scan/Resources/tests/test_gslfitter.cpp | 42 --- Scan/Resources/tests/unittest-GslFitter.cpp | 30 ++ .../tests/unittest-HelperFunctions.cpp | 122 ++++---- .../tests/unittest-PolynomialCfd.cpp | 39 ++- Scan/Resources/tests/unittest-RootFitter.cpp | 10 +- .../tests/unittest-TraditionalCfd.cpp | 42 ++- Scan/ScanLib/include/XiaData.hpp | 26 +- .../include/XiaListModeDataDecoder.hpp | 35 +-- .../include/XiaListModeDataEncoder.hpp | 2 +- Scan/ScanLib/include/XiaListModeDataMask.hpp | 26 +- Scan/ScanLib/source/XiaData.cpp | 17 +- .../ScanLib/source/XiaListModeDataDecoder.cpp | 11 +- .../ScanLib/source/XiaListModeDataEncoder.cpp | 2 + Scan/ScanLib/source/XiaListModeDataMask.cpp | 1 + Scan/ScanLib/tests/unittest-XiaData.cpp | 36 +-- .../tests/unittest-XiaListModeDataDecoder.cpp | 119 ++------ .../tests/unittest-XiaListModeDataEncoder.cpp | 89 ++---- .../tests/unittest-XiaListModeDataMask.cpp | 2 + 22 files changed, 551 insertions(+), 560 deletions(-) delete mode 100644 Scan/Resources/include/UnitTestExampleTrace.hpp create mode 100644 Scan/Resources/include/UnitTestSampleData.hpp delete mode 100644 Scan/Resources/tests/test_gslfitter.cpp create mode 100644 Scan/Resources/tests/unittest-GslFitter.cpp diff --git a/Scan/Resources/include/HelperEnumerations.hpp b/Scan/Resources/include/HelperEnumerations.hpp index 02a5af74f..855675188 100644 --- a/Scan/Resources/include/HelperEnumerations.hpp +++ b/Scan/Resources/include/HelperEnumerations.hpp @@ -1,18 +1,48 @@ -// -// Created by vincent on 12/6/16. -// - +///@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}; + enum CFD_TYPE { + POLY, XIA, BASIC + }; /// An enum listing the known Fitter types - enum FITTER_TYPE{GSL, UNKNOWN}; + enum FITTER_TYPE { + GSL, UNKNOWN + }; } +namespace DataProcessing { + ///An enum for the different firmware revisions for the Pixie-16 modules. + /// * R29432 is valid from 02/15/2014 and 07/28/2014 + /// * R30474, R30980, R30981 is valid from 07/28/2014 and 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 { + 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/Scan/Resources/include/UnitTestExampleTrace.hpp b/Scan/Resources/include/UnitTestExampleTrace.hpp deleted file mode 100644 index b9e6c9bee..000000000 --- a/Scan/Resources/include/UnitTestExampleTrace.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// -// Created by vincent on 12/18/16. -// - -#ifndef PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP -#define PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP - -#include -#include -#include - -namespace unittest_trace_variables { - //This is a trace taken from a medium VANDLE module. - static const std::vector data = { - 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 waveform(data.begin() + 71, - data.begin() + 86); - - //An empty data vector to test error checking. - static const std::vector empty_data; - //A data vector that contains constant data. - static const std::vector const_data = {1000, 4}; - - //-------------------------------------------------------------------------- - // Variables related to Testing the integral - //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 expected_integral = 12.5; - - //-------------------------------------------------------------------------- - // Variables related to Polynomial::CalculatePoly3 - - //The expected maximum from the poly3 fitting - static const double expected_poly3_val = 3818.0718412264; - - //A data vector that contains only the four points for the Poly3 Fitting. - static const std::vector poly3_data(data.begin() + 74, - data.begin() + 78); - //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 expected_poly3_coeffs = - {2358.0, 1635.66666666667, -516.0, 31.3333333333333}; - - //-------------------------------------------------------------------------- - // Variables related to Polynomial::CalculatePoly2 - //The expected maximum from the pol2 fitting - static const double expected_poly2_val = 10737.0720588236; - - //A data vector containing only the three points for the Poly2 fitting - static const std::vector poly2_data(data.begin() + 73, - data.begin() + 76); - //Vector containing the expected coefficients from the poly 2 fit - static const std::vector expected_poly2_coeffs = - {1122.0, 1278.5, -42.4999999999999}; - - //-------------------------------------------------------------------------- - // Variables related to calculation of the maximum of a trace - /// This is the expected value of the maximum - static const double expected_maximum_value = 3816; - /// This is the expected position of the maximum - static const unsigned int expected_max_position = 76; - /// This is the pair made from the expected maximum information - static const std::pair expected_max_info( - expected_max_position, - expected_maximum_value); - - //-------------------------------------------------------------------------- - // Variables related to the calculation of the extrapolated maximum - static const std::vector expected_coeffs = - {-15641316.0007084, 592747.666694852, -7472.00000037373, - 31.3333333349849}; - - //-------------------------------------------------------------------------- - // Variables related to calculation of the baseline of the trace - - //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 expected_baseline = 436.7428571; - //The expected standard deviation was obtained using the STDEVP function in - // Google Sheets. - static const double expected_standard_deviation = 1.976184739; - //Pair of these results to test with and use in other places - static const std::pair expected_baseline_pair - (expected_baseline, expected_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 expected_ratio = 0.2960894762; - - //-------------------------------------------------------------------------- - //Variables related to fitting the above trace - //Set the for the fitting from the results of a gnuplot script - std::pair expected_trace_pars(0.2659404170, - 0.208054799179688); - -} - -#endif //PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP diff --git a/Scan/Resources/include/UnitTestSampleData.hpp b/Scan/Resources/include/UnitTestSampleData.hpp new file mode 100644 index 000000000..fa30650a5 --- /dev/null +++ b/Scan/Resources/include/UnitTestSampleData.hpp @@ -0,0 +1,280 @@ +///@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 crate = 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 = 123456789; + + 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.begin() + 71, + trace.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 = 72; + static const double leading_edge_fraction = 0.5; + static const double bad_fraction = -0.5; +} + +#endif //PIXIESUITE_UNITTESTEXAMPLETRACE_HPP_HPP diff --git a/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index fe35e6f57..0ad816522 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -1,17 +1,17 @@ -if(USE_GSL AND BUILD_TESTS) - 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) +if(BUILD_UNITTESTS) + 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 AND BUILD_TESTS) + #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++) + endif(USE_GSL) -if(BUILD_UNITTESTS) add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) target_link_libraries(unittest-HelperFunctions UnitTest++) install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) diff --git a/Scan/Resources/tests/test_gslfitter.cpp b/Scan/Resources/tests/test_gslfitter.cpp deleted file mode 100644 index d70ab4f49..000000000 --- a/Scan/Resources/tests/test_gslfitter.cpp +++ /dev/null @@ -1,42 +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" -#include "UnitTestExampleTrace.hpp" - -using namespace std; -using namespace unittest_trace_variables; - -int main(int argc, char *argv[]) { - cout << "Testing functionality of FitDriver and GslFitter" << endl; - - //Qdc of the trace is necessary to initialization of the fit - double area = 21329.85714285; - - //Instance the fitter and pass in the flag for the SiPm - GslFitter fitter; - - fitter.SetBaseline(expected_baseline_pair); - fitter.SetQdc(area); - - double phase; - //Actually perform the fitting - ///@TODO : We should never catch ALL throws using this syntax. It's bad - /// practice. Until we can figure out what to throw here then we'll leave - /// it. - try { - phase = fitter.CalculatePhase(waveform, expected_trace_pars); - } catch(...) { - cerr << "Something went wrong with the fit" << endl; - } - - //Output the fit results and compare to what we get with gnuplot - cout << "Chi^2 = " << fitter.GetChiSq() << endl - << "Amplitude from Gnuplot = 0.8565802" << endl - << "Amplitude = " << fitter.GetAmplitude() << endl - << "Phase from Gnuplot = -0.0826487" << endl - << "Phase = " << phase << endl; -} \ No newline at end of file diff --git a/Scan/Resources/tests/unittest-GslFitter.cpp b/Scan/Resources/tests/unittest-GslFitter.cpp new file mode 100644 index 000000000..532c5eebb --- /dev/null +++ b/Scan/Resources/tests/unittest-GslFitter.cpp @@ -0,0 +1,30 @@ +///\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 "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/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index d5c0031bf..0613a3d50 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -1,181 +1,183 @@ ///@file unittest-HelperFunctions.cpp ///@author S. V. Paulauskas ///@date December 12, 2016 +#include + #include #include "HelperFunctions.hpp" -#include "UnitTestExampleTrace.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(data, make_pair(0, 1)), + 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_data, make_pair(0, 16)), + 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(data, make_pair(17, 1)), + 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(data, make_pair(0, 1000)), + 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(data, make_pair(0, 70)); - CHECK_CLOSE(expected_baseline, result.first, 1e-7); - CHECK_CLOSE(expected_standard_deviation, result.second, 1e-9); + 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_data, trace_delay), + 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(data, 1000), range_error); + 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(data, 10), range_error); + CHECK_THROW(TraceFunctions::FindMaximum(trace, 10), 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_data, trace_delay), + CHECK_THROW(TraceFunctions::FindMaximum(const_vector_uint, trace_delay), range_error); pair result = - TraceFunctions::FindMaximum(data, trace_delay); - CHECK_EQUAL(expected_max_position, result.first); - CHECK_EQUAL(expected_maximum_value, result.second); + TraceFunctions::FindMaximum(trace, trace_delay); + CHECK_EQUAL(max_position, result.first); + CHECK_EQUAL(maximum_value, result.second); } TEST(TestFindLeadingEdge) { - //This is the expected position of the leading edge of signal. - static const unsigned int expected_leading_edge_position = 72; - //Check that if we define a threshold that is 0 or less we throw a range // error - CHECK_THROW(TraceFunctions::FindLeadingEdge(data, -2, expected_max_info), + 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_data, 0.5, - expected_max_info), - range_error); + 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(const_data, 0.5, - make_pair(2000, 3)), + 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(expected_leading_edge_position, - TraceFunctions::FindLeadingEdge(data, 0.131, - expected_max_info)); + 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_data, 0), range_error); + 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(expected_poly3_coeffs, result.second, - expected_poly3_coeffs.size(), 1e-6); + CHECK_ARRAY_CLOSE(poly3_coeffs, result.second, poly3_coeffs.size(), 1e-6); //Check that the calculated maximum value is accurate - CHECK_CLOSE(expected_poly3_val, result.first, 1e-6); + 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_data, - expected_max_info), - range_error); + CHECK_THROW(TraceFunctions::ExtrapolateMaximum(empty_vector_uint, + max_pair), range_error); pair > result = - TraceFunctions::ExtrapolateMaximum(data, expected_max_info); + TraceFunctions::ExtrapolateMaximum(trace, max_pair); //Check that the calculated maximum value is accurate - CHECK_CLOSE(expected_poly3_val, result.first, 1e-6); + CHECK_CLOSE(extrapolated_maximum, result.first, 1e-6); //Check that we are returning the correct coefficients for the data being // passed. - CHECK_ARRAY_CLOSE(expected_coeffs, result.second, - expected_coeffs.size(), 1e-3); + 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_data, 0), range_error); + 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(expected_poly2_coeffs, result.second, - expected_poly2_coeffs.size(), 1e-3); + CHECK_ARRAY_CLOSE(poly2_coeffs, result.second, + poly2_coeffs.size(), 1e-3); - CHECK_CLOSE(expected_poly2_val, result.first, 1e-4); + 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_data), range_error); - CHECK_EQUAL(expected_integral, - Statistics::CalculateIntegral(integration_data)); + CHECK_THROW(Statistics::CalculateIntegral(empty_vector_uint), range_error); + CHECK_EQUAL(integral, Statistics::CalculateIntegral(integration_data)); } TEST(TestCalculateQdc) { - static const double expected = 6; //Check that we are throwing an error when the data is empty - CHECK_THROW(TraceFunctions::CalculateQdc(empty_data, make_pair(0, 4)), + 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(data, make_pair(0, 1000)), + CHECK_THROW(TraceFunctions::CalculateQdc(trace, + make_pair(0, trace.size() + 10)), range_error); - CHECK_THROW(TraceFunctions::CalculateQdc(data, make_pair(1000, 0)), + //Check for range error when the range is inverted + CHECK_THROW(TraceFunctions::CalculateQdc(trace, make_pair(1000, 0)), range_error); - CHECK_EQUAL(expected, TraceFunctions::CalculateQdc - (integration_data, make_pair(2, 5))); + //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_data, make_pair(0, 4), - 100.0), range_error); + 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(data, - make_pair(0, 400), 100.0), + 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(data, make_pair(0, 4), + CHECK_THROW(TraceFunctions::CalculateTailRatio(trace, make_pair(0, 4), 0.0), range_error); - double qdc = TraceFunctions::CalculateQdc(data, make_pair(70, 91)); + double qdc = TraceFunctions::CalculateQdc(trace, make_pair(70, 91)); pair range(80, 91); - double result = TraceFunctions::CalculateTailRatio(data, range, qdc); - CHECK_CLOSE(expected_ratio, result, 1e-6); + double result = TraceFunctions::CalculateTailRatio(trace, range, qdc); + CHECK_CLOSE(tail_ratio, result, 1e-6); } int main(int argv, char *argc[]) { diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Scan/Resources/tests/unittest-PolynomialCfd.cpp index 138163e0c..ad895c8f2 100644 --- a/Scan/Resources/tests/unittest-PolynomialCfd.cpp +++ b/Scan/Resources/tests/unittest-PolynomialCfd.cpp @@ -8,33 +8,32 @@ #include #include "PolynomialCfd.hpp" -#include "UnitTestExampleTrace.hpp" +#include "UnitTestSampleData.hpp" using namespace std; using namespace unittest_trace_variables; +using namespace unittest_cfd_variables; -//This pair provides us with the expected extrapolated maximum and the -// position of the maximum. -static const pair max_info(expected_max_position, - expected_poly3_val); TEST_FIXTURE(PolynomialCfd, TestPolynomialCfd) { - static const pair pars(0.5, 2.); - //Checking that we throw a range_error when the data vector is zero - CHECK_THROW(CalculatePhase(empty_data, pars, max_info, - expected_baseline_pair), range_error); - - //Checking that we throw a range_error when the max index is too large - // for the data - static const pair tmp(1000, expected_poly3_val); - CHECK_THROW(CalculatePhase(data, pars, tmp, - expected_baseline_pair), range_error); - - double result = CalculatePhase(data, pars, max_info, - expected_baseline_pair); - CHECK(-9999 != result); - cout << "PolynomialCfd result is " << result << endl; + 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[]) { diff --git a/Scan/Resources/tests/unittest-RootFitter.cpp b/Scan/Resources/tests/unittest-RootFitter.cpp index a072e1c1c..a0763fb5b 100644 --- a/Scan/Resources/tests/unittest-RootFitter.cpp +++ b/Scan/Resources/tests/unittest-RootFitter.cpp @@ -5,10 +5,12 @@ //#include #include "RootFitter.hpp" -#include "UnitTestExampleTrace.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, @@ -23,9 +25,7 @@ using namespace unittest_trace_variables; int main(int argv, char *argc[]) { RootFitter fitter; - fitter.CalculatePhase(waveform, expected_trace_pars, expected_max_info, - expected_baseline_pair); - - + fitter.CalculatePhase(waveform, fitting_parameters, max_pair, + baseline_pair); //return (UnitTest::RunAllTests()); } \ No newline at end of file diff --git a/Scan/Resources/tests/unittest-TraditionalCfd.cpp b/Scan/Resources/tests/unittest-TraditionalCfd.cpp index 4f5b29053..aeef27a9d 100644 --- a/Scan/Resources/tests/unittest-TraditionalCfd.cpp +++ b/Scan/Resources/tests/unittest-TraditionalCfd.cpp @@ -2,39 +2,35 @@ ///@author S. V. Paulauskas ///@date December 12, 2016 #include -#include -#include #include #include "TraditionalCfd.hpp" -#include "UnitTestExampleTrace.hpp" +#include "UnitTestSampleData.hpp" using namespace std; using namespace unittest_trace_variables; - -//This pair provides us with the expected extrapolated maximum and the -// position of the maximum. -static const pair max_info(expected_max_position, - expected_poly3_val); +using namespace unittest_cfd_variables; TEST_FIXTURE(TraditionalCfd, TestTraditionalCfd) { - static const pair pars(0.5, 2.); - //Checking that we throw a range_error when the data vector is zero - CHECK_THROW(CalculatePhase(empty_data, pars, max_info, - expected_baseline_pair), range_error); - - //Checking that we throw a range_error when the max index is too large - // for the data - static const pair tmp(1000, expected_poly3_val); - CHECK_THROW(CalculatePhase(data, pars, tmp, - expected_baseline_pair), range_error); - - double result = CalculatePhase(data, pars, max_info, - expected_baseline_pair); - CHECK(-9999 != result); - cout << "TraditionalCfd result is " << result << endl; + 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[]) { diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index 8890b40ff..2f43f4ae4 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -133,13 +133,17 @@ class XiaData { 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 + moduleNum_ * 16 + chanNum_; + return crateNum_ * 208 + GetModuleNumber() * 16 + chanNum_; } - ///@brief This method returns the module number. - ///@return The module number - unsigned int GetModuleNumber() const { return moduleNum_; } + ///@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_; } @@ -202,10 +206,6 @@ class XiaData { ///@param[in] a : The value to set void SetExternalTimeLow(const unsigned int &a) { externalTimeLow_ = a; } - ///@brief Sets the module number - ///@param[in] a : The value to set - void SetModuleNumber(const unsigned int &a) { moduleNum_ = 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; } @@ -234,15 +234,6 @@ class XiaData { ///@param[in] a : True if we this channel was generated on-board void SetVirtualChannel(const bool &a) { isVirtualChannel_ = a; } - /// 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 unsigned int &input); - - /// Push back the trace vector with a value. - //void push_back(const unsigned int &input); - ///@brief Clear all variables and set them to some default values. void Clear(); @@ -264,7 +255,6 @@ class XiaData { 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 moduleNum_; ///Module number set from the data stream unsigned int slotNum_; ///Slot number std::vector eSums_;///Energy sums recorded by the module diff --git a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp index 31be9f2f2..29fb8b8d9 100644 --- a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp +++ b/Scan/ScanLib/include/XiaListModeDataDecoder.hpp @@ -27,6 +27,21 @@ class XiaListModeDataDecoder { 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 @@ -57,26 +72,6 @@ class XiaListModeDataDecoder { ///@param[in] data : The XiaData object that we are going to fill. void DecodeTrace(unsigned int *buf, XiaData &data, const unsigned int &traceLength); - - ///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 - ///@TODO This method needs to be moved to Resources so that it - /// can be taken advantage of by other classes. - 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 - ///@TODO This method needs to be moved to Resources so that it - /// can be taken advantage of by other classes. - double CalculateTimeInNs(const XiaListModeDataMask &mask, - const XiaData &data); }; #endif //PIXIESUITE_XIALISTMODEDATADECODER_HPP diff --git a/Scan/ScanLib/include/XiaListModeDataEncoder.hpp b/Scan/ScanLib/include/XiaListModeDataEncoder.hpp index 89fb97964..d1d82359a 100644 --- a/Scan/ScanLib/include/XiaListModeDataEncoder.hpp +++ b/Scan/ScanLib/include/XiaListModeDataEncoder.hpp @@ -27,7 +27,7 @@ class XiaListModeDataEncoder { ///@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 FIRMWARE &firmware, + const DataProcessing::FIRMWARE &firmware, const unsigned int &frequency); private: diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index cdaadf3ca..4e58bd512 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -8,18 +8,7 @@ #include #include -///An enum for the different firmware revisions for the Pixie-16 modules. -/// * R29432 is valid from 02/15/2014 and 07/28/2014 -/// * R30474, R30980, R30981 is valid from 07/28/2014 and 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 { - R29432, R30474, R30980, R30981, R34688, UNKNOWN -}; +#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 @@ -33,14 +22,15 @@ class XiaListModeDataMask { ///Default constructor XiaListModeDataMask() { frequency_ = 0; - firmware_ = UNKNOWN; + firmware_ = DataProcessing::UNKNOWN; } ///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 FIRMWARE &firmware, const unsigned int &freq) { + XiaListModeDataMask(const DataProcessing::FIRMWARE &firmware, + const unsigned int &freq) { firmware_ = firmware; frequency_ = freq; } @@ -129,7 +119,7 @@ class XiaListModeDataMask { ///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. - FIRMWARE GetFirmware() const { return firmware_; } + 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 @@ -137,7 +127,7 @@ class XiaListModeDataMask { ///Sets the firmware version ///@param[in] firmware : The firmware type that we would like to set. - void SetFirmware(const FIRMWARE &firmware) { + void SetFirmware(const DataProcessing::FIRMWARE &firmware) { firmware_ = firmware; } @@ -156,13 +146,13 @@ class XiaListModeDataMask { private: ///The firmware version that we are using. - FIRMWARE firmware_; + DataProcessing::FIRMWARE firmware_; ///The frequency of the module that we want to decode. unsigned int frequency_; std::string BadMaskErrorMessage(const std::string &func) const; - FIRMWARE ConvertStringToFirmware(const std::string &type); + DataProcessing::FIRMWARE ConvertStringToFirmware(const std::string &type); }; #endif //PIXIESUITE_XIALISTMODEDATAMASK_HPP diff --git a/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp index 270f27cea..90527e606 100644 --- a/Scan/ScanLib/source/XiaData.cpp +++ b/Scan/ScanLib/source/XiaData.cpp @@ -4,21 +4,6 @@ ///@authors C. R. Thornsberry and S. V. Paulauskas #include "XiaData.hpp" -///@TODO These methods are commented out since I'm not sure that we need them -/// . This should be verified at some point. -//void XiaData::reserve(const size_t &size){ -// if(size == 0){ return; } -// trace_.reserve(size); -//} -// -//void XiaData::assign(const size_t &size, const unsigned int &input){ -// trace_.assign(size, input); -//} -// -//void XiaData::push_back(const unsigned int &input){ -// trace_.push_back(input); -//} - ///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 @@ -29,7 +14,7 @@ void XiaData::Clear(){ energy_ = baseline_ = 0.0; - chanNum_ = crateNum_ = moduleNum_ = slotNum_ = cfdTime_ = 0; + chanNum_ = crateNum_ = slotNum_ = cfdTime_ = 0; eventTimeHigh_ = eventTimeLow_ = externalTimeLow_ = externalTimeHigh_ = 0; eSums_.clear(); diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 161890d21..1adff98ad 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -8,15 +8,11 @@ #include +#include "HelperEnumerations.hpp" #include "XiaListModeDataDecoder.hpp" using namespace std; - -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 -}; +using namespace DataProcessing; vector XiaListModeDataDecoder::DecodeBuffer( unsigned int *buf, const XiaListModeDataMask &mask) { @@ -52,9 +48,6 @@ vector XiaListModeDataDecoder::DecodeBuffer( unsigned int headerLength = lengths.first; unsigned int eventLength = lengths.second; - //This will handles the possibilty of up to 100 crates - data->SetModuleNumber(modNum += 100 * data->GetCrateNumber()); - data->SetEventTimeLow(buf[1]); DecodeWordTwo(buf[2], *data, mask); unsigned int traceLength = DecodeWordThree(buf[3], *data, mask); diff --git a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp index 4e8085071..eea1c6e29 100644 --- a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp @@ -8,9 +8,11 @@ #include +#include "HelperEnumerations.hpp" #include "XiaListModeDataEncoder.hpp" using namespace std; +using namespace DataProcessing; std::vector XiaListModeDataEncoder::EncodeXiaData( const XiaData &data, diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 853dfcfe2..c77636796 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -7,6 +7,7 @@ #include "XiaListModeDataMask.hpp" using namespace std; +using namespace DataProcessing; FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { FIRMWARE firmware = UNKNOWN; diff --git a/Scan/ScanLib/tests/unittest-XiaData.cpp b/Scan/ScanLib/tests/unittest-XiaData.cpp index 518a5b261..398fd6ddb 100644 --- a/Scan/ScanLib/tests/unittest-XiaData.cpp +++ b/Scan/ScanLib/tests/unittest-XiaData.cpp @@ -39,16 +39,10 @@ TEST_FIXTURE(XiaData, Test_GetId) { SetSlotNumber(test_slot_number); SetChannelNumber(test_channel_number); SetCrateNumber(test_crate_number); - SetModuleNumber(test_module_number); CHECK_EQUAL(test_crate_number * 208 + test_module_number * 16 + test_channel_number, GetId()); } -TEST_FIXTURE(XiaData, Test_ModuleNumber) { - SetModuleNumber(test_module_number); - CHECK_EQUAL(test_module_number, GetModuleNumber()); -} - TEST_FIXTURE(XiaData, Test_GetSetCfdForcedTrig) { SetCfdForcedTriggerBit(test_bool); CHECK(GetCfdForcedTriggerBit()); @@ -136,27 +130,16 @@ TEST_FIXTURE(XiaData, Test_GetSetVirtualChannel) { } TEST_FIXTURE(XiaData, Test_GetTime) { - SetCfdFractionalTime(test_cfd_time); - SetEventTimeHigh(test_event_time_high); - SetEventTimeLow(test_event_time_low); - SetCfdTriggerSourceBit(test_bool); - CHECK_EQUAL(test_cfd_time / pow(2., 14) + test_event_time_low + - test_event_time_high * pow(2., 32) - test_bool, GetTime()); + SetTime(123456789.); + CHECK_EQUAL(123456789, GetTime()); } ///This will test that the Time for the rhs is greater than the lhs TEST(Test_CompareTime){ lhs.Clear(); rhs.Clear(); - lhs.SetCfdFractionalTime(test_cfd_time); - lhs.SetEventTimeHigh(test_event_time_high); - lhs.SetEventTimeLow(test_event_time_low); - lhs.SetCfdTriggerSourceBit(test_bool); - - rhs.SetCfdFractionalTime(test_cfd_time+12); - rhs.SetEventTimeHigh(test_event_time_high); - rhs.SetEventTimeLow(test_event_time_low+36); - rhs.SetCfdTriggerSourceBit(test_bool); + lhs.SetTime(123456789.); + rhs.SetTime(123456799.); CHECK(lhs.CompareTime(&lhs, &rhs)); } @@ -167,12 +150,10 @@ TEST(Test_CompareId) { lhs.SetChannelNumber(test_channel_number); lhs.SetSlotNumber(test_slot_number); lhs.SetCrateNumber(test_crate_number); - lhs.SetModuleNumber(test_module_number); rhs.SetChannelNumber(test_channel_number); rhs.SetSlotNumber(test_slot_number+2); rhs.SetCrateNumber(test_crate_number); - rhs.SetModuleNumber(test_module_number+2); CHECK(lhs.CompareId(&lhs, &rhs)); } @@ -188,14 +169,9 @@ TEST(Test_Equality) { TEST(Test_LessThanOperator) { lhs.Clear(); rhs.Clear(); - lhs.SetCfdFractionalTime(test_cfd_time); - lhs.SetEventTimeHigh(test_event_time_high); - lhs.SetEventTimeLow(test_event_time_low); - lhs.SetCfdTriggerSourceBit(test_bool); - + lhs.SetTime(123456789); rhs = lhs; - rhs.SetEventTimeLow(test_event_time_low+100); - + rhs.SetTime(123456799); CHECK(lhs < rhs); } diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index d12533e4d..34c5ca947 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -5,138 +5,67 @@ #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); - -///We have added in the first to elements for the pixie module data header. -/// It contains the information about how many words are in the buffer and -/// the module VSN (number). This header is for firmware R30474 -///This 4 word header has the following characteristics: -/// 1. Word 0 -/// * Channel Number [3:0] : 13 -/// * Slot ID [7:4] : 2 -/// * CrateID [11:8] : 0 -/// * Header Length[16:12] : 4 -/// * Event Length [30:17] : 4 -/// * Finish Code [31] : 0 -/// 2. Word 1 -/// * EVTTIME_LO [0:31] : 123456789 -/// 3. Word 2 -/// * EVTTIME_HI [0:15] : 26001 -/// * CFD Fractional Time [30:16] : 0 -/// * CFD Trigger source bit [31] : 0 -/// 4. Word 3 -/// * Event Energy [0:14] : 2345 -/// * Trace Out-of-Range Flag [15] : 0 -/// * Trace Length [31:16] : 0 -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 -}; - -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}; - -//Here is all of the expected data for the above header. -static const unsigned int expected_chan = 13; -static const unsigned int expected_size = 1; -static const unsigned int expected_ts_high = 26001; -static const unsigned int expected_ts_low = 123456789; -static const unsigned int expected_cfd_fractional_time = 1234; -static const unsigned int expected_slot = 2; -static const unsigned int expected_energy = 2345; -static const double expected_ts = 111673568120085; -static const double expected_ts_w_cfd = 223347136240170.075317; -static const vector expected_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 vector expected_qdc = {123, 456, 789, 987, 654, - 321, 135, 791}; +using namespace unittest_encoded_data::R30474_250; //Test the error handling in the class TEST_FIXTURE(XiaListModeDataDecoder, TestBufferLengthChecks) { - //Check for a length_error when the buffer length is zero - unsigned int buffer_len_zero[6] = {0, 0}; - CHECK_THROW(DecodeBuffer(&buffer_len_zero[0], mask), length_error); - //Check for an empty vector when the buffer length is 2 (empty module) - unsigned int buffer_len_two[6] = {2, 0}; - unsigned int expected_size = 0; - CHECK_EQUAL(expected_size, DecodeBuffer(&buffer_len_two[0], mask).size()); + //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 for length_error when the header has an impossible size. - ///A header with a header length 20 instead of the true header length 4 - unsigned int header_w_bad_len[6] = {4, 0, 3887149, 123456789, 26001, 2345}; - CHECK_THROW(DecodeBuffer(&header_w_bad_len[0], mask), length_error); + CHECK_THROW(DecodeBuffer(&header_w_bad_headerlen[0], mask), length_error); //Check that we can decode a simple 4-word header. vector result = DecodeBuffer(&header[0], mask); XiaData result_data = *result.front(); - CHECK_EQUAL(expected_size, result.size()); - CHECK_EQUAL(expected_slot, result_data.GetSlotNumber()); - CHECK_EQUAL(expected_chan, result_data.GetChannelNumber()); - CHECK_EQUAL(expected_energy, result_data.GetEnergy()); - CHECK_EQUAL(expected_ts_high, result_data.GetEventTimeHigh()); - CHECK_EQUAL(expected_ts_low, result_data.GetEventTimeLow()); - CHECK_EQUAL(expected_ts, result_data.GetTime()); + 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) { - unsigned int badlen[6] = { - 59, 0, 7749677, 123456789, 26001, 8128809}; //Check that we throw length_error when the event length doesn't match. - CHECK_THROW(DecodeBuffer(&badlen[0], mask), length_error); + CHECK_THROW(DecodeBuffer(&header_w_bad_eventlen[0], mask), length_error); XiaData result = *DecodeBuffer(&header_N_trace[0], mask).front(); - CHECK_ARRAY_EQUAL(expected_trace, result.GetTrace(), expected_trace.size()); + 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(expected_qdc, result.GetQdc(), expected_qdc.size()); + 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(expected_cfd_fractional_time, result.GetCfdFractionalTime()); - CHECK_CLOSE(expected_ts_w_cfd, result.GetTime(), 1e-5); + CHECK_EQUAL(cfd_fractional_time, result.GetCfdFractionalTime()); + CHECK_CLOSE(ts_w_cfd, result.GetTime(), 1e-5); } diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp index 448307a19..07d8a3210 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp @@ -6,32 +6,15 @@ #include +#include "HelperEnumerations.hpp" +#include "UnitTestSampleData.hpp" #include "XiaListModeDataEncoder.hpp" using namespace std; - -//Here is all of the expected data for the XiaData. -static const unsigned int chan = 13; -static const unsigned int slot = 2; -static const unsigned int crate = 0; -static const unsigned int ts_high = 26001; -static const unsigned int ts_low = 123456789; -static const unsigned int ex_ts_high = 26001; -static const unsigned int ex_ts_low = 123456789; -static const unsigned int energy = 2345; -static const 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 vector qdc = {123, 456, 789, 987, 654, - 321, 135, 791}; +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 @@ -47,70 +30,34 @@ TEST_FIXTURE(XiaListModeDataEncoder, TestEncodingThrows) { ///Test if we can encode some headers with different information. ///@TODO Add headers for Esums and external TS. TEST_FIXTURE(XiaListModeDataEncoder, TestSimpleHeaderEncoding) { - vector expected_header = - {540717, 123456789, 26001, 2345}; - vector expected_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 - }; - vector expected_w_qdc = { - 1622061, 123456789, 26001, 2345, - 123, 456, 789, 987, 654, 321, 135, 791 - }; - vector expected_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 - }; - XiaData data; data.SetEnergy(energy); - data.SetSlotNumber(slot); - data.SetChannelNumber(chan); + data.SetSlotNumber(slotId); + data.SetChannelNumber(channelNumber); data.SetCrateNumber(crate); data.SetEventTimeLow(ts_low); data.SetEventTimeHigh(ts_high); //Check that we can handle just a simple 4 word header - CHECK_ARRAY_EQUAL(expected_header, EncodeXiaData(data, R30474, 250), - expected_header.size()); + CHECK_ARRAY_EQUAL(header_vec, EncodeXiaData(data, R30474, 250), + header_vec.size()); //Check that we can handle a header with a trace - data.SetTrace(trace); - CHECK_ARRAY_EQUAL(expected_w_trc, EncodeXiaData(data, R30474, 250), - expected_w_trc.size()); + 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(expected_w_qdc, EncodeXiaData(data, R30474, 250), - expected_w_qdc.size()); + 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(trace); - CHECK_ARRAY_EQUAL(expected_w_qdc_n_trc, EncodeXiaData(data, R30474, 250), - expected_w_qdc_n_trc.size()); + 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[]) { diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index b673f4c70..a824f5ebe 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -7,9 +7,11 @@ #include +#include "HelperEnumerations.hpp" #include "XiaListModeDataMask.hpp" using namespace std; +using namespace DataProcessing; TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { //We do not need to test more than on version of these since they are From 86b9d54fe26096c25567c08870acd9ab32f59625 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 4 Jan 2017 18:12:22 -0500 Subject: [PATCH 084/255] Fixing issues found during review process --- .gitignore | 2 +- Scan/Resources/include/UnitTestSampleData.hpp | 11 +- Scan/Resources/tests/CMakeLists.txt | 60 +++++---- .../tests/unittest-HelperFunctions.cpp | 2 - Scan/ScanLib/include/ChannelEvent.hpp | 3 + Scan/ScanLib/include/XiaData.hpp | 3 - Scan/ScanLib/source/ScanInterface.cpp | 4 +- Scan/ScanLib/source/Unpacker.cpp | 1 - Scan/ScanLib/tests/unittest-XiaData.cpp | 123 ++++++++---------- .../tests/unittest-XiaListModeDataDecoder.cpp | 9 +- .../tests/unittest-XiaListModeDataEncoder.cpp | 2 +- .../tests/unittest-XiaListModeDataMask.cpp | 1 - 12 files changed, 104 insertions(+), 117 deletions(-) diff --git a/.gitignore b/.gitignore index fd510478b..8cec4c3be 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ doxywarning.txt #Ignore the build and exec directory build/ -*-build-*/ +*build-*/ install/ diff --git a/Scan/Resources/include/UnitTestSampleData.hpp b/Scan/Resources/include/UnitTestSampleData.hpp index fa30650a5..6647f2f0f 100644 --- a/Scan/Resources/include/UnitTestSampleData.hpp +++ b/Scan/Resources/include/UnitTestSampleData.hpp @@ -16,7 +16,7 @@ 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 crate = 0; + 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; @@ -24,7 +24,14 @@ namespace unittest_decoded_data { 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 = 123456789; + 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}; diff --git a/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index 0ad816522..320028e45 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -1,36 +1,34 @@ -if(BUILD_UNITTESTS) - 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) +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++) - endif(USE_GSL) + #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++) +endif (USE_GSL) - add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) - target_link_libraries(unittest-HelperFunctions UnitTest++) - install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) +add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) +target_link_libraries(unittest-HelperFunctions UnitTest++) +install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) - 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-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) +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) -endif(BUILD_UNITTESTS) \ No newline at end of file +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/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index 0613a3d50..dc395595c 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -1,8 +1,6 @@ ///@file unittest-HelperFunctions.cpp ///@author S. V. Paulauskas ///@date December 12, 2016 -#include - #include #include "HelperFunctions.hpp" diff --git a/Scan/ScanLib/include/ChannelEvent.hpp b/Scan/ScanLib/include/ChannelEvent.hpp index 9d6604867..74c24b65b 100644 --- a/Scan/ScanLib/include/ChannelEvent.hpp +++ b/Scan/ScanLib/include/ChannelEvent.hpp @@ -5,6 +5,8 @@ #ifndef PIXIESUITE_CHANNELEVENT_HPP #define PIXIESUITE_CHANNELEVENT_HPP +#include + #include "XiaData.hpp" class ChannelEvent{ @@ -41,6 +43,7 @@ class ChannelEvent{ /// 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(); diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp index 2f43f4ae4..cb6383786 100644 --- a/Scan/ScanLib/include/XiaData.hpp +++ b/Scan/ScanLib/include/XiaData.hpp @@ -7,9 +7,6 @@ #include -#include -#include - /*! \brief A pixie16 channel event * * All data is grouped together into channels. For each pixie16 channel that diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp index 1b591f0d9..4ac6b951c 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -411,7 +411,7 @@ ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ 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"), + optionExt("version", no_argument, NULL, 'v', "", "Display version information") }; optstr = "bc:f:hi:o:qsv"; @@ -878,7 +878,7 @@ bool ScanInterface::Setup(int argc, char *argv[]){ file_start_offset = atoll(optarg); } else if(strcmp("frequency", longOpts[idx].name) == 0) - samplingFrequency = (unsigned int) atoi(optarg); + samplingFrequency = (unsigned int)std::stoi(optarg); else if(strcmp("firmware", longOpts[idx].name) == 0) firmware = optarg; else{ diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Scan/ScanLib/source/Unpacker.cpp index ac9464231..4b374cc5a 100644 --- a/Scan/ScanLib/source/Unpacker.cpp +++ b/Scan/ScanLib/source/Unpacker.cpp @@ -11,7 +11,6 @@ */ #include #include -#include #include #include diff --git a/Scan/ScanLib/tests/unittest-XiaData.cpp b/Scan/ScanLib/tests/unittest-XiaData.cpp index 398fd6ddb..55053acc0 100644 --- a/Scan/ScanLib/tests/unittest-XiaData.cpp +++ b/Scan/ScanLib/tests/unittest-XiaData.cpp @@ -8,138 +8,125 @@ #include +#include "UnitTestSampleData.hpp" #include "XiaData.hpp" using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_decoded_data; -static const bool test_bool = true; -static const double test_baseline = 32.2; -static const double test_energy = 123.4; -static const unsigned int test_cfd_time = 124; -static const unsigned int test_channel_number = 13; -static const unsigned int test_crate_number = 0; -static const unsigned int test_event_time_high = 1234; -static const unsigned int test_event_time_low = 123456789; -static const unsigned int test_external_time_high = 4321; -static const unsigned int test_external_time_low = 987654321; -static const unsigned int test_slot_number = 3; -static const unsigned int test_module_number = 1; -static const vector test_energy_sums = {12, 13, 14}; -static const vector test_qdc = {12, 13, 14, 78, 23, 34, 35, 6}; -static const vector test_trace = {12, 12, 12, 12, 12, 75, 90, 54, - 32, 12, 12}; XiaData lhs, rhs; TEST_FIXTURE(XiaData, Test_GetBaseline) { - SetBaseline(test_baseline); - CHECK_EQUAL(test_baseline, GetBaseline()); + SetBaseline(baseline); + CHECK_EQUAL(baseline, GetBaseline()); } TEST_FIXTURE(XiaData, Test_GetId) { - SetSlotNumber(test_slot_number); - SetChannelNumber(test_channel_number); - SetCrateNumber(test_crate_number); - CHECK_EQUAL(test_crate_number * 208 + test_module_number * 16 + - test_channel_number, GetId()); + SetSlotNumber(slotId); + SetChannelNumber(channelNumber); + SetCrateNumber(crateId); + CHECK_EQUAL(crateId * 208 + GetModuleNumber() * 16 + + channelNumber, GetId()); } TEST_FIXTURE(XiaData, Test_GetSetCfdForcedTrig) { - SetCfdForcedTriggerBit(test_bool); + SetCfdForcedTriggerBit(cfd_forced_trigger); CHECK(GetCfdForcedTriggerBit()); } TEST_FIXTURE(XiaData, Test_GetSetCfdFractionalTime) { - SetCfdFractionalTime(test_cfd_time); - CHECK_EQUAL(test_cfd_time, GetCfdFractionalTime()); + SetCfdFractionalTime(cfd_fractional_time); + CHECK_EQUAL(cfd_fractional_time, GetCfdFractionalTime()); } TEST_FIXTURE(XiaData, Test_GetSetCfdTriggerSourceBit) { - SetCfdTriggerSourceBit(test_bool); + SetCfdTriggerSourceBit(cfd_source_trigger_bit); CHECK(GetCfdTriggerSourceBit()); } TEST_FIXTURE(XiaData, Test_GetSetChannelNumber) { - SetChannelNumber(test_channel_number); - CHECK_EQUAL(test_channel_number, GetChannelNumber()); + SetChannelNumber(channelNumber); + CHECK_EQUAL(channelNumber, GetChannelNumber()); } TEST_FIXTURE(XiaData, Test_GetSetCrateNumber) { - SetCrateNumber(test_crate_number); - CHECK_EQUAL(test_crate_number, GetCrateNumber()); + SetCrateNumber(crateId); + CHECK_EQUAL(crateId, GetCrateNumber()); } TEST_FIXTURE(XiaData, Test_GetSetEnergy) { - SetEnergy(test_energy); - CHECK_EQUAL(test_energy, GetEnergy()); + SetEnergy(energy); + CHECK_EQUAL(energy, GetEnergy()); } TEST_FIXTURE(XiaData, Test_GetSetEnergySums) { - SetEnergySums(test_energy_sums); - CHECK_ARRAY_EQUAL(test_energy_sums, GetEnergySums(), - test_energy_sums.size()); + SetEnergySums(energy_sums); + CHECK_ARRAY_EQUAL(energy_sums, GetEnergySums(), + energy_sums.size()); } TEST_FIXTURE(XiaData, Test_GetSetEventTimeHigh) { - SetEventTimeHigh(test_event_time_high); - CHECK_EQUAL(test_event_time_high, GetEventTimeHigh()); + SetEventTimeHigh(ts_high); + CHECK_EQUAL(ts_high, GetEventTimeHigh()); } TEST_FIXTURE(XiaData, Test_GetSetEventTimeLow) { - SetEventTimeLow(test_event_time_low); - CHECK_EQUAL(test_event_time_low, GetEventTimeLow()); + SetEventTimeLow(ts_low); + CHECK_EQUAL(ts_low, GetEventTimeLow()); } TEST_FIXTURE(XiaData, Test_GetSetExternalTimeHigh) { - SetExternalTimeHigh(test_external_time_high); - CHECK_EQUAL(test_external_time_high, GetExternalTimeHigh()); + SetExternalTimeHigh(ex_ts_high); + CHECK_EQUAL(ex_ts_high, GetExternalTimeHigh()); } TEST_FIXTURE(XiaData, Test_GetSetExternalTimeLow) { - SetExternalTimeLow(test_external_time_low); - CHECK_EQUAL(test_external_time_low, GetExternalTimeLow()); + SetExternalTimeLow(ex_ts_low); + CHECK_EQUAL(ex_ts_low, GetExternalTimeLow()); } TEST_FIXTURE(XiaData, Test_GetSetPileup) { - SetPileup(test_bool); + SetPileup(pileup_bit); CHECK(IsPileup()); } TEST_FIXTURE(XiaData, Test_GetSetQdc) { - SetQdc(test_qdc); - CHECK_ARRAY_EQUAL(test_qdc, GetQdc(), test_qdc.size()); + SetQdc(qdc); + CHECK_ARRAY_EQUAL(qdc, GetQdc(), qdc.size()); } TEST_FIXTURE(XiaData, Test_GetSetSaturation) { - SetSaturation(test_bool); + SetSaturation(trace_out_of_range); CHECK(IsSaturated()); } TEST_FIXTURE(XiaData, Test_GetSetSlotNumber) { - SetSlotNumber(test_slot_number); - CHECK_EQUAL(test_slot_number, GetSlotNumber()); + SetSlotNumber(slotId); + CHECK_EQUAL(slotId, GetSlotNumber()); } TEST_FIXTURE(XiaData, Test_GetSetTrace) { - SetTrace(test_trace); - CHECK_ARRAY_EQUAL(test_trace, GetTrace(), test_trace.size()); + SetTrace(trace); + CHECK_ARRAY_EQUAL(trace, GetTrace(), trace.size()); } TEST_FIXTURE(XiaData, Test_GetSetVirtualChannel) { - SetVirtualChannel(test_bool); + SetVirtualChannel(virtual_channel); CHECK(IsVirtualChannel()); } TEST_FIXTURE(XiaData, Test_GetTime) { - SetTime(123456789.); - CHECK_EQUAL(123456789, 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(123456789.); - rhs.SetTime(123456799.); + lhs.SetTime(ts); + rhs.SetTime(ts+10); CHECK(lhs.CompareTime(&lhs, &rhs)); } @@ -147,31 +134,31 @@ TEST(Test_CompareTime){ //This will test that the ID for the rhs is greater than the lhs TEST(Test_CompareId) { lhs.Clear(); rhs.Clear(); - lhs.SetChannelNumber(test_channel_number); - lhs.SetSlotNumber(test_slot_number); - lhs.SetCrateNumber(test_crate_number); + lhs.SetChannelNumber(channelNumber); + lhs.SetSlotNumber(slotId); + lhs.SetCrateNumber(crateId); - rhs.SetChannelNumber(test_channel_number); - rhs.SetSlotNumber(test_slot_number+2); - rhs.SetCrateNumber(test_crate_number); + rhs.SetChannelNumber(channelNumber); + rhs.SetSlotNumber(slotId+2); + rhs.SetCrateNumber(crateId); CHECK(lhs.CompareId(&lhs, &rhs)); } TEST(Test_Equality) { lhs.Clear(); rhs.Clear(); - lhs.SetChannelNumber(test_channel_number); - lhs.SetSlotNumber(test_slot_number); - lhs.SetCrateNumber(test_crate_number); + lhs.SetChannelNumber(channelNumber); + lhs.SetSlotNumber(slotId); + lhs.SetCrateNumber(crateId); rhs = lhs; CHECK(lhs == rhs); } TEST(Test_LessThanOperator) { lhs.Clear(); rhs.Clear(); - lhs.SetTime(123456789); + lhs.SetTime(ts); rhs = lhs; - rhs.SetTime(123456799); + rhs.SetTime(ts+10); CHECK(lhs < rhs); } diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index 34c5ca947..5b0b90f6a 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -34,8 +34,7 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { CHECK_THROW(DecodeBuffer(&header_w_bad_headerlen[0], mask), length_error); //Check that we can decode a simple 4-word header. - vector result = DecodeBuffer(&header[0], mask); - XiaData result_data = *result.front(); + XiaData result_data = *(DecodeBuffer(&header[0], mask).front()); CHECK_EQUAL(slotId, result_data.GetSlotNumber()); CHECK_EQUAL(channelNumber, result_data.GetChannelNumber()); @@ -50,20 +49,20 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { //Check that we throw length_error when the event length doesn't match. CHECK_THROW(DecodeBuffer(&header_w_bad_eventlen[0], mask), length_error); - XiaData result = *DecodeBuffer(&header_N_trace[0], mask).front(); + 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(); + 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(); + 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); } diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp index 07d8a3210..e85e64dbe 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp @@ -34,7 +34,7 @@ TEST_FIXTURE(XiaListModeDataEncoder, TestSimpleHeaderEncoding) { data.SetEnergy(energy); data.SetSlotNumber(slotId); data.SetChannelNumber(channelNumber); - data.SetCrateNumber(crate); + data.SetCrateNumber(crateId); data.SetEventTimeLow(ts_low); data.SetEventTimeHigh(ts_high); diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index a824f5ebe..f13d93b76 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -2,7 +2,6 @@ ///@brief Unit testing of the XiaListModeDataMask class ///@author S. V. Paulauskas ///@date December 29, 2016 -#include #include #include From a51a25f703322ea9d0c0d9a33cd4cb533b044789 Mon Sep 17 00:00:00 2001 From: Thomas King Date: Thu, 5 Jan 2017 13:09:38 -0500 Subject: [PATCH 085/255] Added GetOutputName to globals This replaces the old GetArguments way of using the .his name as the name of the created root file. --- Scan/utkscan/core/include/Globals.hpp | 9 +++++++++ Scan/utkscan/core/source/UtkScanInterface.cpp | 3 +++ 2 files changed, 12 insertions(+) diff --git a/Scan/utkscan/core/include/Globals.hpp b/Scan/utkscan/core/include/Globals.hpp index 804e9c42d..434a1faee 100644 --- a/Scan/utkscan/core/include/Globals.hpp +++ b/Scan/utkscan/core/include/Globals.hpp @@ -270,6 +270,10 @@ 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 */ @@ -293,6 +297,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); @@ -339,6 +347,7 @@ class Globals { std::map > cfdPars_; //!< Map containing all of the parameters to be used in the cfd analyzer for a type:subtype std::map > trapFiltPars_; //!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 From 9270d47a6a4b1a7123f514f63959d4d42e59f913 Mon Sep 17 00:00:00 2001 From: Thomas King Date: Thu, 5 Jan 2017 14:23:31 -0500 Subject: [PATCH 086/255] Making Requested Changes Fixed the line breaks --- Scan/utkscan/core/include/Globals.hpp | 1 - Scan/utkscan/core/source/UtkScanInterface.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/Scan/utkscan/core/include/Globals.hpp b/Scan/utkscan/core/include/Globals.hpp index 434a1faee..ebf0bd84b 100644 --- a/Scan/utkscan/core/include/Globals.hpp +++ b/Scan/utkscan/core/include/Globals.hpp @@ -273,7 +273,6 @@ class Globals { /*! \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 */ diff --git a/Scan/utkscan/core/source/UtkScanInterface.cpp b/Scan/utkscan/core/source/UtkScanInterface.cpp index 7797c6a09..af1c4b414 100644 --- a/Scan/utkscan/core/source/UtkScanInterface.cpp +++ b/Scan/utkscan/core/source/UtkScanInterface.cpp @@ -75,7 +75,6 @@ bool UtkScanInterface::Initialize(std::string prefix_) { output_his = new OutputHisFile(GetOutputFilename().c_str()); output_his->SetDebugMode(false); - Globals::get()->SetOutputFilename(GetOutputFilename()); /** The DetectorDriver constructor will load processors From 986d9e9893e55948d3679e143d96c02b38d02d8c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sun, 8 Jan 2017 18:38:06 -0500 Subject: [PATCH 087/255] Adding simple Jenkinsfile to tracking --- Jenkinsfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..e69de29bb From ad0bd7eafa582e15c0876f721663b023ba0cfa25 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Sun, 8 Jan 2017 19:47:32 -0500 Subject: [PATCH 088/255] some simple updates --- Jenkinsfile | 14 ++++++++++++++ Scan/ScanLib/source/XiaListModeDataDecoder.cpp | 1 + Scan/ScanLib/source/XiaListModeDataEncoder.cpp | 1 + Scan/ScanLib/source/XiaListModeDataMask.cpp | 1 + 4 files changed, 17 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index e69de29bb..cdd7690aa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -0,0 +1,14 @@ +simpleBuild{ + env= [ + FOO : 42, + BAR : "YASS" + ] + + before_script = 'echo before' + script = 'echo after $FOO' + after_script = 'ls -lah' + + notifications = [ + email : "spaualus@utk.edu" + ] +} \ No newline at end of file diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 1adff98ad..5a9ea3725 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -5,6 +5,7 @@ /// @date December 23, 2016 #include #include +#include #include diff --git a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp index eea1c6e29..bb402ddc8 100644 --- a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataEncoder.cpp @@ -5,6 +5,7 @@ /// @date December 30, 2016 #include #include +#include #include diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index c77636796..1fbd2b6ff 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -3,6 +3,7 @@ /// @author S. V. Paulauskas /// @date December 29, 2016 #include +#include #include "XiaListModeDataMask.hpp" From f0677cba8433add3a442b298b28a84eb83801461 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 17:17:49 -0500 Subject: [PATCH 089/255] Fixing some header issues --- Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp | 3 ++- Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index 5b0b90f6a..9676ec6a8 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -2,7 +2,8 @@ ///@brief Unit tests for the XiaListModeDataDecoder class ///@author S. V. Paulauskas ///@author December 25, 2016 -#include +#include + #include #include "HelperEnumerations.hpp" diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index f13d93b76..a824f5ebe 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -2,6 +2,7 @@ ///@brief Unit testing of the XiaListModeDataMask class ///@author S. V. Paulauskas ///@date December 29, 2016 +#include #include #include From 706661cec3ad3b99e700a8d1ea488bad3ec36b08 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 17:19:53 -0500 Subject: [PATCH 090/255] Few more missing headers --- Scan/Resources/tests/unittest-GslFitter.cpp | 1 + Scan/Resources/tests/unittest-PolynomialCfd.cpp | 1 + Scan/Resources/tests/unittest-TraditionalCfd.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/Scan/Resources/tests/unittest-GslFitter.cpp b/Scan/Resources/tests/unittest-GslFitter.cpp index 532c5eebb..0474503c2 100644 --- a/Scan/Resources/tests/unittest-GslFitter.cpp +++ b/Scan/Resources/tests/unittest-GslFitter.cpp @@ -3,6 +3,7 @@ ///\author S. V. Paulauskas ///\date August 8, 2016 #include +#include #include diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Scan/Resources/tests/unittest-PolynomialCfd.cpp index ad895c8f2..11efe5f5e 100644 --- a/Scan/Resources/tests/unittest-PolynomialCfd.cpp +++ b/Scan/Resources/tests/unittest-PolynomialCfd.cpp @@ -2,6 +2,7 @@ ///@author S. V. Paulauskas ///@date December 12, 2016 #include +#include #include #include diff --git a/Scan/Resources/tests/unittest-TraditionalCfd.cpp b/Scan/Resources/tests/unittest-TraditionalCfd.cpp index aeef27a9d..3616edd0b 100644 --- a/Scan/Resources/tests/unittest-TraditionalCfd.cpp +++ b/Scan/Resources/tests/unittest-TraditionalCfd.cpp @@ -2,6 +2,7 @@ ///@author S. V. Paulauskas ///@date December 12, 2016 #include +#include #include From b1a42abb4b71d35f8c3c6a79b105fdd4d6e6c0fb Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 19:18:35 -0500 Subject: [PATCH 091/255] Removing Jenkins file from tracking since its unnecessary. --- Jenkinsfile | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index cdd7690aa..000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,14 +0,0 @@ -simpleBuild{ - env= [ - FOO : 42, - BAR : "YASS" - ] - - before_script = 'echo before' - script = 'echo after $FOO' - after_script = 'ls -lah' - - notifications = [ - email : "spaualus@utk.edu" - ] -} \ No newline at end of file From d0a88d8f715352d38a40ce734dc4143af6bca2b9 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 19:58:57 -0500 Subject: [PATCH 092/255] Fixing HelperFunction unit test so that all tests pass --- Scan/Resources/include/HelperFunctions.hpp | 41 +++++++------------ Scan/Resources/include/UnitTestSampleData.hpp | 3 +- .../tests/unittest-HelperFunctions.cpp | 10 ++--- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index 5630a5ac2..96e8a4a9b 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -206,7 +206,7 @@ namespace Statistics { namespace TraceFunctions { ///The minimum length that is necessary for a good baseline calculation. - static const unsigned int minimum_baseline_length = 30; + 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 @@ -220,11 +220,9 @@ namespace TraceFunctions { /// baseline and the second element being the standard deviation of the /// baseline. template - inline pair CalculateBaseline(const vector - &data, - const pair - &range) { + inline pair CalculateBaseline( + const vector &data, + const pair &range) { if (data.size() == 0) throw range_error("TraceFunctions::ComputeBaseline - Data vector " "sized 0"); @@ -265,8 +263,8 @@ namespace TraceFunctions { /// @return An STL pair containing the maximum that we found and the template inline pair > ExtrapolateMaximum( - const vector &data, const pair &maxInfo) { + const vector &data, + const pair &maxInfo) { if (data.size() < 4) throw range_error("TraceFunctions::ExtrapolateMaximum - " "The data vector has less than 4 " @@ -348,9 +346,9 @@ namespace TraceFunctions { ///@TODO Fix this method so that it works properly. template inline unsigned int FindLeadingEdge(const vector &data, - const double &threshold, + const double &fraction, const pair &maxInfo) { - if (threshold <= 0) + if (fraction <= 0) throw range_error("TraceFunctions::FindLeadingEdge - The " "threshold was below zero."); if (data.size() < minimum_baseline_length) @@ -361,23 +359,14 @@ namespace TraceFunctions { throw range_error("TraceFunctions::FindLeadingEdge - The " "position of the maximum is outside of " "the size of the data vector."); - unsigned int val = 9999; + + double threshold = fraction * maxInfo.second; + unsigned int idx = 9999; for (size_t index = maxInfo.first; - index > minimum_baseline_length; index--) { - if (data[index] <= threshold * maxInfo.second) { - // Interpolate and return the value - // y = thresh_ * maximum - // x = (x1 + (y-y1)/(y2-y1)) - // x1 = index, x2 = index+1 - // y1 = data[index], y2 = data[index+1] - if (data[index + 1] == data[index]) - val = index + 1; - else - val = index + (threshold * maxInfo.second - data[index]) / - (data[index + 1] - data[index]); - } - } - return val; + 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 diff --git a/Scan/Resources/include/UnitTestSampleData.hpp b/Scan/Resources/include/UnitTestSampleData.hpp index 6647f2f0f..6b1fad8bd 100644 --- a/Scan/Resources/include/UnitTestSampleData.hpp +++ b/Scan/Resources/include/UnitTestSampleData.hpp @@ -247,7 +247,6 @@ namespace unittest_helper_functions { //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 @@ -279,7 +278,7 @@ namespace unittest_helper_functions { //-------------------------------------------------------------------------- //This is the expected position of the leading edge of signal. - static const unsigned int leading_edge_position = 72; + static const unsigned int leading_edge_position = 73; static const double leading_edge_fraction = 0.5; static const double bad_fraction = -0.5; } diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Scan/Resources/tests/unittest-HelperFunctions.cpp index dc395595c..9c6939eff 100644 --- a/Scan/Resources/tests/unittest-HelperFunctions.cpp +++ b/Scan/Resources/tests/unittest-HelperFunctions.cpp @@ -29,8 +29,8 @@ TEST(TestCalculateBaseline) { //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_THROW(TraceFunctions::CalculateBaseline( + trace, make_pair(0, trace.size() + 100)), range_error); //Check that we are actually calculating the parameters properly pair result = @@ -51,7 +51,7 @@ TEST(TestFindMaxiumum) { //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, 10), range_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. @@ -77,8 +77,8 @@ TEST(TestFindLeadingEdge) { 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.)), + 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 From b3cfc7a530e9e9e4e0c363bcfa18f49017cf81eb Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 21:11:48 -0500 Subject: [PATCH 093/255] Fixing issues with GslFitters, Unit Tests. --- Scan/Resources/include/GslFitter.hpp | 2 +- Scan/Resources/include/RootFitter.hpp | 2 +- Scan/Resources/include/UnitTestSampleData.hpp | 5 +- Scan/Resources/source/Gsl1Fitter.cpp | 61 +++++++++---------- Scan/Resources/source/Gsl2Fitter.cpp | 4 +- Scan/Resources/source/RootFitter.cpp | 2 +- Scan/Resources/tests/CMakeLists.txt | 1 + 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Scan/Resources/include/GslFitter.hpp b/Scan/Resources/include/GslFitter.hpp index dc114e514..48a43c4f8 100644 --- a/Scan/Resources/include/GslFitter.hpp +++ b/Scan/Resources/include/GslFitter.hpp @@ -37,7 +37,7 @@ class GslFitter : public TimingDriver { /// @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, + double CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline); diff --git a/Scan/Resources/include/RootFitter.hpp b/Scan/Resources/include/RootFitter.hpp index 18d6bb6ec..6dd2d767a 100644 --- a/Scan/Resources/include/RootFitter.hpp +++ b/Scan/Resources/include/RootFitter.hpp @@ -14,7 +14,7 @@ class RootFitter : public TimingDriver { ~RootFitter() {}; /// Perform CFD analysis on the waveform using the pol2 algorithm. - double CalculatePhase(const std::vector &data, + double CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &maxInfo, std::pair baseline); diff --git a/Scan/Resources/include/UnitTestSampleData.hpp b/Scan/Resources/include/UnitTestSampleData.hpp index 6b1fad8bd..facfd2c2b 100644 --- a/Scan/Resources/include/UnitTestSampleData.hpp +++ b/Scan/Resources/include/UnitTestSampleData.hpp @@ -185,8 +185,9 @@ namespace unittest_trace_variables { //This is the region that should be defined as the waveform for the above // trace - static const std::vector waveform(trace.begin() + 71, - trace.begin() + 86); + 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; diff --git a/Scan/Resources/source/Gsl1Fitter.cpp b/Scan/Resources/source/Gsl1Fitter.cpp index 618fd3668..0d7e1f9fa 100644 --- a/Scan/Resources/source/Gsl1Fitter.cpp +++ b/Scan/Resources/source/Gsl1Fitter.cpp @@ -47,7 +47,7 @@ int SiPmtFunctionDerivative(const gsl_vector *x, void *FitData, gsl_vector *f, using namespace std; -void GslFitter::PerformFit(const std::vector &data, +double GslFitter::CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline) { @@ -60,17 +60,17 @@ void GslFitter::PerformFit(const std::vector &data, double *y = new double[sizeFit]; double *sigma = new double[sizeFit]; for(unsigned int i = 0; i < sizeFit; i++) { - y[i] = data.at(i) - baseline.first; + y[i] = data.at(i); sigma[i] = baseline.second; } - struct FitDriver::FitData fitData = + struct GslFitter::FitData fitData = {sizeFit, y, sigma, pars.first, pars.second, area}; f.n = sizeFit; f.params = &fitData; - if(!isSipmFast) { + if(!isFastSiPm_) { numParams = 2; xInit[0] = 0.0; xInit[1] = 2.5; @@ -93,8 +93,8 @@ void GslFitter::PerformFit(const std::vector &data, f.p = numParams; gsl_multifit_fdfsolver_set (s, &f, &x.vector); - static const maxIter = 1e8; - static const tolerance = 1e-4; + 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); @@ -108,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(!isSipmFast) { - 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); @@ -147,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); @@ -185,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); @@ -203,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/Scan/Resources/source/Gsl2Fitter.cpp b/Scan/Resources/source/Gsl2Fitter.cpp index e0066551c..bf40176c5 100644 --- a/Scan/Resources/source/Gsl2Fitter.cpp +++ b/Scan/Resources/source/Gsl2Fitter.cpp @@ -34,7 +34,7 @@ int CalcSiPmtJacobian(const gsl_vector *x, void *FitData, gsl_matrix *J); using namespace std; -double GslFitter::CalculatePhase(const std::vector &data, +double GslFitter::CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &max, const std::pair baseline) { @@ -83,7 +83,7 @@ double GslFitter::CalculatePhase(const std::vector &data, for (unsigned int i = 0; i < n; i++) { weights[i] = baseline.second; - y[i] = data[i] - baseline.first; + y[i] = data[i]; } gsl_multifit_fdfsolver_wset(s, &f, &x.vector, &w.vector); diff --git a/Scan/Resources/source/RootFitter.cpp b/Scan/Resources/source/RootFitter.cpp index 360b4bd78..da13d2882 100644 --- a/Scan/Resources/source/RootFitter.cpp +++ b/Scan/Resources/source/RootFitter.cpp @@ -13,7 +13,7 @@ using namespace std; -double RootFitter::CalculatePhase(const std::vector &data, +double RootFitter::CalculatePhase(const std::vector &data, const std::pair &pars, const std::pair &maxInfo, std::pair baseline) { diff --git a/Scan/Resources/tests/CMakeLists.txt b/Scan/Resources/tests/CMakeLists.txt index 320028e45..42539aee6 100644 --- a/Scan/Resources/tests/CMakeLists.txt +++ b/Scan/Resources/tests/CMakeLists.txt @@ -9,6 +9,7 @@ if (USE_GSL) 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-HelperFunctions unittest-HelperFunctions.cpp) From e55d0e54025ceef3e4c0c6661017a5941f4aa19b Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 21:19:09 -0500 Subject: [PATCH 094/255] Removing unnecessary Cmake Flag --- Scan/utkscan/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index be406c30e..e219d1c46 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -1,6 +1,4 @@ #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(UTKSCAN_ONLINE "Options for online scans" OFF) option(UTKSCAN_TREE_DEBUG "Debugging info for TreeCorrelator" OFF) From 3806fc324ccd64e8b3e49a356abe7a31f34327fd Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 9 Jan 2017 21:24:49 -0500 Subject: [PATCH 095/255] Fixing bug in Gsl1Fitter --- Scan/Resources/source/Gsl1Fitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/Resources/source/Gsl1Fitter.cpp b/Scan/Resources/source/Gsl1Fitter.cpp index 0d7e1f9fa..039aa5ba9 100644 --- a/Scan/Resources/source/Gsl1Fitter.cpp +++ b/Scan/Resources/source/Gsl1Fitter.cpp @@ -65,7 +65,7 @@ double GslFitter::CalculatePhase(const std::vector &data, } struct GslFitter::FitData fitData = - {sizeFit, y, sigma, pars.first, pars.second, area}; + {sizeFit, y, sigma, pars.first, pars.second, qdc_}; f.n = sizeFit; f.params = &fitData; From e74d5cd5aa0aa6976c17504fefe91a3c47614261 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 10 Jan 2017 09:55:34 -0500 Subject: [PATCH 096/255] Remvoing constexpr since it requires c++std11 We still have some dev machines (kqxhc) that do not have access to this yet. This machine has gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) --- Scan/ScanLib/include/RootScanner.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/ScanLib/include/RootScanner.hpp b/Scan/ScanLib/include/RootScanner.hpp index 0e8ea8b2a..63b5cf544 100644 --- a/Scan/ScanLib/include/RootScanner.hpp +++ b/Scan/ScanLib/include/RootScanner.hpp @@ -20,7 +20,7 @@ class RootScanner : public ScanInterface { private: TCanvas *canvas_; - static constexpr const int numAxes_ = 3; + static const int numAxes_ = 3; struct AxisInfo { double rangeUserMin[numAxes_]; double rangeUserMax[numAxes_]; From 2b35924d2473d530c0ee2b74ce8d2162216a26ef Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 10 Jan 2017 10:03:16 -0500 Subject: [PATCH 097/255] Some more updates to get compiled on kqxhc --- Scan/ScanLib/source/Unpacker.cpp | 1 + Scan/utkscan/core/source/Trace.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Scan/ScanLib/source/Unpacker.cpp index 4b374cc5a..080f78130 100644 --- a/Scan/ScanLib/source/Unpacker.cpp +++ b/Scan/ScanLib/source/Unpacker.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include diff --git a/Scan/utkscan/core/source/Trace.cpp b/Scan/utkscan/core/source/Trace.cpp index 05889703c..08edeaa83 100644 --- a/Scan/utkscan/core/source/Trace.cpp +++ b/Scan/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)); } } From d3d159b203ded64b35fb57eab97d0c905a204185 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Wed, 28 Dec 2016 10:10:19 -0600 Subject: [PATCH 098/255] Fixed pld format incorrect max_spill_size Former-commit-id: 3278c92775d69fd9e104b9bd2ad978d24f24b7db --- Core/source/hribf_buffers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 473a43c58..5b1c557d9 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -1028,7 +1028,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; From 376a6888eebc814665f7112e6a2621734ef721c0 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Wed, 28 Dec 2016 10:21:48 -0600 Subject: [PATCH 099/255] Fixed pld format run number display Former-commit-id: f1534254a0c1a7df959f508ad905ca57eeedd1cf --- Core/include/hribf_buffers.h | 2 +- Core/source/hribf_buffers.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Core/include/hribf_buffers.h b/Core/include/hribf_buffers.h index 9bfb62d68..15d9a0a00 100644 --- a/Core/include/hribf_buffers.h +++ b/Core/include/hribf_buffers.h @@ -405,7 +405,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/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 5b1c557d9..0d0f07fe8 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -1263,6 +1263,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; } From 6a9950124b3c3d524ab54bb05ab7225856966d61 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Wed, 28 Dec 2016 10:37:42 -0600 Subject: [PATCH 100/255] Fixed ldf header not being initialized properly Former-commit-id: 2e6b5df04f8d48f24d4a5b0ea01155295eb0eef0 --- Core/source/hribf_buffers.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 0d0f07fe8..32e51ecae 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -96,7 +96,7 @@ bool BufferType::ReadHeader(std::ifstream *file_){ /// Default constructor. PLD_header::PLD_header() : BufferType(HEAD, 0){ // 0x44414548 "HEAD" - PLD_header::Reset(); + this->Reset(); } /// Destructor. @@ -254,6 +254,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. @@ -318,6 +319,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, @@ -391,6 +393,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. @@ -589,6 +592,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. From da84abd406c09761c21abf4151a7ec7dc3b0a7d6 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Wed, 28 Dec 2016 13:51:24 -0600 Subject: [PATCH 101/255] Fixed pld ACQ time not being set correctly Former-commit-id: fa1533769c46dd0069eb32d74786de3f60e4b81c --- Core/include/hribf_buffers.h | 3 +++ Core/source/hribf_buffers.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Core/include/hribf_buffers.h b/Core/include/hribf_buffers.h index 15d9a0a00..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(); diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 32e51ecae..07ecf74e5 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -113,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 } @@ -1296,7 +1297,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(); From a4297f6adbfee9e5f16335f5df8b349d42bbcc28 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 08:54:35 -0500 Subject: [PATCH 102/255] Removing throw for Bad Event Length error Due to issues with data corruption for data taken using PixieSuite2 this throw caused many data files to be unreadable. We have recovered previous functionality and updated the error message accordingly. --- Scan/ScanLib/source/XiaListModeDataDecoder.cpp | 17 +++++++++++------ .../tests/unittest-XiaListModeDataDecoder.cpp | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 5a9ea3725..cc4f631ae 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -37,6 +37,7 @@ vector XiaListModeDataDecoder::DecodeBuffer( stringstream msg; vector events; + unsigned int numSkippedTriggers = 0; while (buf < bufStart + bufLen) { XiaData* data = new XiaData(); @@ -133,13 +134,17 @@ vector XiaListModeDataDecoder::DecodeBuffer( //We set the time according to the revision and firmware. data->SetTime(CalculateTimeInSamples(mask, *data)); - // One last check + // One last check to ensure event length matches what we think it + // should be. if (traceLength / 2 + headerLength != eventLength) { - msg << "ReadBuffer: Bad event length (" << eventLength - << ") does not correspond with length of header (" - << headerLength << ") and length of trace (" << traceLength - << ")"; - throw length_error(msg.str()); + numSkippedTriggers++; + cerr << "XiaListModeDataDecoder::ReadBuffer : Event" + "length (" << eventLength << ") does not correspond to " + "header length (" << headerLength << ") and trace length (" + << traceLength / 2 << "). Skipping this trigger. Skipped " + "trigger(s) this buffer " << numSkippedTriggers << "."; + buf += eventLength; + continue; } else //Advance the buffer past the header and to the trace buf += headerLength; diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index 9676ec6a8..44082fd3b 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -47,8 +47,8 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { //Test if we can decode a trace properly TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { - //Check that we throw length_error when the event length doesn't match. - CHECK_THROW(DecodeBuffer(&header_w_bad_eventlen[0], mask), length_error); + //Now doing this just to view the error message + DecodeBuffer(&header_w_bad_eventlen[0], mask); XiaData result = *(DecodeBuffer(&header_N_trace[0], mask).front()); CHECK_ARRAY_EQUAL(unittest_trace_variables::trace, result.GetTrace(), From 01aa1cb66f528e618be760a23fb84efe6647f405 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 09:28:29 -0500 Subject: [PATCH 103/255] Just skipping ahead in the buffer is a bad idea. If we simply skip ahead in the buffer then the next pass through the buffer will give us a bad header length, since we didn't decode the first trigger properly. In both cases (unknown header length and bad event length) we simply need to throw away the entire buffer. --- .../ScanLib/source/XiaListModeDataDecoder.cpp | 50 ++++++++++--------- .../tests/unittest-XiaListModeDataDecoder.cpp | 10 ++-- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index cc4f631ae..cad93c96d 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -5,7 +5,6 @@ /// @date December 23, 2016 #include #include -#include #include @@ -15,7 +14,7 @@ using namespace std; using namespace DataProcessing; -vector XiaListModeDataDecoder::DecodeBuffer( +vector XiaListModeDataDecoder::DecodeBuffer( unsigned int *buf, const XiaListModeDataMask &mask) { unsigned int *bufStart = buf; @@ -33,14 +32,14 @@ vector XiaListModeDataDecoder::DecodeBuffer( //For empty buffers we just return an empty vector. static const unsigned int emptyBufferLength = 2; if (bufLen == emptyBufferLength) - return vector(); + return vector(); stringstream msg; - vector events; - unsigned int numSkippedTriggers = 0; + vector events; + static unsigned int numSkippedBuffers = 0; while (buf < bufStart + bufLen) { - XiaData* data = new XiaData(); + XiaData *data = new XiaData(); bool hasExternalTimestamp = false; bool hasQdc = false; bool hasEnergySums = false; @@ -90,17 +89,20 @@ vector XiaListModeDataDecoder::DecodeBuffer( hasQdc = hasExternalTimestamp = true; break; default: - msg << "XiaListModeDataDecoder::ReadBuffer : We encountered an " - "unrecognized header length (" - << headerLength << "). Skipping the remaining buffer." - << endl << "ReadBuffer: Unexpected header length: " - << headerLength << endl << "ReadBuffer: Buffer " - << modNum << " of length " << bufLen << endl - << "ReadBuffer: CHAN:SLOT:CRATE " - << data->GetChannelNumber() << ":" - << data->GetSlotNumber() << ":" - << data->GetCrateNumber() << endl; - throw length_error(msg.str()); + 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:CHAN " + << data->GetCrateNumber() << ":" + << data->GetSlotNumber() << ":" + << data->GetChannelNumber() << endl; + return vector(); } if (hasExternalTimestamp) { @@ -137,14 +139,14 @@ vector XiaListModeDataDecoder::DecodeBuffer( // One last check to ensure event length matches what we think it // should be. if (traceLength / 2 + headerLength != eventLength) { - numSkippedTriggers++; + numSkippedBuffers++; cerr << "XiaListModeDataDecoder::ReadBuffer : Event" "length (" << eventLength << ") does not correspond to " - "header length (" << headerLength << ") and trace length (" - << traceLength / 2 << "). Skipping this trigger. Skipped " - "trigger(s) this buffer " << numSkippedTriggers << "."; - buf += eventLength; - continue; + "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; @@ -216,7 +218,7 @@ double XiaListModeDataDecoder::CalculateTimeInSamples( double filterTime = data.GetEventTimeLow() + data.GetEventTimeHigh() * pow(2., 32); - if(data.GetCfdFractionalTime() == 0 || data.GetCfdForcedTriggerBit()) + if (data.GetCfdFractionalTime() == 0 || data.GetCfdForcedTriggerBit()) return filterTime; double cfdTime = 0, multiplier = 1; diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp index 44082fd3b..50d3dbdf8 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp @@ -31,8 +31,9 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestBufferLengthChecks) { ///Test if we can decode a simple 4 word header that includes the Pixie /// Module Data Header. TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { - //Check for length_error when the header has an impossible size. - CHECK_THROW(DecodeBuffer(&header_w_bad_headerlen[0], mask), length_error); + //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()); @@ -47,8 +48,9 @@ TEST_FIXTURE(XiaListModeDataDecoder, TestHeaderDecoding) { //Test if we can decode a trace properly TEST_FIXTURE(XiaListModeDataDecoder, TestTraceDecoding) { - //Now doing this just to view the error message - DecodeBuffer(&header_w_bad_eventlen[0], mask); + //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(), From 902257f25a9d2cedfadb7db7a405958741b4162d Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 09:59:22 -0500 Subject: [PATCH 104/255] Updated error message to include module number --- Scan/ScanLib/source/XiaListModeDataDecoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index cad93c96d..5382e34f2 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -98,9 +98,9 @@ vector XiaListModeDataDecoder::DecodeBuffer( << "Unexpected header length: " << headerLength << endl << "ReadBuffer: Buffer " << modNum << " of length " << bufLen << endl - << "ReadBuffer: CRATE:SLOT:CHAN " + << "ReadBuffer: CRATE:SLOT(MOD):CHAN " << data->GetCrateNumber() << ":" - << data->GetSlotNumber() << ":" + << data->GetSlotNumber() << "(" << modNum << "):" << data->GetChannelNumber() << endl; return vector(); } From 69f79a52bc2d73cf6115116ef3ec8d0a1c5033b0 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 10:19:48 -0500 Subject: [PATCH 105/255] Adding a missing header. --- Scan/ScanLib/source/XiaListModeDataDecoder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 5382e34f2..8d7a5283c 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -5,6 +5,7 @@ /// @date December 23, 2016 #include #include +#include #include From 1beb17e90e86dd4893c08b8ac768bbb2d213ed92 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 11 Jan 2017 09:34:24 -0500 Subject: [PATCH 106/255] Now properly handling the sign of the x^2 coefficient --- Scan/Resources/source/PolynomialCfd.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Scan/Resources/source/PolynomialCfd.cpp index f53dc97a9..957652095 100644 --- a/Scan/Resources/source/PolynomialCfd.cpp +++ b/Scan/Resources/source/PolynomialCfd.cpp @@ -25,6 +25,7 @@ double PolynomialCfd::CalculatePhase(const std::vector &data, double threshold = pars.first * max.second; double phase = -9999; + float multiplier = 1.; vector result; for (unsigned int cfdIndex = max.first; cfdIndex > 0; cfdIndex--) { @@ -32,17 +33,11 @@ double PolynomialCfd::CalculatePhase(const std::vector &data, // Fit the rise of the trace to a 2nd order polynomial. result = Polynomial::CalculatePoly2(data, cfdIndex - 1).second; - //We want to stop things here so that the user can do some - // debugging of potential issues. - if (result[2] > 0) - throw range_error("PolynomialCfd::CalculatePhase : The " - "calculated coefficients were for a" - " concave-upward parabola. " - "Increase your fraction to " - "improve quality."); - // Calculate the phase of the trace. - phase = (-result[1] + + if(result[2] > 1) + multiplier = -1.; + + phase = (-result[1] + multiplier * sqrt(result[1] * result[1] - 4 * result[2] * (result[0] - threshold))) / From d5f3047c9a9e88be38d3d911c16e41e4187c5d4d Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 13:14:49 -0500 Subject: [PATCH 107/255] If the USE_ROOT Flag was turned off, then we couldn't compile ScanLib --- Scan/ScanLib/source/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt index b015abde2..674926281 100644 --- a/Scan/ScanLib/source/CMakeLists.txt +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -1,7 +1,11 @@ #Set the scan sources that we will make a lib out of set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp - XiaListModeDataEncoder.cpp RootScanner.cpp) + XiaListModeDataEncoder.cpp) + +if(USE_ROOT) + list(APPEND ScanSources RootScanner.cpp) +endif(USE_ROOT) #Add the sources to the library add_library(ScanObjects OBJECT ${ScanSources}) From cc3055dd3437fbb8523920f049970431d68cf39f Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 11:46:11 -0500 Subject: [PATCH 108/255] Updating TemplateExpProcessor to remove warnings. --- Scan/utkscan/core/source/DetectorDriver.cpp | 27 ++++++++++++------- .../include/TemplateExpProcessor.hpp | 3 --- .../source/TemplateExpProcessor.cpp | 27 ++++++++----------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index ba377c0c6..a0a18c57f 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -11,8 +11,12 @@ #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" @@ -22,6 +26,17 @@ #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,15 +55,7 @@ #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" #ifdef useroot @@ -215,7 +222,7 @@ 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") { vecProcess.push_back(new RootProcessor("tree.root", "tree")); diff --git a/Scan/utkscan/experiment/include/TemplateExpProcessor.hpp b/Scan/utkscan/experiment/include/TemplateExpProcessor.hpp index 1d668f0b0..29d604b08 100644 --- a/Scan/utkscan/experiment/include/TemplateExpProcessor.hpp +++ b/Scan/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/source/TemplateExpProcessor.cpp b/Scan/utkscan/experiment/source/TemplateExpProcessor.cpp index c865bab3b..3636772b7 100644 --- a/Scan/utkscan/experiment/source/TemplateExpProcessor.cpp +++ b/Scan/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); From 4d8cd0c401a9dae86b9ddf0818ddc0acf666881c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 11:50:08 -0500 Subject: [PATCH 109/255] Adding TwoChanTimingProcessor to compilation --- Scan/utkscan/core/source/DetectorDriver.cpp | 7 +++++-- Scan/utkscan/experiment/source/CMakeLists.txt | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index a0a18c57f..764b8b540 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -57,6 +57,7 @@ //These headers are for handling experiment specific processing. #include "TemplateExpProcessor.hpp" +#include "TwoChanTimingProcessor.hpp" #ifdef useroot #include "RootProcessor.hpp" @@ -222,7 +223,9 @@ void DetectorDriver::LoadProcessors(Messenger& m) { vecProcess.push_back(new TemplateProcessor()); } else if (name == "TemplateExpProcessor") { vecProcess.push_back(new TemplateExpProcessor()); - } + } else if (name == "TwoChanTimingProcessor") { + vecProcess.push_back(new TwoChanTimingProcessor()); + } #ifdef useroot else if (name == "RootProcessor") { vecProcess.push_back(new RootProcessor("tree.root", "tree")); @@ -230,7 +233,7 @@ void DetectorDriver::LoadProcessors(Messenger& m) { #endif else { stringstream ss; - ss << "DetectorDriver: unknown processor type" << name; + ss << "DetectorDriver: unknown processor type : " << name; throw GeneralException(ss.str()); } stringstream ss; diff --git a/Scan/utkscan/experiment/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt index 13e53cb67..5b7cd4e8e 100644 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ b/Scan/utkscan/experiment/source/CMakeLists.txt @@ -1,5 +1,6 @@ set(EXPERIMENT_SOURCES TemplateExpProcessor.cpp + TwoChanTimingProcessor.cpp ) add_library(ExperimentObjects OBJECT ${EXPERIMENT_SOURCES}) From 6ce546adbdda8bd5eaccaf262b129956f2d74a4a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 11:53:53 -0500 Subject: [PATCH 110/255] Adding IS600Processor to compilation --- Scan/utkscan/core/source/DetectorDriver.cpp | 3 +++ Scan/utkscan/experiment/source/CMakeLists.txt | 1 + .../experiment/source/IS600Processor.cpp | 26 ++++++------------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index 764b8b540..5de5068c6 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -56,6 +56,7 @@ #include "ValidProcessor.hpp" //These headers are for handling experiment specific processing. +#include "IS600Processor.hpp" #include "TemplateExpProcessor.hpp" #include "TwoChanTimingProcessor.hpp" @@ -225,6 +226,8 @@ void DetectorDriver::LoadProcessors(Messenger& m) { vecProcess.push_back(new TemplateExpProcessor()); } else if (name == "TwoChanTimingProcessor") { vecProcess.push_back(new TwoChanTimingProcessor()); + } else if (name == "IS600Processor") { + vecProcess.push_back(new IS600Processor()); } #ifdef useroot else if (name == "RootProcessor") { diff --git a/Scan/utkscan/experiment/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt index 5b7cd4e8e..899acf265 100644 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ b/Scan/utkscan/experiment/source/CMakeLists.txt @@ -1,4 +1,5 @@ set(EXPERIMENT_SOURCES + IS600Processor.cpp TemplateExpProcessor.cpp TwoChanTimingProcessor.cpp ) diff --git a/Scan/utkscan/experiment/source/IS600Processor.cpp b/Scan/utkscan/experiment/source/IS600Processor.cpp index e405a61a5..dc0205376 100644 --- a/Scan/utkscan/experiment/source/IS600Processor.cpp +++ b/Scan/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"); From a80331887f8a1ae1348a31ede396181494a020f6 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 12:02:34 -0500 Subject: [PATCH 111/255] Removing the E11006Processor since it is not needed This processor is not needed. It was never updated past its initial template stage. This experiment was lead by the U. Warsaw group. If they would like to have this processor added back, they can go through the development cycle. --- .../experiment/include/E11006Processor.hpp | 27 -------- .../experiment/source/E11006Processor.cpp | 69 ------------------- 2 files changed, 96 deletions(-) delete mode 100644 Scan/utkscan/experiment/include/E11006Processor.hpp delete mode 100644 Scan/utkscan/experiment/source/E11006Processor.cpp 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/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; -} From 9e6aced36e8ecb167e1e1912218b0c789366fd65 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 13:04:20 -0500 Subject: [PATCH 112/255] Some Processors require ROOT to function. These files are moved to inside the #ifdefs for root and selectively chosen in the CMakeLists.txt file. --- Scan/utkscan/core/source/DetectorDriver.cpp | 16 ++++++++-------- Scan/utkscan/experiment/source/CMakeLists.txt | 8 ++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index 5de5068c6..7ae4c0804 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -56,12 +56,12 @@ #include "ValidProcessor.hpp" //These headers are for handling experiment specific processing. -#include "IS600Processor.hpp" #include "TemplateExpProcessor.hpp" -#include "TwoChanTimingProcessor.hpp" -#ifdef useroot +#ifdef useroot //Some processors REQURE ROOT to function +#include "IS600Processor.hpp" #include "RootProcessor.hpp" +#include "TwoChanTimingProcessor.hpp" #endif using namespace std; @@ -224,13 +224,13 @@ void DetectorDriver::LoadProcessors(Messenger& m) { vecProcess.push_back(new TemplateProcessor()); } else if (name == "TemplateExpProcessor") { vecProcess.push_back(new TemplateExpProcessor()); - } else if (name == "TwoChanTimingProcessor") { + } +#ifdef useroot //Certain process REQURE root to actually work + else if (name == "TwoChanTimingProcessor") { vecProcess.push_back(new TwoChanTimingProcessor()); } else if (name == "IS600Processor") { vecProcess.push_back(new IS600Processor()); - } -#ifdef useroot - else if (name == "RootProcessor") { + } else if (name == "RootProcessor") { vecProcess.push_back(new RootProcessor("tree.root", "tree")); } #endif @@ -334,7 +334,7 @@ void DetectorDriver::ProcessEvent(RawEvent& rawev) { PlotCal((*it)); string place = (*it)->GetChanID().GetPlaceName(); - if (place == "__-1") + if (place == "__4294967295") continue; if ( (*it)->IsSaturated() || (*it)->IsPileup() ) diff --git a/Scan/utkscan/experiment/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt index 899acf265..d0244a5b2 100644 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ b/Scan/utkscan/experiment/source/CMakeLists.txt @@ -1,7 +1,11 @@ set(EXPERIMENT_SOURCES - IS600Processor.cpp TemplateExpProcessor.cpp - TwoChanTimingProcessor.cpp ) +if(USE_ROOT) +list(APPEND EXPERIMENT_SOURCES + IS600Processor.cpp + TwoChanTimingProcessor.cpp) +endif(USE_ROOT) + add_library(ExperimentObjects OBJECT ${EXPERIMENT_SOURCES}) From 50a7fec039a54ae6ef2d708c3533562e82d32d48 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 13:09:14 -0500 Subject: [PATCH 113/255] Updating Anl1471Processor --- Scan/utkscan/core/source/DetectorDriver.cpp | 5 +- .../experiment/include/Anl1471Processor.hpp | 31 +- .../experiment/source/Anl1471Processor.cpp | 444 +++++++++++++----- Scan/utkscan/experiment/source/CMakeLists.txt | 1 + 4 files changed, 340 insertions(+), 141 deletions(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index 7ae4c0804..b99864a24 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -59,6 +59,7 @@ #include "TemplateExpProcessor.hpp" #ifdef useroot //Some processors REQURE ROOT to function +#include "Anl1471Processor.hpp" #include "IS600Processor.hpp" #include "RootProcessor.hpp" #include "TwoChanTimingProcessor.hpp" @@ -226,7 +227,9 @@ void DetectorDriver::LoadProcessors(Messenger& m) { vecProcess.push_back(new TemplateExpProcessor()); } #ifdef useroot //Certain process REQURE root to actually work - else if (name == "TwoChanTimingProcessor") { + 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()); diff --git a/Scan/utkscan/experiment/include/Anl1471Processor.hpp b/Scan/utkscan/experiment/include/Anl1471Processor.hpp index b88c8bd6d..a402e9c66 100644 --- a/Scan/utkscan/experiment/include/Anl1471Processor.hpp +++ b/Scan/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/source/Anl1471Processor.cpp b/Scan/utkscan/experiment/source/Anl1471Processor.cpp index 368caf7c8..a2809c0d7 100644 --- a/Scan/utkscan/experiment/source/Anl1471Processor.cpp +++ b/Scan/utkscan/experiment/source/Anl1471Processor.cpp @@ -1,157 +1,353 @@ -/** \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 +///@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 #include "BarBuilder.hpp" -#include "DammPlotIds.hpp" -#include "GetArguments.hpp" -#include "Globals.hpp" -#include "RawEvent.hpp" -#include "TimingMapBuilder.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 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 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::vandle; +using namespace dammIds::experiment; 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"); -} + 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(const std::vector &typeList, - const double &res, const double &offset, const double &numStarts) : - VandleProcessor(typeList,res,offset,numStarts) { +Anl1471Processor::Anl1471Processor() : EventProcessor(OFFSET, RANGE, + "Anl1471PRocessor") { associatedTypes.insert("vandle"); + 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; - fileName_ = name.str(); - fileNames_.push_back(fileName_ + "-tof-sm.dat"); - fileNames_.push_back(fileName_ + "-tof-md.dat"); - fileNames_.push_back(fileName_ + "-tof-04Plus.dat"); + 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); - if(!VandleProcessor::Process(event)) - return(false); + return (false); + double plotMult_ = 2; + double plotOffset_ = 1000; - for (BarMap::iterator it = bars_.begin(); it != bars_.end(); it++) { + 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()) + + if (!bar.GetHasEvent()) continue; + if (bar.GetType() == "small") + barType = 0; + else if (bar.GetType() == "medium") + barType = 1; + 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; - + 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; - unsigned int barPlusStartLoc = numStarts_*barLoc+startLoc; - + if (!beta_start.GetHasEvent()) + continue; double tofOffset = cal.GetTofOffset(startLoc); - double tof = bar.GetWalkCorTimeAve() - - start.GetTimeAverage() + tofOffset; + double tof = bar.GetCorTimeAve() - + beta_start.GetCorTimeAve() + 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(); + ((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; } - 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 + 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); -} + return (true); +} \ No newline at end of file diff --git a/Scan/utkscan/experiment/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt index d0244a5b2..f5bdf8bce 100644 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ b/Scan/utkscan/experiment/source/CMakeLists.txt @@ -4,6 +4,7 @@ set(EXPERIMENT_SOURCES if(USE_ROOT) list(APPEND EXPERIMENT_SOURCES + Anl1471Processor.cpp IS600Processor.cpp TwoChanTimingProcessor.cpp) endif(USE_ROOT) From 7d5054ed85852a9f7044b2cdfd8a46a9645b9412 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 14:06:38 -0500 Subject: [PATCH 114/255] Adding VandleOrnl2012Processor. --- Scan/utkscan/core/source/DetectorDriver.cpp | 3 + .../include/VandleAtLeribssProcessor.hpp | 40 ---- .../include/VandleOrnl2012Processor.hpp | 28 +++ Scan/utkscan/experiment/source/CMakeLists.txt | 1 + .../source/VandleAtLeribssProcessor.cpp | 212 ----------------- .../source/VandleOrnl2012Processor.cpp | 221 ++++++++++++++++++ 6 files changed, 253 insertions(+), 252 deletions(-) delete mode 100644 Scan/utkscan/experiment/include/VandleAtLeribssProcessor.hpp create mode 100644 Scan/utkscan/experiment/include/VandleOrnl2012Processor.hpp delete mode 100644 Scan/utkscan/experiment/source/VandleAtLeribssProcessor.cpp create mode 100644 Scan/utkscan/experiment/source/VandleOrnl2012Processor.cpp diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index b99864a24..1b6b7aed4 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -57,6 +57,7 @@ //These headers are for handling experiment specific processing. #include "TemplateExpProcessor.hpp" +#include "VandleOrnl2012Processor.hpp" #ifdef useroot //Some processors REQURE ROOT to function #include "Anl1471Processor.hpp" @@ -233,6 +234,8 @@ void DetectorDriver::LoadProcessors(Messenger& m) { 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")); } 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/include/VandleOrnl2012Processor.hpp b/Scan/utkscan/experiment/include/VandleOrnl2012Processor.hpp new file mode 100644 index 000000000..d3df2f638 --- /dev/null +++ b/Scan/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/source/CMakeLists.txt b/Scan/utkscan/experiment/source/CMakeLists.txt index f5bdf8bce..1eeac03f9 100644 --- a/Scan/utkscan/experiment/source/CMakeLists.txt +++ b/Scan/utkscan/experiment/source/CMakeLists.txt @@ -1,5 +1,6 @@ set(EXPERIMENT_SOURCES TemplateExpProcessor.cpp + VandleOrnl2012Processor.cpp ) if(USE_ROOT) 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/Scan/utkscan/experiment/source/VandleOrnl2012Processor.cpp b/Scan/utkscan/experiment/source/VandleOrnl2012Processor.cpp new file mode 100644 index 000000000..968eb8a57 --- /dev/null +++ b/Scan/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); +} From 90470e4156775ca87a17594bd01da683dc2e1ed7 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 14:09:05 -0500 Subject: [PATCH 115/255] Undesired change snuck into DetectorDriver --- Scan/utkscan/core/source/DetectorDriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index 1b6b7aed4..c90f3aec5 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -340,7 +340,7 @@ void DetectorDriver::ProcessEvent(RawEvent& rawev) { PlotCal((*it)); string place = (*it)->GetChanID().GetPlaceName(); - if (place == "__4294967295") + if (place == "__-1") continue; if ( (*it)->IsSaturated() || (*it)->IsPileup() ) From 5f93d52fd55490391fa26386a5a541ca589474ac Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 15:29:25 -0500 Subject: [PATCH 116/255] Fix to prevent scope from segfaulting. --- Scan/util/source/scope.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scan/util/source/scope.cpp b/Scan/util/source/scope.cpp index b391f5d6b..62122a8ba 100644 --- a/Scan/util/source/scope.cpp +++ b/Scan/util/source/scope.cpp @@ -3,6 +3,7 @@ // PixieCore libraries #include "ChannelEvent.hpp" +#include "HelperFunctions.hpp" #include "XiaData.hpp" // Local files @@ -97,7 +98,9 @@ void scopeUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ } // Pass this event to the correct processor - int maximum = *std::max_element(current_event->GetTrace().begin(), current_event->GetTrace().end()); + 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_) { From 037ad6a4324db6e3f3b74a760405714770f832a9 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 16:35:01 -0500 Subject: [PATCH 117/255] Fixing bug in the Waveform and Fitting Analyzers This bug is probably the cause for the updside down histograms. --- .../analyzers/include/FittingAnalyzer.hpp | 5 ++-- .../analyzers/source/FittingAnalyzer.cpp | 27 +++++------------- .../analyzers/source/WaveformAnalyzer.cpp | 28 ++++++++----------- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp index 5a90a0c13..5decfb50a 100644 --- a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp +++ b/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp @@ -24,14 +24,13 @@ class FittingAnalyzer : public TraceAnalyzer { /** Default Destructor */ ~FittingAnalyzer(); - /** Declare plots for the analyzer */ - virtual void DeclarePlots(void); + /** 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: diff --git a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp index d9a196d87..d37b2c5fc 100644 --- a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp @@ -17,24 +17,10 @@ #include #include -#include - -#include "DammPlotIds.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"; @@ -71,12 +57,13 @@ void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, trace.GetValue("sigmaBaseline")); const pair max(trace.GetValue("maxpos"), trace.GetValue("maxval")); - bool isDblBeta = detType == "beta" && detSubtype == "double"; - bool isDblBetaT = isDblBeta && tagMap.find("timing") != tagMap.end(); - trace.plot(D_SIGMA, baseline.second * 100); + //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 (!isDblBetaT) { + if (!isFastSiPm) { if (baseline.second > globals->sigmaBaselineThresh()) { EndAnalyze(); return; @@ -89,11 +76,11 @@ void FittingAnalyzer::Analyze(Trace &trace, const std::string &detType, } pair pars = globals->fitPars(detType + ":" + detSubtype); - if (isDblBetaT) + if (isFastSiPm) pars = globals->fitPars(detType + ":" + detSubtype + ":timing"); driver_->SetQdc(trace.GetValue("qdc")); - double phase = driver_->CalculatePhase(trace.GetWaveformWithBaseline(), + double phase = driver_->CalculatePhase(trace.GetWaveform(), pars, max, baseline); trace.InsertValue("phase", phase + max.first); diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index d7a3b55a5..0bafeded6 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -37,6 +37,7 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, pair range = globals->waveformRange(type + ":" + subtype); + if (type == "beta" && subtype == "double" && tags.find("timing") != tags.end()) range = globals->waveformRange(type + ":" + subtype + ":timing"); @@ -46,7 +47,7 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, pair max = TraceFunctions::FindMaximum(trace, globals->traceDelay() / (globals->adcClockInSeconds() * - 1e9)); + 1.e9)); //If the max value is a saturation we mark it here. if (max.second >= globals->bitResolution()) @@ -54,9 +55,9 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, //Next we calculate the baseline and its standard deviation pair baseline = - TraceFunctions::CalculateBaseline(trace, make_pair(0, - max.first - - range.first)); + 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); @@ -64,12 +65,9 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, //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) - - (waveformRange.second - waveformRange.first) * - baseline.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); @@ -77,16 +75,12 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, 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); + TraceFunctions::ExtrapolateMaximum(traceNoBaseline, max).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 From db35155547c20f88ccc7b94181b560679d73a4a7 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 10:59:36 -0500 Subject: [PATCH 118/255] Fixing issue #168 --- Scan/utkscan/core/include/Identifier.hpp | 58 ++++++++++++------------ Scan/utkscan/core/source/Identifier.cpp | 30 ++++++------ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Scan/utkscan/core/include/Identifier.hpp b/Scan/utkscan/core/include/Identifier.hpp index 960e3ae2c..6fe4f01c7 100644 --- a/Scan/utkscan/core/include/Identifier.hpp +++ b/Scan/utkscan/core/include/Identifier.hpp @@ -37,43 +37,43 @@ class Identifier { * \param [in] loc : the location to set */ Identifier(const std::string &atype, const std::string &subType, const unsigned int &loc) { - type = atype; - subtype = subType; - location = loc; + type_ = atype; + subtype_ = subType; + location_ = loc; } /** Sets the DAMM ID * \param [in] a : the id to set */ - void SetDammID(unsigned 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(const unsigned int &a) {location = a;} + void SetLocation(const unsigned int &a) {location_ = a;} ///@return The value of the private variable dammID - unsigned int GetDammID() const {return dammID;} + unsigned int GetDammID() const {return dammID_;} ///@return The value of the private variable type - const std::string& GetType() const {return type;} + const std::string& GetType() const {return type_;} ///@return the value of the private variable subtype - const std::string& GetSubtype() const {return subtype;} + const std::string& GetSubtype() const {return subtype_;} ///@return The value of the private variable location - unsigned int GetLocation() const {return 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);} @@ -82,7 +82,7 @@ class Identifier { 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 * @@ -99,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 @@ -115,17 +115,17 @@ 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_); } } } @@ -139,16 +139,18 @@ class Identifier { /** \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 */ - unsigned int dammID; /**< Damm spectrum number for plotting + 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. + 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/source/Identifier.cpp b/Scan/utkscan/core/source/Identifier.cpp index 7c5b99611..7235cfb31 100644 --- a/Scan/utkscan/core/source/Identifier.cpp +++ b/Scan/utkscan/core/source/Identifier.cpp @@ -9,22 +9,20 @@ 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; } From 04e40a42f5c6ee8a226a04aec68fe779472ca91a Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 13 Jan 2017 11:13:28 -0500 Subject: [PATCH 119/255] Actually fixing #168 Forgot to commit DetectorDriver --- Scan/utkscan/core/source/DetectorDriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index c90f3aec5..a5157202a 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -340,7 +340,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() ) From a3b9ca890bfafc56bc138772cc8f2948748ba75f Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Thu, 19 Jan 2017 16:36:21 -0500 Subject: [PATCH 120/255] Closes #181 --- share/plx/systemd/plx.service | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/plx/systemd/plx.service b/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] From e71ff3a8a0f7dddb121a8c69565af7b1420aef2d Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 11:31:04 -0500 Subject: [PATCH 121/255] Resolves #186 --- Scan/Resources/include/HelperFunctions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Scan/Resources/include/HelperFunctions.hpp index 96e8a4a9b..e2e0d1a4b 100644 --- a/Scan/Resources/include/HelperFunctions.hpp +++ b/Scan/Resources/include/HelperFunctions.hpp @@ -237,7 +237,7 @@ namespace TraceFunctions { if (range.second - range.first < minimum_baseline_length) throw range_error("TraceFunctions::ComputeBaseline - The range " - "specified is smaller than the minumum" + "specified is smaller than the minimum" " necessary range."); double baseline = Statistics::CalculateAverage( From cdc4749683f2b9cd4ae57f9bc2117baabd6a85ae Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 16 Jan 2017 21:09:14 -0500 Subject: [PATCH 122/255] Fixing error on the extrapolated maximum --- Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp index 0bafeded6..67c2bcb70 100644 --- a/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp +++ b/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp @@ -75,7 +75,8 @@ void WaveformAnalyzer::Analyze(Trace &trace, const std::string &type, trace.InsertValue("sigmaBaseline", baseline.second); trace.InsertValue("maxval", max.second - baseline.first); trace.InsertValue("extrapolatedMaxVal", - TraceFunctions::ExtrapolateMaximum(traceNoBaseline, max).first); + TraceFunctions::ExtrapolateMaximum(trace, max) + .first - baseline.first); trace.InsertValue("maxpos", (int)max.first); trace.SetBaselineSubtractedTrace(traceNoBaseline); trace.SetWaveformRange(waveformRange); From d7a658acd1ec83924d2fe0a456bf9b4c31031ba4 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 13:59:23 -0500 Subject: [PATCH 123/255] Resolves #191 - Skeleton failes to compile with HRIBF Libs This was broken when XiaData was overhauled, and was not caught due to the #ifdefs. --- Scan/util/source/Skeleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/util/source/Skeleton.cpp b/Scan/util/source/Skeleton.cpp index b8fe2f9ba..7541cf0ea 100644 --- a/Scan/util/source/Skeleton.cpp +++ b/Scan/util/source/Skeleton.cpp @@ -39,7 +39,7 @@ void skeletonUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ #ifdef USE_HRIBF // If using scanor, output to the generic histogram so we know that something is happening. - count1cc_(8000, (current_event->modNum*16+current_event->chanNum), 1); + count1cc_(8000, (current_event->GetId()), 1); #endif // Check that this channel event exists. From 9137571f2e746686b5fdec85a27eeaab70e14b66 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 25 Jan 2017 09:27:32 -0500 Subject: [PATCH 124/255] Fixes #120 We now check during initialization that the output file name has been provided to the scan code. These values are initialized to an empty string in the ScanInterface to facilitate this check. --- Scan/ScanLib/source/ScanInterface.cpp | 4 ++++ Scan/utkscan/core/source/UtkScanInterface.cpp | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp index 4ac6b951c..7a3784c3c 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -386,6 +386,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; diff --git a/Scan/utkscan/core/source/UtkScanInterface.cpp b/Scan/utkscan/core/source/UtkScanInterface.cpp index af1c4b414..3664f6f29 100644 --- a/Scan/utkscan/core/source/UtkScanInterface.cpp +++ b/Scan/utkscan/core/source/UtkScanInterface.cpp @@ -1,4 +1,7 @@ +#include + #include "DetectorDriver.hpp" +#include "Display.h" #include "UtkScanInterface.hpp" #include "UtkUnpacker.hpp" @@ -71,7 +74,11 @@ 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); @@ -91,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); From e821d258a44c5e8a8d46ec7a7177aa781bd249fc Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 25 Jan 2017 08:50:40 -0500 Subject: [PATCH 125/255] Wrapping the TreeCorrelator calls in try/catches. --- .../utkscan/processors/source/GeProcessor.cpp | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Scan/utkscan/processors/source/GeProcessor.cpp b/Scan/utkscan/processors/source/GeProcessor.cpp index 0cb5f42fb..1be841b62 100644 --- a/Scan/utkscan/processors/source/GeProcessor.cpp +++ b/Scan/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; @@ -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 From 3ae7e732d4fb386711a138bf9e5a68ab0bf0103d Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 25 Jan 2017 07:11:40 -0500 Subject: [PATCH 126/255] Replacing exits with throws until we get back up to main I have replaced the exits that occur during the exceptions with throw. This will throw the errorup until it reaches main, where we handle exiting cleanly by returning. This fixes the issue where the terminal would get corrupted. --- Scan/utkscan/CMakeLists.txt | 3 ++- Scan/utkscan/core/source/DetectorDriver.cpp | 23 +++++++++++-------- Scan/utkscan/core/source/UtkUnpacker.cpp | 25 ++++++++++++--------- Scan/utkscan/core/source/utkscan.cpp | 9 +++++++- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/Scan/utkscan/CMakeLists.txt b/Scan/utkscan/CMakeLists.txt index e219d1c46..35a82c207 100644 --- a/Scan/utkscan/CMakeLists.txt +++ b/Scan/utkscan/CMakeLists.txt @@ -70,7 +70,8 @@ else(USE_HRIBF) endif(NOT USE_HRIBF) #Add libraries to be linked with utkscan -target_link_libraries(${SCAN_NAME} ${LIBS} ScanStatic ResourceStatic) +target_link_libraries(${SCAN_NAME} ${LIBS} ScanStatic ResourceStatic + PixieCoreStatic) #If we have GSL installed link if(USE_GSL) diff --git a/Scan/utkscan/core/source/DetectorDriver.cpp b/Scan/utkscan/core/source/DetectorDriver.cpp index a5157202a..406c9377d 100644 --- a/Scan/utkscan/core/source/DetectorDriver.cpp +++ b/Scan/utkscan/core/source/DetectorDriver.cpp @@ -20,6 +20,7 @@ #include "DammPlotIds.hpp" #include "DetectorDriver.hpp" #include "DetectorLibrary.hpp" +#include "Display.h" #include "Exceptions.hpp" #include "HighResTimingData.hpp" #include "RandomPool.hpp" @@ -90,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; @@ -375,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; } } @@ -446,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/UtkUnpacker.cpp b/Scan/utkscan/core/source/UtkUnpacker.cpp index bd57fbcc6..1fd7aaf07 100644 --- a/Scan/utkscan/core/source/UtkUnpacker.cpp +++ b/Scan/utkscan/core/source/UtkUnpacker.cpp @@ -112,19 +112,24 @@ void UtkUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/) { ///@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 diff --git a/Scan/utkscan/core/source/utkscan.cpp b/Scan/utkscan/core/source/utkscan.cpp index 0b9fc54ae..d3ea3698f 100644 --- a/Scan/utkscan/core/source/utkscan.cpp +++ b/Scan/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; From 4d6b07cfa066eafcc224c8104d07cd2c6055a3f3 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 18 Jan 2017 13:54:13 -0500 Subject: [PATCH 127/255] ConvertStringToFirmware now tests against ranges The users no longer have to have the exact firmware number. If they have a number that's inbetween major revisions then they can simply input that number and the correct firmware header revision will be found. --- Scan/ScanLib/include/XiaListModeDataMask.hpp | 22 +++++++++++--- Scan/ScanLib/source/XiaListModeDataMask.cpp | 25 +++++++++++----- .../tests/unittest-XiaListModeDataMask.cpp | 30 +++++++++++++++++++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index 4e58bd512..6c9ecda33 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -25,7 +25,7 @@ class XiaListModeDataMask { firmware_ = DataProcessing::UNKNOWN; } - ///Constructor accepting a string with the firmware type and the frequency + ///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. @@ -35,6 +35,16 @@ class XiaListModeDataMask { 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() {}; @@ -123,7 +133,7 @@ class XiaListModeDataMask { ///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_; } + unsigned int GetFrequency() const { return frequency_; } ///Sets the firmware version ///@param[in] firmware : The firmware type that we would like to set. @@ -143,6 +153,12 @@ class XiaListModeDataMask { /// 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. @@ -151,8 +167,6 @@ class XiaListModeDataMask { unsigned int frequency_; std::string BadMaskErrorMessage(const std::string &func) const; - - DataProcessing::FIRMWARE ConvertStringToFirmware(const std::string &type); }; #endif //PIXIESUITE_XIALISTMODEDATAMASK_HPP diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 1fbd2b6ff..095a02249 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -2,8 +2,10 @@ /// @brief Class that provides the data masks for XIA list mode data /// @author S. V. Paulauskas /// @date December 29, 2016 +#include #include -#include + +#include #include "XiaListModeDataMask.hpp" @@ -12,16 +14,25 @@ using namespace DataProcessing; FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { FIRMWARE firmware = UNKNOWN; + unsigned int firmwareNumber = 0; stringstream msg; - if (type == "R29432") + + //First convert the string into a number + if (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 >= 29432 && firmwareNumber < 30474) firmware = R29432; - else if (type == "R30474") + else if(firmwareNumber >= 30474 && firmwareNumber < 30980) firmware = R30474; - else if (type == "R30980") + else if(firmwareNumber >= 30980 && firmwareNumber < 30981) firmware = R30980; - else if (type == "R30981") + else if(firmwareNumber >= 30981 && firmwareNumber < 34688) firmware = R30981; - else if (type == "R34688") + else if(firmwareNumber == 34688) //compare exactly here since nothing higher firmware = R34688; else { msg << "XiaListModeDataMask::CovnertStringToFirmware : " @@ -250,7 +261,7 @@ double XiaListModeDataMask::GetCfdSize() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage ("GetCfdFractionalTimeMask")); - if(frequency_ == 500) + if (frequency_ == 500) return 8192.; double val = 0; diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index a824f5ebe..581fb52cc 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -13,6 +13,36 @@ 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(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(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. From e474a079c4c9b89e15793ebc4e956a66848ba22c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 12:56:11 -0500 Subject: [PATCH 128/255] Adding new firmwares to the enumeration --- Scan/Resources/include/HelperEnumerations.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Scan/Resources/include/HelperEnumerations.hpp b/Scan/Resources/include/HelperEnumerations.hpp index 855675188..a0ecc0be9 100644 --- a/Scan/Resources/include/HelperEnumerations.hpp +++ b/Scan/Resources/include/HelperEnumerations.hpp @@ -19,8 +19,12 @@ namespace Timing { namespace DataProcessing { ///An enum for the different firmware revisions for the Pixie-16 modules. - /// * R29432 is valid from 02/15/2014 and 07/28/2014 - /// * R30474, R30980, R30981 is valid from 07/28/2014 and 03/08/2016 + /// * 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 @@ -28,7 +32,7 @@ namespace DataProcessing { /// guide the user if they do not know the particular firmware that was used /// to obtain their data set. enum FIRMWARE { - R29432, R30474, R30980, R30981, R34688, UNKNOWN + R17562, R20466, R27361, R29432, R30474, R30980, R30981, R34688, UNKNOWN }; ///An enumeration that tells how long headers from the XIA List mode data From 896d2a8f3d6dcacb3cea6620f2b925ba6c88bd07 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 13:43:53 -0500 Subject: [PATCH 129/255] Updating the XiListModeDataMask to handle older firmwares. --- Scan/ScanLib/include/XiaListModeDataMask.hpp | 18 ++- Scan/ScanLib/source/XiaListModeDataMask.cpp | 110 +++++++++++++----- .../tests/unittest-XiaListModeDataMask.cpp | 17 ++- 3 files changed, 101 insertions(+), 44 deletions(-) diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Scan/ScanLib/include/XiaListModeDataMask.hpp index 6c9ecda33..99240464c 100644 --- a/Scan/ScanLib/include/XiaListModeDataMask.hpp +++ b/Scan/ScanLib/include/XiaListModeDataMask.hpp @@ -46,49 +46,47 @@ class XiaListModeDataMask { } ///Default Destructor - ~XiaListModeDataMask() {}; + ~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 { - return std::make_pair(0x1FFE0000, 17); - }; + 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. diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 095a02249..1d22a2219 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -5,8 +5,6 @@ #include #include -#include - #include "XiaListModeDataMask.hpp" using namespace std; @@ -19,20 +17,27 @@ FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { //First convert the string into a number if (type.find("R") == 0) { - string tmp(type.begin() +1, type.end()); - firmwareNumber = (unsigned int)atoi(tmp.c_str()); + string tmp(type.begin() + 1, type.end()); + firmwareNumber = (unsigned int) atoi(tmp.c_str()); } else - firmwareNumber = (unsigned int)atoi(type.c_str()); + firmwareNumber = (unsigned int) atoi(type.c_str()); - if(firmwareNumber >= 29432 && firmwareNumber < 30474) + 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) + else if (firmwareNumber >= 30474 && firmwareNumber < 30980) firmware = R30474; - else if(firmwareNumber >= 30980 && firmwareNumber < 30981) + else if (firmwareNumber >= 30980 && firmwareNumber < 30981) firmware = R30980; - else if(firmwareNumber >= 30981 && firmwareNumber < 34688) + else if (firmwareNumber >= 30981 && firmwareNumber < 34688) firmware = R30981; - else if(firmwareNumber == 34688) //compare exactly here since nothing higher + else if (firmwareNumber == + 34688) //compare exactly here since nothing higher firmware = R34688; else { msg << "XiaListModeDataMask::CovnertStringToFirmware : " @@ -52,6 +57,7 @@ XiaListModeDataMask::GetCfdFractionalTimeMask() const { unsigned int mask = 0; if (frequency_ == 100) { switch (firmware_) { + case R17562: case R29432: mask = 0xFFFF0000; break; @@ -61,11 +67,15 @@ XiaListModeDataMask::GetCfdFractionalTimeMask() const { case R34688: mask = 0x7FFF0000; break; - case UNKNOWN: + default: break; } } else if (frequency_ == 250) { switch (firmware_) { + case R20466: + mask = 0xFFFF0000; + break; + case R27361: case R29432: mask = 0x7FFF0000; break; @@ -75,7 +85,7 @@ XiaListModeDataMask::GetCfdFractionalTimeMask() const { case R34688: mask = 0x3FFF0000; break; - case UNKNOWN: + default: break; } } else if (frequency_ == 500) { @@ -87,26 +97,49 @@ XiaListModeDataMask::GetCfdFractionalTimeMask() const { case R34688: mask = 0x1FFF0000; break; - case UNKNOWN: + 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 = 0x1FFE0000; + bit = 17; + break; + default: + break; + } + return make_pair(mask, bit); +} + pair XiaListModeDataMask::GetCfdForcedTriggerBitMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("GetCfdForcedTriggerBitMask")); unsigned int mask = 0; unsigned int bit = 0; if (frequency_ == 100) { switch (firmware_) { - case R29432: - mask = 0; - bit = 0; - break; case R30474: case R30980: case R30981: @@ -114,7 +147,7 @@ XiaListModeDataMask::GetCfdForcedTriggerBitMask() const { mask = 0x80000000; bit = 31; break; - case UNKNOWN: + default: break; } } else if (frequency_ == 250) { @@ -126,8 +159,7 @@ XiaListModeDataMask::GetCfdForcedTriggerBitMask() const { mask = 0x80000000; bit = 31; break; - case R29432: - case UNKNOWN: + default: break; } } @@ -138,11 +170,12 @@ pair XiaListModeDataMask::GetCfdTriggerSourceMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("GetCfdTriggerSourceMask")); unsigned int mask = 0; unsigned int bit = 0; if (frequency_ == 250) { switch (firmware_) { + case R27361: case R29432: mask = 0x80000000; bit = 31; @@ -154,7 +187,7 @@ XiaListModeDataMask::GetCfdTriggerSourceMask() const { mask = 0x40000000; bit = 30; break; - case UNKNOWN: + default: break; } } else if (frequency_ == 500) { @@ -167,7 +200,7 @@ XiaListModeDataMask::GetCfdTriggerSourceMask() const { mask = 0xE0000000; bit = 29; break; - case UNKNOWN: + default: break; } } @@ -189,10 +222,13 @@ const { case R30981: mask = 0x00007FFF; break; + case R17562: + case R20466: + case R27361: case R34688: mask = 0x0000FFFF; break; - case UNKNOWN: + default: break; } return make_pair(mask, 0); @@ -204,11 +240,17 @@ pair XiaListModeDataMask::GetTraceOutOfRangeFlagMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("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: @@ -220,7 +262,7 @@ XiaListModeDataMask::GetTraceOutOfRangeFlagMask() const { mask = 0x80000000; bit = 31; break; - case UNKNOWN: + default: break; } return make_pair(mask, bit); @@ -234,6 +276,9 @@ const { ("GetCfdFractionalTimeMask")); unsigned int mask = 0; switch (firmware_) { + case R17562: + case R20466: + case R27361: case R29432: case R30474: case R30980: @@ -243,7 +288,7 @@ const { case R34688: mask = 0x7FFF0000; break; - case UNKNOWN: + default: break; } return make_pair(mask, 16); @@ -267,6 +312,7 @@ double XiaListModeDataMask::GetCfdSize() const { double val = 0; if (frequency_ == 100) { switch (firmware_) { + case R17562: case R29432: val = 65536; break; @@ -276,11 +322,15 @@ double XiaListModeDataMask::GetCfdSize() const { case R34688: val = 32768; break; - case UNKNOWN: + default: break; } } else if (frequency_ == 250) { switch (firmware_) { + case R20466: + val = 65536; + break; + case R27361: case R29432: val = 32768; break; @@ -290,7 +340,7 @@ double XiaListModeDataMask::GetCfdSize() const { case R30474: val = 16384; break; - case UNKNOWN: + default: break; } } diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp index 581fb52cc..04ae447b5 100644 --- a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp +++ b/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp @@ -16,6 +16,15 @@ 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")); @@ -27,11 +36,14 @@ TEST_FIXTURE(XiaListModeDataMask, TestConvertStringToFirmware) { 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")); @@ -59,9 +71,6 @@ TEST_FIXTURE(XiaListModeDataMask, TestXiaListModeDataMask) { CHECK_EQUAL((unsigned int) 0x0001F000, GetHeaderLengthMask().first); CHECK_EQUAL((unsigned int) 12, GetHeaderLengthMask().second); - CHECK_EQUAL((unsigned int) 0x1FFE0000, GetEventLengthMask().first); - CHECK_EQUAL((unsigned int) 17, GetEventLengthMask().second); - CHECK_EQUAL((unsigned int) 0x80000000, GetFinishCodeMask().first); CHECK_EQUAL((unsigned int) 31, GetFinishCodeMask().second); From 56e9d7c60bd0ada7a5131ae51eb848c014822a91 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 13:45:32 -0500 Subject: [PATCH 130/255] Adding additional logic since older firmwares are less consistent. Older firmwares store the Trace-Out-of-Range Flag in Word 0 instead of Word 3. I had to add some additional logic to handle these firmwares. --- .../ScanLib/source/XiaListModeDataDecoder.cpp | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp index 8d7a5283c..90d591d25 100644 --- a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp +++ b/Scan/ScanLib/source/XiaListModeDataDecoder.cpp @@ -171,6 +171,20 @@ std::pair XiaListModeDataDecoder::DecodeWordZero( >> 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) @@ -195,7 +209,21 @@ unsigned int XiaListModeDataDecoder::DecodeWordThree( const unsigned int &word, XiaData &data, const XiaListModeDataMask &mask) { data.SetEnergy(word & mask.GetEventEnergyMask().first); - data.SetSaturation((bool) (word & mask.GetTraceOutOfRangeFlagMask().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); From 0623e197bb445a4486e22778318aa057b83c192f Mon Sep 17 00:00:00 2001 From: "S. Z. Taylor" Date: Tue, 24 Jan 2017 10:49:38 -0500 Subject: [PATCH 131/255] Added stdexcept to XiaListModeDataMask.cpp. --- Scan/ScanLib/source/XiaListModeDataMask.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 1d22a2219..b8a83b0db 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -4,6 +4,7 @@ /// @date December 29, 2016 #include #include +#include #include "XiaListModeDataMask.hpp" @@ -346,4 +347,4 @@ double XiaListModeDataMask::GetCfdSize() const { } return val; -} \ No newline at end of file +} From 3a5556058177ec185953d5efe3951db91246eef5 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 25 Jan 2017 06:30:20 -0500 Subject: [PATCH 132/255] Fixes bad mask, and updates names for error messages This addresses issues found by @ksmith0 during the review process. --- Scan/ScanLib/source/XiaListModeDataMask.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index b8a83b0db..6e7a5f445 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -123,7 +123,7 @@ const { case R30980: case R30981: case R34688: - mask = 0x1FFE0000; + mask = 0x7FFE0000; bit = 17; break; default: @@ -214,7 +214,7 @@ pair XiaListModeDataMask::GetEventEnergyMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("GetEventEnergyMask")); unsigned int mask = 0; switch (firmware_) { case R29432: @@ -274,7 +274,7 @@ pair XiaListModeDataMask::GetTraceLengthMask() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("GetTraceLengthMask")); unsigned int mask = 0; switch (firmware_) { case R17562: @@ -306,7 +306,7 @@ string XiaListModeDataMask::BadMaskErrorMessage(const std::string &func) const { double XiaListModeDataMask::GetCfdSize() const { if (firmware_ == UNKNOWN || frequency_ == 0) throw invalid_argument(BadMaskErrorMessage - ("GetCfdFractionalTimeMask")); + ("GetCfdSize")); if (frequency_ == 500) return 8192.; From 473844ceff9d6053092e12b87aa7078210e2ddf3 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 25 Jan 2017 09:34:32 -0500 Subject: [PATCH 133/255] Allows the use of r in the firmware string --- Scan/ScanLib/source/XiaListModeDataMask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Scan/ScanLib/source/XiaListModeDataMask.cpp index 6e7a5f445..309b22254 100644 --- a/Scan/ScanLib/source/XiaListModeDataMask.cpp +++ b/Scan/ScanLib/source/XiaListModeDataMask.cpp @@ -17,7 +17,7 @@ FIRMWARE XiaListModeDataMask::ConvertStringToFirmware(const std::string &type) { stringstream msg; //First convert the string into a number - if (type.find("R") == 0) { + if (type.find("R") == 0 || type.find("r") == 0) { string tmp(type.begin() + 1, type.end()); firmwareNumber = (unsigned int) atoi(tmp.c_str()); } else From 62170fd490eeb093b319d021da3b854a8cc85867 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 11:08:03 -0500 Subject: [PATCH 134/255] Fixes #184 --- Scan/ScanLib/source/ScanInterface.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp index 7a3784c3c..fecb384aa 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -957,8 +958,15 @@ bool ScanInterface::Setup(int argc, char *argv[]){ //Initialize the data mask for decoding the data ///@TODO We need to be able to handle mixed systems, which is not /// implemented yet. - std::cout << firmware << " " << samplingFrequency << std::endl; - core->InitializeDataMask(firmware, samplingFrequency); + 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(); From 4eabf6ab659a5f8422a5f60c13f619d617915bf5 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Mon, 30 Jan 2017 16:13:36 -0500 Subject: [PATCH 135/255] Moved INSTALL_PREFIX definition. This allows faster recompile times as less objects are set as dependent on this compiler defintion. --- CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88fb51fa0..d6021e156 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,11 +64,6 @@ 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 #The MCA will write DAMM histograms as output @@ -155,6 +150,9 @@ add_subdirectory(Scan) #Building polling tools if (BUILD_SUITE) + #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) From d74925fba92f343a991f46de63639829631f1d08 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 31 Jan 2017 08:39:52 -0500 Subject: [PATCH 136/255] Massive overhaul to directory structure. We needed to overhaul the directory structure so that we could start implementing changes that could be seen by all of the software and not jus a subset. In addition, the analysis software (Scan) all lived in its own directory, where as the Acquisition (Poll, MCA, etc) all lived in the base directory. Simplification of the structure means that the users will have an easier time finding the information that they need. --- {Interface => Acquisition/Interface}/include/Lock.h | 0 .../Interface}/include/PixieInterface.h | 0 .../Interface}/include/PixieSupport.h | 0 .../Interface}/include/Utility.h | 0 .../Interface}/source/CMakeLists.txt | 0 .../Interface}/source/Lock.cpp | 0 .../Interface}/source/PixieInterface.cpp | 0 .../Interface}/source/PixieSupport.cpp | 0 .../Interface}/source/Utility.cpp | 0 .../Interface}/source/test.cpp | 0 {MCA => Acquisition/MCA}/CMakeLists.txt | 0 {MCA => Acquisition/MCA}/include/DrrBlock.h | 0 {MCA => Acquisition/MCA}/include/Exceptions.h | 0 {MCA => Acquisition/MCA}/include/HisDrr.h | 0 {MCA => Acquisition/MCA}/include/MCA.h | 0 {MCA => Acquisition/MCA}/include/MCA_DAMM.h | 0 {MCA => Acquisition/MCA}/include/MCA_ROOT.h | 0 {MCA => Acquisition/MCA}/share/mca_input.txt | 0 {MCA => Acquisition/MCA}/source/CMakeLists.txt | 0 {MCA => Acquisition/MCA}/source/HisDrr.cpp | 0 {MCA => Acquisition/MCA}/source/MCA.cpp | 0 {MCA => Acquisition/MCA}/source/MCA_DAMM.cpp | 0 {MCA => Acquisition/MCA}/source/MCA_ROOT.cpp | 0 {MCA => Acquisition/MCA}/source/MCA_exec.cpp | 0 {Poll => Acquisition/Poll}/CMakeLists.txt | 0 {Poll => Acquisition/Poll}/include/poll2_core.h | 0 {Poll => Acquisition/Poll}/include/poll2_stats.h | 0 {Poll => Acquisition/Poll}/monitor.bash | 0 {Poll => Acquisition/Poll}/send_alarm | 0 {Poll => Acquisition/Poll}/source/CMakeLists.txt | 0 {Poll => Acquisition/Poll}/source/listener.cpp | 0 {Poll => Acquisition/Poll}/source/monitor.cpp | 0 {Poll => Acquisition/Poll}/source/poll2.cpp | 0 {Poll => Acquisition/Poll}/source/poll2_core.cpp | 0 {Poll => Acquisition/Poll}/source/poll2_stats.cpp | 0 {PxiDump => Acquisition/PxiDump}/CMakeLists.txt | 0 .../PxiDump}/include/set2root.hpp | 0 .../PxiDump}/source/CMakeLists.txt | 0 .../PxiDump}/source/set2root.cpp | 0 {Setup => Acquisition/Setup}/CMakeLists.txt | 0 {Setup => Acquisition/Setup}/Traces/CMakeLists.txt | 0 .../Setup}/Traces/share/traces/plotTraces_ch | 0 .../Setup}/Traces/share/traces/plotTraces_mod | 0 .../Setup}/Traces/share/traces/tra | 0 .../Setup}/Traces/source/viewBaseline.sh | 0 {Setup => Acquisition/Setup}/include/utilities.h | 0 {Setup => Acquisition/Setup}/source/CMakeLists.txt | 0 .../Setup}/source/adjust_offsets.cpp | 0 {Setup => Acquisition/Setup}/source/boot.cpp | 0 {Setup => Acquisition/Setup}/source/copy_params.cpp | 0 {Setup => Acquisition/Setup}/source/csr_test.cpp | 0 {Setup => Acquisition/Setup}/source/find_tau.cpp | 0 {Setup => Acquisition/Setup}/source/get_traces.cpp | 0 .../Setup}/source/input_whole_crate.txt | 0 {Setup => Acquisition/Setup}/source/mca_paw.cpp | 0 {Setup => Acquisition/Setup}/source/paramScan.cpp | 0 {Setup => Acquisition/Setup}/source/pmread.cpp | 0 {Setup => Acquisition/Setup}/source/pmwrite.cpp | 0 {Setup => Acquisition/Setup}/source/pread.cpp | 0 {Setup => Acquisition/Setup}/source/pwrite.cpp | 0 {Setup => Acquisition/Setup}/source/rate.cpp | 0 {Setup => Acquisition/Setup}/source/set_hybrid.cpp | 0 .../Setup}/source/set_pileups_only.cpp | 0 .../Setup}/source/set_pileups_reject.cpp | 0 .../Setup}/source/set_standard.cpp | 0 {Setup => Acquisition/Setup}/source/toggle.cpp | 0 .../Setup}/source/toggle_catcher.cpp | 0 {Setup => Acquisition/Setup}/source/toggle_gain.cpp | 0 {Setup => Acquisition/Setup}/source/toggle_good.cpp | 0 .../Setup}/source/toggle_pileup.cpp | 0 .../Setup}/source/toggle_polarity.cpp | 0 .../Setup}/source/toggle_trace.cpp | 0 {Setup => Acquisition/Setup}/source/trace.cpp | 0 {Setup => Acquisition/Setup}/source/trace_paw.cpp | 0 {Scan => Analysis}/CMakeLists.txt | 0 {Scan => Analysis}/Resources/CMakeLists.txt | 0 {Scan => Analysis}/Resources/include/GslFitter.hpp | 0 .../Resources/include/HelperEnumerations.hpp | 0 .../Resources/include/HelperFunctions.hpp | 0 .../Resources/include/PolynomialCfd.hpp | 0 {Scan => Analysis}/Resources/include/RootFitter.hpp | 0 .../Resources/include/TimingDriver.hpp | 0 .../Resources/include/TraditionalCfd.hpp | 0 .../Resources/include/UnitTestSampleData.hpp | 0 .../Resources/include/VandleTimingFunction.hpp | 0 {Scan => Analysis}/Resources/include/XiaCfd.hpp | 0 {Scan => Analysis}/Resources/source/CMakeLists.txt | 0 {Scan => Analysis}/Resources/source/Gsl1Fitter.cpp | 0 {Scan => Analysis}/Resources/source/Gsl2Fitter.cpp | 0 .../Resources/source/PolynomialCfd.cpp | 0 {Scan => Analysis}/Resources/source/RootFitter.cpp | 0 .../Resources/source/TraditionalCfd.cpp | 0 .../Resources/source/VandleTimingFunction.cpp | 0 {Scan => Analysis}/Resources/source/XiaCfd.cpp | 0 {Scan => Analysis}/Resources/tests/CMakeLists.txt | 0 .../Resources/tests/unittest-GslFitter.cpp | 0 .../Resources/tests/unittest-HelperFunctions.cpp | 0 .../Resources/tests/unittest-PolynomialCfd.cpp | 0 .../Resources/tests/unittest-RootFitter.cpp | 0 .../Resources/tests/unittest-TraditionalCfd.cpp | 0 .../ScanLibraries}/CMakeLists.txt | 0 .../ScanLibraries}/include/ChannelData.hpp | 0 .../ScanLibraries}/include/ChannelEvent.hpp | 0 .../ScanLibraries}/include/RootScanner.hpp | 0 .../ScanLibraries}/include/ScanInterface.hpp | 0 .../ScanLibraries}/include/Unpacker.hpp | 0 .../ScanLibraries}/include/XiaData.hpp | 0 .../include/XiaListModeDataDecoder.hpp | 0 .../include/XiaListModeDataEncoder.hpp | 0 .../ScanLibraries}/include/XiaListModeDataMask.hpp | 0 .../ScanLibraries}/source/CMakeLists.txt | 0 .../ScanLibraries}/source/ChannelData.cpp | 0 .../ScanLibraries}/source/ChannelEvent.cpp | 0 .../ScanLibraries}/source/RootScanner.cpp | 0 .../ScanLibraries}/source/ScanInterface.cpp | 0 .../ScanLibraries}/source/Unpacker.cpp | 0 .../ScanLibraries}/source/XiaData.cpp | 0 .../source/XiaListModeDataDecoder.cpp | 0 .../source/XiaListModeDataEncoder.cpp | 0 .../ScanLibraries}/source/XiaListModeDataMask.cpp | 0 .../ScanLibraries}/tests/CMakeLists.txt | 0 .../ScanLibraries}/tests/unittest-XiaData.cpp | 0 .../tests/unittest-XiaListModeDataDecoder.cpp | 0 .../tests/unittest-XiaListModeDataEncoder.cpp | 0 .../tests/unittest-XiaListModeDataMask.cpp | 0 {Scan/scanor => Analysis/Scanor}/CMakeLists.txt | 0 .../Scanor}/include/GetArguments.hpp | 0 {Scan/scanor => Analysis/Scanor}/include/Scanor.hpp | 0 .../Scanor}/include/ScanorInterface.hpp | 0 .../Scanor}/source/CMakeLists.txt | 0 .../Scanor}/source/GetArguments.cpp | 0 {Scan/scanor => Analysis/Scanor}/source/Scanor.cpp | 0 .../Scanor}/source/ScanorInterface.cpp | 0 {Scan/scanor => Analysis/Scanor}/source/messlog.f | 0 {Scan/scanor => Analysis/Scanor}/source/mildatim.f | 0 {Scan/scanor => Analysis/Scanor}/source/scanof.f | 0 {Scan/scanor => Analysis/Scanor}/source/scanor.f | 0 {Scan/scanor => Analysis/Scanor}/source/scanorux.f | 0 {Scan/scanor => Analysis/Scanor}/source/set2cc.f | 0 {Scan/util => Analysis/Utilities}/CMakeLists.txt | 0 .../Utilities}/include/Skeleton.hpp | 0 .../Utilities}/include/filterer.hpp | 0 {Scan/util => Analysis/Utilities}/include/scope.hpp | 0 .../Utilities}/source/CMakeLists.txt | 0 .../util => Analysis/Utilities}/source/Skeleton.cpp | 0 .../util => Analysis/Utilities}/source/filterer.cpp | 0 .../Utilities}/source/headReader.cpp | 0 {Scan/util => Analysis/Utilities}/source/scope.cpp | 0 {Scan/utkscan => Analysis/Utkscan}/CMakeLists.txt | 0 .../Utkscan}/analyzers/CMakeLists.txt | 0 .../Utkscan}/analyzers/include/CfdAnalyzer.hpp | 0 .../Utkscan}/analyzers/include/FittingAnalyzer.hpp | 0 .../Utkscan}/analyzers/include/TauAnalyzer.hpp | 0 .../Utkscan}/analyzers/include/TraceAnalyzer.hpp | 0 .../Utkscan}/analyzers/include/TraceExtractor.hpp | 0 .../Utkscan}/analyzers/include/TraceFilter.hpp | 0 .../analyzers/include/TraceFilterAnalyzer.hpp | 0 .../analyzers/include/TrapFilterParameters.hpp | 0 .../Utkscan}/analyzers/include/WaaAnalyzer.hpp | 0 .../Utkscan}/analyzers/include/WaveformAnalyzer.hpp | 0 .../Utkscan}/analyzers/source/CMakeLists.txt | 0 .../Utkscan}/analyzers/source/CfdAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/FittingAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/TauAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/TraceAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/TraceExtractor.cpp | 0 .../Utkscan}/analyzers/source/TraceFilter.cpp | 0 .../analyzers/source/TraceFilterAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/WaaAnalyzer.cpp | 0 .../Utkscan}/analyzers/source/WaveformAnalyzer.cpp | 0 .../Utkscan}/core/CMakeLists.txt | 0 .../Utkscan}/core/include/BarBuilder.hpp | 0 .../Utkscan}/core/include/BarDetector.hpp | 0 .../Utkscan}/core/include/Calibrator.hpp | 0 .../Utkscan}/core/include/ChanEvent.hpp | 0 .../Utkscan}/core/include/Correlator.hpp | 0 .../Utkscan}/core/include/DammPlotIds.hpp | 0 .../Utkscan}/core/include/DetectorDriver.hpp | 0 .../Utkscan}/core/include/DetectorLibrary.hpp | 0 .../Utkscan}/core/include/DetectorSummary.hpp | 0 .../Utkscan}/core/include/EventData.hpp | 0 .../Utkscan}/core/include/Exceptions.hpp | 0 .../Utkscan}/core/include/Globals.hpp | 0 .../Utkscan}/core/include/HighResTimingData.hpp | 0 .../Utkscan}/core/include/HisFile.hpp | 0 .../Utkscan}/core/include/Identifier.hpp | 0 .../Utkscan}/core/include/MersenneTwister.hpp | 0 .../Utkscan}/core/include/Messenger.hpp | 0 .../Utkscan}/core/include/Notebook.hpp | 0 .../Utkscan}/core/include/OutputHisFile.hpp | 0 .../Utkscan}/core/include/PlaceBuilder.hpp | 0 .../Utkscan}/core/include/Places.hpp | 0 .../Utkscan}/core/include/Plots.hpp | 0 .../Utkscan}/core/include/PlotsRegister.hpp | 0 .../Utkscan}/core/include/RandomPool.hpp | 0 .../Utkscan}/core/include/RawEvent.hpp | 0 .../Utkscan}/core/include/SheCorrelator.hpp | 0 .../Utkscan}/core/include/StatsData.hpp | 0 .../Utkscan}/core/include/TimingCalibrator.hpp | 0 .../Utkscan}/core/include/TimingMapBuilder.hpp | 0 .../Utkscan}/core/include/Trace.hpp | 0 .../Utkscan}/core/include/TreeCorrelator.hpp | 0 .../Utkscan}/core/include/UtkScanInterface.hpp | 0 .../Utkscan}/core/include/UtkUnpacker.hpp | 0 .../Utkscan}/core/include/WalkCorrector.hpp | 0 .../Utkscan}/core/include/pugiconfig.hpp | 0 .../Utkscan}/core/include/pugixml.hpp | 0 .../Utkscan}/core/source/BarBuilder.cpp | 0 .../Utkscan}/core/source/CMakeLists.txt | 0 .../Utkscan}/core/source/Calibrator.cpp | 0 .../Utkscan}/core/source/ChanEvent.cpp | 0 .../Utkscan}/core/source/Correlator.cpp | 0 .../Utkscan}/core/source/DetectorDriver.cpp | 0 .../Utkscan}/core/source/DetectorLibrary.cpp | 0 .../Utkscan}/core/source/DetectorSummary.cpp | 0 .../Utkscan}/core/source/Globals.cpp | 0 .../Utkscan}/core/source/HisFile.cpp | 0 .../Utkscan}/core/source/Identifier.cpp | 0 .../Utkscan}/core/source/Messenger.cpp | 0 .../Utkscan}/core/source/Notebook.cpp | 0 .../Utkscan}/core/source/OutputHisFile.cpp | 0 .../Utkscan}/core/source/PlaceBuilder.cpp | 0 .../Utkscan}/core/source/Places.cpp | 0 .../Utkscan}/core/source/Plots.cpp | 0 .../Utkscan}/core/source/PlotsRegister.cpp | 0 .../Utkscan}/core/source/RandomPool.cpp | 0 .../Utkscan}/core/source/RawEvent.cpp | 0 .../Utkscan}/core/source/ReadBuffDataA.cpp | 0 .../Utkscan}/core/source/ReadBuffDataD.cpp | 0 .../Utkscan}/core/source/ReadBuffDataF.cpp | 0 .../Utkscan}/core/source/StatsData.cpp | 0 .../Utkscan}/core/source/TimingCalibrator.cpp | 0 .../Utkscan}/core/source/TimingMapBuilder.cpp | 0 .../Utkscan}/core/source/Trace.cpp | 0 .../Utkscan}/core/source/TreeCorrelator.cpp | 0 .../Utkscan}/core/source/UtkScanInterface.cpp | 0 .../Utkscan}/core/source/UtkUnpacker.cpp | 0 .../Utkscan}/core/source/WalkCorrector.cpp | 0 .../Utkscan}/core/source/pugixml.cpp | 0 .../Utkscan}/core/source/utkscan.cpp | 0 .../Utkscan}/core/source/utkscanor.cpp | 0 .../Utkscan}/core/tests/CMakeLists.txt | 0 .../Utkscan}/core/tests/unittest-Identifier.cpp | 0 .../Utkscan}/core/tests/unittest-WalkCorrector.cpp | 0 .../Utkscan}/experiment/CMakeLists.txt | 0 .../experiment/include/Anl1471Processor.hpp | 0 .../experiment/include/Beta4Hen3Processor.hpp | 0 .../experiment/include/CrosstalkProcessor.hpp | 0 .../experiment/include/Dssd4SHEProcessor.hpp | 0 .../experiment/include/Ge4Hen3Processor.hpp | 0 .../Utkscan}/experiment/include/IS600Processor.hpp | 0 .../experiment/include/LaBr3TestProcessor.hpp | 0 .../experiment/include/TemplateExpProcessor.hpp | 0 .../experiment/include/TwoChanTimingProcessor.hpp | 0 .../experiment/include/VandleOrnl2012Processor.hpp | 0 .../experiment/include/WalkVandleBetaProcessor.hpp | 0 .../Utkscan}/experiment/source/Anl1471Processor.cpp | 0 .../experiment/source/Beta4Hen3Processor.cpp | 0 .../Utkscan}/experiment/source/CMakeLists.txt | 0 .../experiment/source/CrosstalkProcessor.cpp | 0 .../experiment/source/Dssd4SHEProcessor.cpp | 0 .../Utkscan}/experiment/source/Ge4Hen3Processor.cpp | 0 .../Utkscan}/experiment/source/IS600Processor.cpp | 0 .../experiment/source/LaBr3TestProcessor.cpp | 0 .../Utkscan}/experiment/source/SheCorrelator.cpp | 0 .../experiment/source/TemplateExpProcessor.cpp | 0 .../experiment/source/TwoChanTimingProcessor.cpp | 0 .../experiment/source/VandleOrnl2012Processor.cpp | 0 .../experiment/source/WalkVandleBetaProcessor.cpp | 0 .../Utkscan}/processors/CMakeLists.txt | 0 .../Utkscan}/processors/include/BetaProcessor.hpp | 0 .../processors/include/BetaScintProcessor.hpp | 0 .../processors/include/DoubleBetaProcessor.hpp | 0 .../Utkscan}/processors/include/DssdProcessor.hpp | 0 .../Utkscan}/processors/include/EventProcessor.hpp | 0 .../processors/include/GeCalibProcessor.hpp | 0 .../Utkscan}/processors/include/GeProcessor.hpp | 0 .../Utkscan}/processors/include/Hen3Processor.hpp | 0 .../processors/include/ImplantSsdProcessor.hpp | 0 .../processors/include/IonChamberProcessor.hpp | 0 .../Utkscan}/processors/include/LiquidProcessor.hpp | 0 .../processors/include/LiquidScintProcessor.hpp | 0 .../processors/include/LitePositionProcessor.hpp | 0 .../Utkscan}/processors/include/LogicProcessor.hpp | 0 .../Utkscan}/processors/include/McpProcessor.hpp | 0 .../processors/include/NeutronProcessor.hpp | 0 .../processors/include/NeutronScintProcessor.hpp | 0 .../processors/include/PositionProcessor.hpp | 0 .../Utkscan}/processors/include/PspmtProcessor.hpp | 0 .../Utkscan}/processors/include/RootProcessor.hpp | 0 .../Utkscan}/processors/include/ScintProcessor.hpp | 0 .../processors/include/SsdBetaProcessor.hpp | 0 .../Utkscan}/processors/include/SsdProcessor.hpp | 0 .../processors/include/TeenyVandleProcessor.hpp | 0 .../processors/include/TemplateProcessor.hpp | 0 .../Utkscan}/processors/include/ValidProcessor.hpp | 0 .../Utkscan}/processors/include/VandleProcessor.hpp | 0 .../Utkscan}/processors/source/BetaProcessor.cpp | 0 .../processors/source/BetaScintProcessor.cpp | 0 .../Utkscan}/processors/source/CMakeLists.txt | 0 .../processors/source/DoubleBetaProcessor.cpp | 0 .../Utkscan}/processors/source/DssdProcessor.cpp | 0 .../Utkscan}/processors/source/EventProcessor.cpp | 0 .../Utkscan}/processors/source/GeCalibProcessor.cpp | 0 .../Utkscan}/processors/source/GeProcessor.cpp | 0 .../Utkscan}/processors/source/Hen3Processor.cpp | 0 .../processors/source/ImplantSsdProcessor.cpp | 0 .../processors/source/IonChamberProcessor.cpp | 0 .../Utkscan}/processors/source/LiquidProcessor.cpp | 0 .../processors/source/LiquidScintProcessor.cpp | 0 .../processors/source/LitePositionProcessor.cpp | 0 .../Utkscan}/processors/source/LogicProcessor.cpp | 0 .../Utkscan}/processors/source/McpProcessor.cpp | 0 .../Utkscan}/processors/source/NeutronProcessor.cpp | 0 .../processors/source/NeutronScintProcessor.cpp | 0 .../processors/source/PositionProcessor.cpp | 0 .../Utkscan}/processors/source/PspmtProcessor.cpp | 0 .../Utkscan}/processors/source/RootProcessor.cpp | 0 .../Utkscan}/processors/source/ScintProcessor.cpp | 0 .../Utkscan}/processors/source/SsdBetaProcessor.cpp | 0 .../Utkscan}/processors/source/SsdProcessor.cpp | 0 .../processors/source/TeenyVandleProcessor.cpp | 0 .../processors/source/TemplateProcessor.cpp | 0 .../Utkscan}/processors/source/ValidProcessor.cpp | 0 .../Utkscan}/processors/source/VandleProcessor.cpp | 0 .../Utkscan}/share/utkscan/bananas/077cu.ban | 0 .../Utkscan}/share/utkscan/bananas/test.ban | 0 .../utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml | 0 .../utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml | 0 .../utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml | 0 .../utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml | 0 .../share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_01.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_03.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_06.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_07.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_08.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_10.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_11.xml | 0 .../utkscan/cfgs/anl/1471/85As/as85_apr_12.xml | 0 .../share/utkscan/cfgs/anl/1471/anl2015.xml | 0 .../share/utkscan/cfgs/anl/2013/Globals.xml | 0 .../share/utkscan/cfgs/anl/2013/TreeCorrelator.xml | 0 .../Utkscan}/share/utkscan/cfgs/anl/2013/cal.txt | 0 .../Utkscan}/share/utkscan/cfgs/anl/2013/filter.txt | 0 .../Utkscan}/share/utkscan/cfgs/anl/2013/map2.txt | 0 .../Utkscan}/share/utkscan/cfgs/anl/2013/qdc.txt | 0 .../share/utkscan/cfgs/anl/2013/timingCal.txt | 0 .../share/utkscan/cfgs/anl/2013/timingConstants.txt | 0 .../Utkscan}/share/utkscan/cfgs/examples/cal.xml | 0 .../share/utkscan/cfgs/examples/example.xml | 0 .../Utkscan}/share/utkscan/cfgs/examples/qdc.txt | 0 .../share/utkscan/cfgs/isolde/is599-600/gcal.xml | 0 .../is599-600/is599/aug/051k/is599_51k_01.xml | 0 .../is599-600/is599/aug/052k/is599_52k_00.xml | 0 .../is599-600/is599/aug/052k/is599_52k_01.xml | 0 .../is599-600/is599/aug/052k/is599_52k_02.xml | 0 .../is599-600/is599/aug/052k/is599_52k_04.xml | 0 .../is599-600/is599/aug/052k/is599_a52_00-alt.xml | 0 .../is599-600/is599/aug/052k/is599_a52_00-mod.xml | 0 .../is599-600/is599/aug/053k/is599_53k_00.xml | 0 .../is599-600/is599/aug/053k/is599_53k_01.xml | 0 .../is599-600/is599/aug/053k/is599_53k_02.xml | 0 .../is599-600/is599/aug/053k/is599_53k_03.xml | 0 .../is599-600/is599/aug/053k/is599_53k_04.xml | 0 .../is599-600/is599/aug/053k/is599_53k_08.xml | 0 .../is599-600/is599/aug/053k/is599_53k_09.xml | 0 .../is599-600/is599/aug/053k/is599_53k_10.xml | 0 .../is599-600/is599/aug/053k/is599_53k_12.xml | 0 .../is599-600/is599/aug/054k/is599_54k_01.xml | 0 .../cfgs/isolde/is599-600/is599/aug/cf05.xml | 0 .../is599-600/is599/aug/is599_07232015-1219am.xml | 0 .../is599-600/is599/oct/052k/IS599Oct_A052_02.xml | 0 .../is599-600/is599/oct/052k/IS599Oct_A052_03.xml | 0 .../is599-600/is599/oct/052k/IS599Oct_A052_04.xml | 0 .../is599/oct/052k/IS599Oct_A052_HRS_05.xml | 0 .../is599/oct/052k/IS599Oct_A052_HRS_06.xml | 0 .../is599/oct/052k/IS599Oct_A052_HRS_08.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a130_00.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_03.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_07.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_08.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_09.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_10.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_11.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_12.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_13.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_14.xml | 0 .../cfgs/isolde/is599-600/is600/is600_a83_15.xml | 0 .../cfgs/isolde/is599-600/is600/is600_cf03.xml | 0 .../share/utkscan/cfgs/isolde/is599-600/master.xml | 0 .../share/utkscan/cfgs/isolde/is599-600/vcal.xml | 0 .../utkscan/cfgs/nscl/e11027/01-2013/Globals.xml | 0 .../cfgs/nscl/e11027/01-2013/TreeCorrelator.xml | 0 .../share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt | 0 .../utkscan/cfgs/nscl/e11027/01-2013/filter.txt | 0 .../share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt | 0 .../share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt | 0 .../utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt | 0 .../cfgs/nscl/e11027/01-2013/timingConstants.txt | 0 .../utkscan/cfgs/nscl/e11027/05-2013/Globals.xml | 0 .../cfgs/nscl/e11027/05-2013/TreeCorrelator.xml | 0 .../share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt | 0 .../utkscan/cfgs/nscl/e11027/05-2013/filter.txt | 0 .../share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt | 0 .../share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt | 0 .../utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt | 0 .../cfgs/nscl/e11027/05-2013/timingConstants.txt | 0 .../cfgs/nscl/e11027/gainmatching/Globals.xml | 0 .../nscl/e11027/gainmatching/TreeCorrelator.xml | 0 .../utkscan/cfgs/nscl/e11027/gainmatching/cal.txt | 0 .../cfgs/nscl/e11027/gainmatching/filter.txt | 0 .../utkscan/cfgs/nscl/e11027/gainmatching/map2.txt | 0 .../utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt | 0 .../cfgs/nscl/e11027/gainmatching/timingCal.txt | 0 .../nscl/e11027/gainmatching/timingConstants.txt | 0 .../utkscan/cfgs/nscl/e11027/toftest/Globals.xml | 0 .../cfgs/nscl/e11027/toftest/TreeCorrelator.xml | 0 .../share/utkscan/cfgs/nscl/e11027/toftest/cal.txt | 0 .../utkscan/cfgs/nscl/e11027/toftest/filter.txt | 0 .../share/utkscan/cfgs/nscl/e11027/toftest/map2.txt | 0 .../share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt | 0 .../utkscan/cfgs/nscl/e11027/toftest/timingCal.txt | 0 .../cfgs/nscl/e11027/toftest/timingConstants.txt | 0 .../share/utkscan/cfgs/ornl/leribss2011/73cu.xml | 0 .../share/utkscan/cfgs/ornl/leribss2011/93br.xml | 0 .../share/utkscan/cfgs/ornl/monaOrnl/Globals.xml | 0 .../utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml | 0 .../share/utkscan/cfgs/ornl/monaOrnl/cal.txt | 0 .../share/utkscan/cfgs/ornl/monaOrnl/filter.txt | 0 .../share/utkscan/cfgs/ornl/monaOrnl/map2.txt | 0 .../share/utkscan/cfgs/ornl/monaOrnl/qdc.txt | 0 .../share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt | 0 .../utkscan/cfgs/ornl/monaOrnl/timingConstants.txt | 0 .../cfgs/ornl/vandle2012/077cu/77cu-01-4.xml | 0 .../utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml | 0 .../utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml | 0 .../cfgs/ornl/vandle2012/077cu/77cu-105-7.xml | 0 .../cfgs/ornl/vandle2012/077cu/77cu-test.xml | 0 .../cfgs/ornl/vandle2012/084ga/084ga-001-3.xml | 0 .../cfgs/ornl/vandle2012/085as/85as-test.xml | 0 .../share/utkscan/cfgs/ornl/vandle2012/83ga.xml | 0 .../share/utkscan/cfgs/ornl/vandle2012/85ga.xml | 0 .../share/utkscan/cfgs/ornl/vandle2012/86ga.xml | 0 .../Utkscan}/share/utkscan/cfgs/she/Config.xml.she | 0 .../share/utkscan/cfgs/she/Config.xml.she2010 | 0 .../Utkscan}/share/utkscan/cfgs/svp/newhist.xml | 0 .../share/utkscan/cfgs/svp/pixieworkshop-cfd.xml | 0 .../share/utkscan/cfgs/svp/pixieworkshop.xml | 0 .../Utkscan}/share/utkscan/cfgs/svp/pulsertst.xml | 0 .../Utkscan}/share/utkscan/cfgs/svp/skutek.xml | 0 .../Utkscan}/share/utkscan/cfgs/svp/testing.xml | 0 .../Utkscan}/share/utkscan/cfgs/utk/labr3tst.xml | 0 .../Utkscan}/share/utkscan/cfgs/utk/pulser.xml | 0 .../share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml | 0 .../share/utkscan/cfgs/utk/sipm/sienergytst.xml | 0 .../Utkscan}/share/utkscan/cfgs/utk/tvandleWalk.xml | 0 .../Utkscan}/share/utkscan/scripts/analyze.bash | 0 .../Utkscan}/share/utkscan/scripts/cmapbill.dat | 0 .../Utkscan}/share/utkscan/scripts/makedist.bash | 0 .../Utkscan}/share/utkscan/scripts/map_to_config.py | 0 .../share/utkscan/scripts/multianalyze.bash | 0 .../Utkscan}/share/utkscan/scripts/online.bash | 0 .../Utkscan}/share/utkscan/scripts/qrun.bash | 0 .../Utkscan}/share/utkscan/scripts/start.cmd | 0 .../Utkscan}/share/utkscan/scripts/tcaltoxml.awk | 0 .../Utkscan}/share/utkscan/scripts/test.cmd | 0 {cmake => Cmake}/modules/FindGSL.cmake | 0 {cmake => Cmake}/modules/FindHRIBF.cmake | 0 {cmake => Cmake}/modules/FindPLX.cmake | 0 {cmake => Cmake}/modules/FindPXI.cmake | 0 {cmake => Cmake}/modules/FindROOT.cmake | 0 {cmake => Cmake}/modules/FindUnitTest++.cmake | 0 {doc => Doc}/doxyfile | 0 {doc => Doc}/pages/mainPage.dox | 0 {doc => Doc}/pics/analysisflow.eps | Bin {doc => Doc}/pics/analysisflow.jpg | Bin {doc => Doc}/pics/timingCorrection.eps | 0 {doc => Doc}/pics/timingCorrection.jpg | Bin {share => Share}/CMakeLists.txt | 0 {share => Share}/modulefiles/pixieSuite | 0 {share => Share}/plx/init.d/plxload | 0 {share => Share}/plx/init.d/plxunload | 0 {share => Share}/plx/systemd/plx.service | 0 489 files changed, 0 insertions(+), 0 deletions(-) rename {Interface => Acquisition/Interface}/include/Lock.h (100%) rename {Interface => Acquisition/Interface}/include/PixieInterface.h (100%) rename {Interface => Acquisition/Interface}/include/PixieSupport.h (100%) rename {Interface => Acquisition/Interface}/include/Utility.h (100%) rename {Interface => Acquisition/Interface}/source/CMakeLists.txt (100%) rename {Interface => Acquisition/Interface}/source/Lock.cpp (100%) rename {Interface => Acquisition/Interface}/source/PixieInterface.cpp (100%) rename {Interface => Acquisition/Interface}/source/PixieSupport.cpp (100%) rename {Interface => Acquisition/Interface}/source/Utility.cpp (100%) rename {Interface => Acquisition/Interface}/source/test.cpp (100%) rename {MCA => Acquisition/MCA}/CMakeLists.txt (100%) rename {MCA => Acquisition/MCA}/include/DrrBlock.h (100%) rename {MCA => Acquisition/MCA}/include/Exceptions.h (100%) rename {MCA => Acquisition/MCA}/include/HisDrr.h (100%) rename {MCA => Acquisition/MCA}/include/MCA.h (100%) rename {MCA => Acquisition/MCA}/include/MCA_DAMM.h (100%) rename {MCA => Acquisition/MCA}/include/MCA_ROOT.h (100%) rename {MCA => Acquisition/MCA}/share/mca_input.txt (100%) rename {MCA => Acquisition/MCA}/source/CMakeLists.txt (100%) rename {MCA => Acquisition/MCA}/source/HisDrr.cpp (100%) rename {MCA => Acquisition/MCA}/source/MCA.cpp (100%) rename {MCA => Acquisition/MCA}/source/MCA_DAMM.cpp (100%) rename {MCA => Acquisition/MCA}/source/MCA_ROOT.cpp (100%) rename {MCA => Acquisition/MCA}/source/MCA_exec.cpp (100%) rename {Poll => Acquisition/Poll}/CMakeLists.txt (100%) rename {Poll => Acquisition/Poll}/include/poll2_core.h (100%) rename {Poll => Acquisition/Poll}/include/poll2_stats.h (100%) rename {Poll => Acquisition/Poll}/monitor.bash (100%) rename {Poll => Acquisition/Poll}/send_alarm (100%) rename {Poll => Acquisition/Poll}/source/CMakeLists.txt (100%) rename {Poll => Acquisition/Poll}/source/listener.cpp (100%) rename {Poll => Acquisition/Poll}/source/monitor.cpp (100%) rename {Poll => Acquisition/Poll}/source/poll2.cpp (100%) rename {Poll => Acquisition/Poll}/source/poll2_core.cpp (100%) rename {Poll => Acquisition/Poll}/source/poll2_stats.cpp (100%) rename {PxiDump => Acquisition/PxiDump}/CMakeLists.txt (100%) rename {PxiDump => Acquisition/PxiDump}/include/set2root.hpp (100%) rename {PxiDump => Acquisition/PxiDump}/source/CMakeLists.txt (100%) rename {PxiDump => Acquisition/PxiDump}/source/set2root.cpp (100%) rename {Setup => Acquisition/Setup}/CMakeLists.txt (100%) rename {Setup => Acquisition/Setup}/Traces/CMakeLists.txt (100%) rename {Setup => Acquisition/Setup}/Traces/share/traces/plotTraces_ch (100%) rename {Setup => Acquisition/Setup}/Traces/share/traces/plotTraces_mod (100%) rename {Setup => Acquisition/Setup}/Traces/share/traces/tra (100%) rename {Setup => Acquisition/Setup}/Traces/source/viewBaseline.sh (100%) rename {Setup => Acquisition/Setup}/include/utilities.h (100%) rename {Setup => Acquisition/Setup}/source/CMakeLists.txt (100%) rename {Setup => Acquisition/Setup}/source/adjust_offsets.cpp (100%) rename {Setup => Acquisition/Setup}/source/boot.cpp (100%) rename {Setup => Acquisition/Setup}/source/copy_params.cpp (100%) rename {Setup => Acquisition/Setup}/source/csr_test.cpp (100%) rename {Setup => Acquisition/Setup}/source/find_tau.cpp (100%) rename {Setup => Acquisition/Setup}/source/get_traces.cpp (100%) rename {Setup => Acquisition/Setup}/source/input_whole_crate.txt (100%) rename {Setup => Acquisition/Setup}/source/mca_paw.cpp (100%) rename {Setup => Acquisition/Setup}/source/paramScan.cpp (100%) rename {Setup => Acquisition/Setup}/source/pmread.cpp (100%) rename {Setup => Acquisition/Setup}/source/pmwrite.cpp (100%) rename {Setup => Acquisition/Setup}/source/pread.cpp (100%) rename {Setup => Acquisition/Setup}/source/pwrite.cpp (100%) rename {Setup => Acquisition/Setup}/source/rate.cpp (100%) rename {Setup => Acquisition/Setup}/source/set_hybrid.cpp (100%) rename {Setup => Acquisition/Setup}/source/set_pileups_only.cpp (100%) rename {Setup => Acquisition/Setup}/source/set_pileups_reject.cpp (100%) rename {Setup => Acquisition/Setup}/source/set_standard.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_catcher.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_gain.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_good.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_pileup.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_polarity.cpp (100%) rename {Setup => Acquisition/Setup}/source/toggle_trace.cpp (100%) rename {Setup => Acquisition/Setup}/source/trace.cpp (100%) rename {Setup => Acquisition/Setup}/source/trace_paw.cpp (100%) rename {Scan => Analysis}/CMakeLists.txt (100%) rename {Scan => Analysis}/Resources/CMakeLists.txt (100%) rename {Scan => Analysis}/Resources/include/GslFitter.hpp (100%) rename {Scan => Analysis}/Resources/include/HelperEnumerations.hpp (100%) rename {Scan => Analysis}/Resources/include/HelperFunctions.hpp (100%) rename {Scan => Analysis}/Resources/include/PolynomialCfd.hpp (100%) rename {Scan => Analysis}/Resources/include/RootFitter.hpp (100%) rename {Scan => Analysis}/Resources/include/TimingDriver.hpp (100%) rename {Scan => Analysis}/Resources/include/TraditionalCfd.hpp (100%) rename {Scan => Analysis}/Resources/include/UnitTestSampleData.hpp (100%) rename {Scan => Analysis}/Resources/include/VandleTimingFunction.hpp (100%) rename {Scan => Analysis}/Resources/include/XiaCfd.hpp (100%) rename {Scan => Analysis}/Resources/source/CMakeLists.txt (100%) rename {Scan => Analysis}/Resources/source/Gsl1Fitter.cpp (100%) rename {Scan => Analysis}/Resources/source/Gsl2Fitter.cpp (100%) rename {Scan => Analysis}/Resources/source/PolynomialCfd.cpp (100%) rename {Scan => Analysis}/Resources/source/RootFitter.cpp (100%) rename {Scan => Analysis}/Resources/source/TraditionalCfd.cpp (100%) rename {Scan => Analysis}/Resources/source/VandleTimingFunction.cpp (100%) rename {Scan => Analysis}/Resources/source/XiaCfd.cpp (100%) rename {Scan => Analysis}/Resources/tests/CMakeLists.txt (100%) rename {Scan => Analysis}/Resources/tests/unittest-GslFitter.cpp (100%) rename {Scan => Analysis}/Resources/tests/unittest-HelperFunctions.cpp (100%) rename {Scan => Analysis}/Resources/tests/unittest-PolynomialCfd.cpp (100%) rename {Scan => Analysis}/Resources/tests/unittest-RootFitter.cpp (100%) rename {Scan => Analysis}/Resources/tests/unittest-TraditionalCfd.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/CMakeLists.txt (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/ChannelData.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/ChannelEvent.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/RootScanner.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/ScanInterface.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/Unpacker.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/XiaData.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/XiaListModeDataDecoder.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/XiaListModeDataEncoder.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/XiaListModeDataMask.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/CMakeLists.txt (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/ChannelData.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/ChannelEvent.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/RootScanner.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/ScanInterface.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/Unpacker.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/XiaData.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/XiaListModeDataDecoder.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/XiaListModeDataEncoder.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/XiaListModeDataMask.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/tests/CMakeLists.txt (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/tests/unittest-XiaData.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/tests/unittest-XiaListModeDataDecoder.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/tests/unittest-XiaListModeDataEncoder.cpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/tests/unittest-XiaListModeDataMask.cpp (100%) rename {Scan/scanor => Analysis/Scanor}/CMakeLists.txt (100%) rename {Scan/scanor => Analysis/Scanor}/include/GetArguments.hpp (100%) rename {Scan/scanor => Analysis/Scanor}/include/Scanor.hpp (100%) rename {Scan/scanor => Analysis/Scanor}/include/ScanorInterface.hpp (100%) rename {Scan/scanor => Analysis/Scanor}/source/CMakeLists.txt (100%) rename {Scan/scanor => Analysis/Scanor}/source/GetArguments.cpp (100%) rename {Scan/scanor => Analysis/Scanor}/source/Scanor.cpp (100%) rename {Scan/scanor => Analysis/Scanor}/source/ScanorInterface.cpp (100%) rename {Scan/scanor => Analysis/Scanor}/source/messlog.f (100%) rename {Scan/scanor => Analysis/Scanor}/source/mildatim.f (100%) rename {Scan/scanor => Analysis/Scanor}/source/scanof.f (100%) rename {Scan/scanor => Analysis/Scanor}/source/scanor.f (100%) rename {Scan/scanor => Analysis/Scanor}/source/scanorux.f (100%) rename {Scan/scanor => Analysis/Scanor}/source/set2cc.f (100%) rename {Scan/util => Analysis/Utilities}/CMakeLists.txt (100%) rename {Scan/util => Analysis/Utilities}/include/Skeleton.hpp (100%) rename {Scan/util => Analysis/Utilities}/include/filterer.hpp (100%) rename {Scan/util => Analysis/Utilities}/include/scope.hpp (100%) rename {Scan/util => Analysis/Utilities}/source/CMakeLists.txt (100%) rename {Scan/util => Analysis/Utilities}/source/Skeleton.cpp (100%) rename {Scan/util => Analysis/Utilities}/source/filterer.cpp (100%) rename {Scan/util => Analysis/Utilities}/source/headReader.cpp (100%) rename {Scan/util => Analysis/Utilities}/source/scope.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/CfdAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/FittingAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TauAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TraceAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TraceExtractor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TraceFilter.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TraceFilterAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/TrapFilterParameters.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/WaaAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/include/WaveformAnalyzer.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/CfdAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/FittingAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/TauAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/TraceAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/TraceExtractor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/TraceFilter.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/TraceFilterAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/WaaAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/analyzers/source/WaveformAnalyzer.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/BarBuilder.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/BarDetector.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Calibrator.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/ChanEvent.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Correlator.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/DammPlotIds.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/DetectorDriver.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/DetectorLibrary.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/DetectorSummary.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/EventData.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Exceptions.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Globals.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/HighResTimingData.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/HisFile.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Identifier.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/MersenneTwister.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Messenger.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Notebook.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/OutputHisFile.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/PlaceBuilder.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Places.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Plots.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/PlotsRegister.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/RandomPool.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/RawEvent.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/SheCorrelator.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/StatsData.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/TimingCalibrator.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/TimingMapBuilder.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/Trace.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/TreeCorrelator.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/UtkScanInterface.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/UtkUnpacker.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/WalkCorrector.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/pugiconfig.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/include/pugixml.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/BarBuilder.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Calibrator.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/ChanEvent.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Correlator.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/DetectorDriver.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/DetectorLibrary.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/DetectorSummary.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Globals.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/HisFile.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Identifier.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Messenger.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Notebook.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/OutputHisFile.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/PlaceBuilder.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Places.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Plots.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/PlotsRegister.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/RandomPool.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/RawEvent.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/ReadBuffDataA.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/ReadBuffDataD.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/ReadBuffDataF.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/StatsData.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/TimingCalibrator.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/TimingMapBuilder.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/Trace.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/TreeCorrelator.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/UtkScanInterface.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/UtkUnpacker.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/WalkCorrector.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/pugixml.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/utkscan.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/source/utkscanor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/tests/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/tests/unittest-Identifier.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/core/tests/unittest-WalkCorrector.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/Anl1471Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/Beta4Hen3Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/CrosstalkProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/Dssd4SHEProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/Ge4Hen3Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/IS600Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/LaBr3TestProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/TemplateExpProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/TwoChanTimingProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/VandleOrnl2012Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/include/WalkVandleBetaProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/Anl1471Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/Beta4Hen3Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/CrosstalkProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/Dssd4SHEProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/Ge4Hen3Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/IS600Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/LaBr3TestProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/SheCorrelator.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/TemplateExpProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/TwoChanTimingProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/VandleOrnl2012Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/experiment/source/WalkVandleBetaProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/BetaProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/BetaScintProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/DoubleBetaProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/DssdProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/EventProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/GeCalibProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/GeProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/Hen3Processor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/ImplantSsdProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/IonChamberProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/LiquidProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/LiquidScintProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/LitePositionProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/LogicProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/McpProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/NeutronProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/NeutronScintProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/PositionProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/PspmtProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/RootProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/ScintProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/SsdBetaProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/SsdProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/TeenyVandleProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/TemplateProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/ValidProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/include/VandleProcessor.hpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/BetaProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/BetaScintProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/CMakeLists.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/DoubleBetaProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/DssdProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/EventProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/GeCalibProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/GeProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/Hen3Processor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/ImplantSsdProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/IonChamberProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/LiquidProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/LiquidScintProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/LitePositionProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/LogicProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/McpProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/NeutronProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/NeutronScintProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/PositionProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/PspmtProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/RootProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/ScintProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/SsdBetaProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/SsdProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/TeenyVandleProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/TemplateProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/ValidProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/processors/source/VandleProcessor.cpp (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/bananas/077cu.ban (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/bananas/test.ban (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/135Sb/a135_apr_06.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_02.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_04.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/135Sb/a135_feb_12.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_06.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_07.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_08.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_09.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_10.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/136Sb/A136sb_11.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_01.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_03.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_06.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_07.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_08.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_10.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_11.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/85As/as85_apr_12.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/1471/anl2015.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/anl/2013/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/examples/cal.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/examples/example.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/examples/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/gcal.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/051k/is599_51k_01.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_00.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_01.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_02.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_52k_04.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-alt.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/052k/is599_a52_00-mod.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_00.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_01.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_02.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_03.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_04.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_08.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_09.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_10.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/053k/is599_53k_12.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/054k/is599_54k_01.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/cf05.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/aug/is599_07232015-1219am.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_02.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_03.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_04.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_05.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_06.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is599/oct/052k/IS599Oct_A052_HRS_08.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a130_00.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_03.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_07.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_08.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_09.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_10.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_11.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_12.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_13.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_14.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_a83_15.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/is600/is600_cf03.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/master.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/isolde/is599-600/vcal.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/01-2013/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/05-2013/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/gainmatching/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/nscl/e11027/toftest/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/leribss2011/73cu.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/leribss2011/93br.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/Globals.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/TreeCorrelator.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/cal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/filter.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/map2.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/qdc.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/timingCal.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/monaOrnl/timingConstants.txt (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-01-4.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-103.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-104.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-105-7.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/077cu/77cu-test.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/084ga/084ga-001-3.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/085as/85as-test.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/83ga.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/85ga.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/ornl/vandle2012/86ga.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/she/Config.xml.she (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/she/Config.xml.she2010 (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/newhist.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/pixieworkshop.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/pulsertst.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/skutek.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/svp/testing.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/utk/labr3tst.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/utk/pulser.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/utk/sipm/doubleBetaTest.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/utk/sipm/sienergytst.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/cfgs/utk/tvandleWalk.xml (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/analyze.bash (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/cmapbill.dat (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/makedist.bash (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/map_to_config.py (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/multianalyze.bash (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/online.bash (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/qrun.bash (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/start.cmd (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/tcaltoxml.awk (100%) rename {Scan/utkscan => Analysis/Utkscan}/share/utkscan/scripts/test.cmd (100%) rename {cmake => Cmake}/modules/FindGSL.cmake (100%) rename {cmake => Cmake}/modules/FindHRIBF.cmake (100%) rename {cmake => Cmake}/modules/FindPLX.cmake (100%) rename {cmake => Cmake}/modules/FindPXI.cmake (100%) rename {cmake => Cmake}/modules/FindROOT.cmake (100%) rename {cmake => Cmake}/modules/FindUnitTest++.cmake (100%) rename {doc => Doc}/doxyfile (100%) rename {doc => Doc}/pages/mainPage.dox (100%) rename {doc => Doc}/pics/analysisflow.eps (100%) rename {doc => Doc}/pics/analysisflow.jpg (100%) rename {doc => Doc}/pics/timingCorrection.eps (100%) rename {doc => Doc}/pics/timingCorrection.jpg (100%) rename {share => Share}/CMakeLists.txt (100%) rename {share => Share}/modulefiles/pixieSuite (100%) rename {share => Share}/plx/init.d/plxload (100%) rename {share => Share}/plx/init.d/plxunload (100%) rename {share => Share}/plx/systemd/plx.service (100%) 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 100% rename from Interface/include/PixieInterface.h rename to Acquisition/Interface/include/PixieInterface.h 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 100% rename from Interface/source/CMakeLists.txt rename to Acquisition/Interface/source/CMakeLists.txt 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 100% rename from Interface/source/PixieInterface.cpp rename to Acquisition/Interface/source/PixieInterface.cpp 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 100% rename from MCA/source/HisDrr.cpp rename to Acquisition/MCA/source/HisDrr.cpp 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 100% rename from Poll/CMakeLists.txt rename to Acquisition/Poll/CMakeLists.txt diff --git a/Poll/include/poll2_core.h b/Acquisition/Poll/include/poll2_core.h similarity index 100% rename from Poll/include/poll2_core.h rename to Acquisition/Poll/include/poll2_core.h 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 100% rename from Poll/source/CMakeLists.txt rename to Acquisition/Poll/source/CMakeLists.txt 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 100% rename from Poll/source/poll2_core.cpp rename to Acquisition/Poll/source/poll2_core.cpp 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 100% rename from PxiDump/source/set2root.cpp rename to Acquisition/PxiDump/source/set2root.cpp diff --git a/Setup/CMakeLists.txt b/Acquisition/Setup/CMakeLists.txt similarity index 100% rename from Setup/CMakeLists.txt rename to Acquisition/Setup/CMakeLists.txt 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/Scan/CMakeLists.txt b/Analysis/CMakeLists.txt similarity index 100% rename from Scan/CMakeLists.txt rename to Analysis/CMakeLists.txt diff --git a/Scan/Resources/CMakeLists.txt b/Analysis/Resources/CMakeLists.txt similarity index 100% rename from Scan/Resources/CMakeLists.txt rename to Analysis/Resources/CMakeLists.txt diff --git a/Scan/Resources/include/GslFitter.hpp b/Analysis/Resources/include/GslFitter.hpp similarity index 100% rename from Scan/Resources/include/GslFitter.hpp rename to Analysis/Resources/include/GslFitter.hpp diff --git a/Scan/Resources/include/HelperEnumerations.hpp b/Analysis/Resources/include/HelperEnumerations.hpp similarity index 100% rename from Scan/Resources/include/HelperEnumerations.hpp rename to Analysis/Resources/include/HelperEnumerations.hpp diff --git a/Scan/Resources/include/HelperFunctions.hpp b/Analysis/Resources/include/HelperFunctions.hpp similarity index 100% rename from Scan/Resources/include/HelperFunctions.hpp rename to Analysis/Resources/include/HelperFunctions.hpp diff --git a/Scan/Resources/include/PolynomialCfd.hpp b/Analysis/Resources/include/PolynomialCfd.hpp similarity index 100% rename from Scan/Resources/include/PolynomialCfd.hpp rename to Analysis/Resources/include/PolynomialCfd.hpp diff --git a/Scan/Resources/include/RootFitter.hpp b/Analysis/Resources/include/RootFitter.hpp similarity index 100% rename from Scan/Resources/include/RootFitter.hpp rename to Analysis/Resources/include/RootFitter.hpp diff --git a/Scan/Resources/include/TimingDriver.hpp b/Analysis/Resources/include/TimingDriver.hpp similarity index 100% rename from Scan/Resources/include/TimingDriver.hpp rename to Analysis/Resources/include/TimingDriver.hpp diff --git a/Scan/Resources/include/TraditionalCfd.hpp b/Analysis/Resources/include/TraditionalCfd.hpp similarity index 100% rename from Scan/Resources/include/TraditionalCfd.hpp rename to Analysis/Resources/include/TraditionalCfd.hpp diff --git a/Scan/Resources/include/UnitTestSampleData.hpp b/Analysis/Resources/include/UnitTestSampleData.hpp similarity index 100% rename from Scan/Resources/include/UnitTestSampleData.hpp rename to Analysis/Resources/include/UnitTestSampleData.hpp diff --git a/Scan/Resources/include/VandleTimingFunction.hpp b/Analysis/Resources/include/VandleTimingFunction.hpp similarity index 100% rename from Scan/Resources/include/VandleTimingFunction.hpp rename to Analysis/Resources/include/VandleTimingFunction.hpp diff --git a/Scan/Resources/include/XiaCfd.hpp b/Analysis/Resources/include/XiaCfd.hpp similarity index 100% rename from Scan/Resources/include/XiaCfd.hpp rename to Analysis/Resources/include/XiaCfd.hpp diff --git a/Scan/Resources/source/CMakeLists.txt b/Analysis/Resources/source/CMakeLists.txt similarity index 100% rename from Scan/Resources/source/CMakeLists.txt rename to Analysis/Resources/source/CMakeLists.txt diff --git a/Scan/Resources/source/Gsl1Fitter.cpp b/Analysis/Resources/source/Gsl1Fitter.cpp similarity index 100% rename from Scan/Resources/source/Gsl1Fitter.cpp rename to Analysis/Resources/source/Gsl1Fitter.cpp diff --git a/Scan/Resources/source/Gsl2Fitter.cpp b/Analysis/Resources/source/Gsl2Fitter.cpp similarity index 100% rename from Scan/Resources/source/Gsl2Fitter.cpp rename to Analysis/Resources/source/Gsl2Fitter.cpp diff --git a/Scan/Resources/source/PolynomialCfd.cpp b/Analysis/Resources/source/PolynomialCfd.cpp similarity index 100% rename from Scan/Resources/source/PolynomialCfd.cpp rename to Analysis/Resources/source/PolynomialCfd.cpp diff --git a/Scan/Resources/source/RootFitter.cpp b/Analysis/Resources/source/RootFitter.cpp similarity index 100% rename from Scan/Resources/source/RootFitter.cpp rename to Analysis/Resources/source/RootFitter.cpp diff --git a/Scan/Resources/source/TraditionalCfd.cpp b/Analysis/Resources/source/TraditionalCfd.cpp similarity index 100% rename from Scan/Resources/source/TraditionalCfd.cpp rename to Analysis/Resources/source/TraditionalCfd.cpp diff --git a/Scan/Resources/source/VandleTimingFunction.cpp b/Analysis/Resources/source/VandleTimingFunction.cpp similarity index 100% rename from Scan/Resources/source/VandleTimingFunction.cpp rename to Analysis/Resources/source/VandleTimingFunction.cpp diff --git a/Scan/Resources/source/XiaCfd.cpp b/Analysis/Resources/source/XiaCfd.cpp similarity index 100% rename from Scan/Resources/source/XiaCfd.cpp rename to Analysis/Resources/source/XiaCfd.cpp diff --git a/Scan/Resources/tests/CMakeLists.txt b/Analysis/Resources/tests/CMakeLists.txt similarity index 100% rename from Scan/Resources/tests/CMakeLists.txt rename to Analysis/Resources/tests/CMakeLists.txt diff --git a/Scan/Resources/tests/unittest-GslFitter.cpp b/Analysis/Resources/tests/unittest-GslFitter.cpp similarity index 100% rename from Scan/Resources/tests/unittest-GslFitter.cpp rename to Analysis/Resources/tests/unittest-GslFitter.cpp diff --git a/Scan/Resources/tests/unittest-HelperFunctions.cpp b/Analysis/Resources/tests/unittest-HelperFunctions.cpp similarity index 100% rename from Scan/Resources/tests/unittest-HelperFunctions.cpp rename to Analysis/Resources/tests/unittest-HelperFunctions.cpp diff --git a/Scan/Resources/tests/unittest-PolynomialCfd.cpp b/Analysis/Resources/tests/unittest-PolynomialCfd.cpp similarity index 100% rename from Scan/Resources/tests/unittest-PolynomialCfd.cpp rename to Analysis/Resources/tests/unittest-PolynomialCfd.cpp diff --git a/Scan/Resources/tests/unittest-RootFitter.cpp b/Analysis/Resources/tests/unittest-RootFitter.cpp similarity index 100% rename from Scan/Resources/tests/unittest-RootFitter.cpp rename to Analysis/Resources/tests/unittest-RootFitter.cpp diff --git a/Scan/Resources/tests/unittest-TraditionalCfd.cpp b/Analysis/Resources/tests/unittest-TraditionalCfd.cpp similarity index 100% rename from Scan/Resources/tests/unittest-TraditionalCfd.cpp rename to Analysis/Resources/tests/unittest-TraditionalCfd.cpp diff --git a/Scan/ScanLib/CMakeLists.txt b/Analysis/ScanLibraries/CMakeLists.txt similarity index 100% rename from Scan/ScanLib/CMakeLists.txt rename to Analysis/ScanLibraries/CMakeLists.txt 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/Scan/ScanLib/include/ChannelEvent.hpp b/Analysis/ScanLibraries/include/ChannelEvent.hpp similarity index 100% rename from Scan/ScanLib/include/ChannelEvent.hpp rename to Analysis/ScanLibraries/include/ChannelEvent.hpp diff --git a/Scan/ScanLib/include/RootScanner.hpp b/Analysis/ScanLibraries/include/RootScanner.hpp similarity index 100% rename from Scan/ScanLib/include/RootScanner.hpp rename to Analysis/ScanLibraries/include/RootScanner.hpp 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 100% rename from Scan/ScanLib/include/Unpacker.hpp rename to Analysis/ScanLibraries/include/Unpacker.hpp diff --git a/Scan/ScanLib/include/XiaData.hpp b/Analysis/ScanLibraries/include/XiaData.hpp similarity index 100% rename from Scan/ScanLib/include/XiaData.hpp rename to Analysis/ScanLibraries/include/XiaData.hpp diff --git a/Scan/ScanLib/include/XiaListModeDataDecoder.hpp b/Analysis/ScanLibraries/include/XiaListModeDataDecoder.hpp similarity index 100% rename from Scan/ScanLib/include/XiaListModeDataDecoder.hpp rename to Analysis/ScanLibraries/include/XiaListModeDataDecoder.hpp diff --git a/Scan/ScanLib/include/XiaListModeDataEncoder.hpp b/Analysis/ScanLibraries/include/XiaListModeDataEncoder.hpp similarity index 100% rename from Scan/ScanLib/include/XiaListModeDataEncoder.hpp rename to Analysis/ScanLibraries/include/XiaListModeDataEncoder.hpp diff --git a/Scan/ScanLib/include/XiaListModeDataMask.hpp b/Analysis/ScanLibraries/include/XiaListModeDataMask.hpp similarity index 100% rename from Scan/ScanLib/include/XiaListModeDataMask.hpp rename to Analysis/ScanLibraries/include/XiaListModeDataMask.hpp diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt similarity index 100% rename from Scan/ScanLib/source/CMakeLists.txt rename to Analysis/ScanLibraries/source/CMakeLists.txt diff --git a/Scan/ScanLib/source/ChannelData.cpp b/Analysis/ScanLibraries/source/ChannelData.cpp similarity index 100% rename from Scan/ScanLib/source/ChannelData.cpp rename to Analysis/ScanLibraries/source/ChannelData.cpp diff --git a/Scan/ScanLib/source/ChannelEvent.cpp b/Analysis/ScanLibraries/source/ChannelEvent.cpp similarity index 100% rename from Scan/ScanLib/source/ChannelEvent.cpp rename to Analysis/ScanLibraries/source/ChannelEvent.cpp diff --git a/Scan/ScanLib/source/RootScanner.cpp b/Analysis/ScanLibraries/source/RootScanner.cpp similarity index 100% rename from Scan/ScanLib/source/RootScanner.cpp rename to Analysis/ScanLibraries/source/RootScanner.cpp diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Analysis/ScanLibraries/source/ScanInterface.cpp similarity index 100% rename from Scan/ScanLib/source/ScanInterface.cpp rename to Analysis/ScanLibraries/source/ScanInterface.cpp diff --git a/Scan/ScanLib/source/Unpacker.cpp b/Analysis/ScanLibraries/source/Unpacker.cpp similarity index 100% rename from Scan/ScanLib/source/Unpacker.cpp rename to Analysis/ScanLibraries/source/Unpacker.cpp diff --git a/Scan/ScanLib/source/XiaData.cpp b/Analysis/ScanLibraries/source/XiaData.cpp similarity index 100% rename from Scan/ScanLib/source/XiaData.cpp rename to Analysis/ScanLibraries/source/XiaData.cpp diff --git a/Scan/ScanLib/source/XiaListModeDataDecoder.cpp b/Analysis/ScanLibraries/source/XiaListModeDataDecoder.cpp similarity index 100% rename from Scan/ScanLib/source/XiaListModeDataDecoder.cpp rename to Analysis/ScanLibraries/source/XiaListModeDataDecoder.cpp diff --git a/Scan/ScanLib/source/XiaListModeDataEncoder.cpp b/Analysis/ScanLibraries/source/XiaListModeDataEncoder.cpp similarity index 100% rename from Scan/ScanLib/source/XiaListModeDataEncoder.cpp rename to Analysis/ScanLibraries/source/XiaListModeDataEncoder.cpp diff --git a/Scan/ScanLib/source/XiaListModeDataMask.cpp b/Analysis/ScanLibraries/source/XiaListModeDataMask.cpp similarity index 100% rename from Scan/ScanLib/source/XiaListModeDataMask.cpp rename to Analysis/ScanLibraries/source/XiaListModeDataMask.cpp diff --git a/Scan/ScanLib/tests/CMakeLists.txt b/Analysis/ScanLibraries/tests/CMakeLists.txt similarity index 100% rename from Scan/ScanLib/tests/CMakeLists.txt rename to Analysis/ScanLibraries/tests/CMakeLists.txt diff --git a/Scan/ScanLib/tests/unittest-XiaData.cpp b/Analysis/ScanLibraries/tests/unittest-XiaData.cpp similarity index 100% rename from Scan/ScanLib/tests/unittest-XiaData.cpp rename to Analysis/ScanLibraries/tests/unittest-XiaData.cpp diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataDecoder.cpp similarity index 100% rename from Scan/ScanLib/tests/unittest-XiaListModeDataDecoder.cpp rename to Analysis/ScanLibraries/tests/unittest-XiaListModeDataDecoder.cpp diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataEncoder.cpp similarity index 100% rename from Scan/ScanLib/tests/unittest-XiaListModeDataEncoder.cpp rename to Analysis/ScanLibraries/tests/unittest-XiaListModeDataEncoder.cpp diff --git a/Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp b/Analysis/ScanLibraries/tests/unittest-XiaListModeDataMask.cpp similarity index 100% rename from Scan/ScanLib/tests/unittest-XiaListModeDataMask.cpp rename to Analysis/ScanLibraries/tests/unittest-XiaListModeDataMask.cpp diff --git a/Scan/scanor/CMakeLists.txt b/Analysis/Scanor/CMakeLists.txt similarity index 100% rename from Scan/scanor/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 100% rename from Scan/util/include/scope.hpp rename to Analysis/Utilities/include/scope.hpp diff --git a/Scan/util/source/CMakeLists.txt b/Analysis/Utilities/source/CMakeLists.txt similarity index 100% rename from Scan/util/source/CMakeLists.txt rename to Analysis/Utilities/source/CMakeLists.txt diff --git a/Scan/util/source/Skeleton.cpp b/Analysis/Utilities/source/Skeleton.cpp similarity index 100% rename from Scan/util/source/Skeleton.cpp rename to Analysis/Utilities/source/Skeleton.cpp 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 100% rename from Scan/util/source/scope.cpp rename to Analysis/Utilities/source/scope.cpp diff --git a/Scan/utkscan/CMakeLists.txt b/Analysis/Utkscan/CMakeLists.txt similarity index 100% rename from Scan/utkscan/CMakeLists.txt rename to Analysis/Utkscan/CMakeLists.txt diff --git a/Scan/utkscan/analyzers/CMakeLists.txt b/Analysis/Utkscan/analyzers/CMakeLists.txt similarity index 100% rename from Scan/utkscan/analyzers/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 100% rename from Scan/utkscan/analyzers/include/CfdAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/CfdAnalyzer.hpp diff --git a/Scan/utkscan/analyzers/include/FittingAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/FittingAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/FittingAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/FittingAnalyzer.hpp 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/Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp b/Analysis/Utkscan/analyzers/include/WaveformAnalyzer.hpp similarity index 100% rename from Scan/utkscan/analyzers/include/WaveformAnalyzer.hpp rename to Analysis/Utkscan/analyzers/include/WaveformAnalyzer.hpp diff --git a/Scan/utkscan/analyzers/source/CMakeLists.txt b/Analysis/Utkscan/analyzers/source/CMakeLists.txt similarity index 100% rename from Scan/utkscan/analyzers/source/CMakeLists.txt rename to Analysis/Utkscan/analyzers/source/CMakeLists.txt diff --git a/Scan/utkscan/analyzers/source/CfdAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/CfdAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/CfdAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/CfdAnalyzer.cpp diff --git a/Scan/utkscan/analyzers/source/FittingAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/FittingAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/FittingAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/FittingAnalyzer.cpp 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/Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp b/Analysis/Utkscan/analyzers/source/WaveformAnalyzer.cpp similarity index 100% rename from Scan/utkscan/analyzers/source/WaveformAnalyzer.cpp rename to Analysis/Utkscan/analyzers/source/WaveformAnalyzer.cpp diff --git a/Scan/utkscan/core/CMakeLists.txt b/Analysis/Utkscan/core/CMakeLists.txt similarity index 100% rename from Scan/utkscan/core/CMakeLists.txt rename to Analysis/Utkscan/core/CMakeLists.txt 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 100% rename from Scan/utkscan/core/include/ChanEvent.hpp rename to Analysis/Utkscan/core/include/ChanEvent.hpp 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 100% rename from Scan/utkscan/core/include/DetectorSummary.hpp rename to Analysis/Utkscan/core/include/DetectorSummary.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 100% rename from Scan/utkscan/core/include/Globals.hpp rename to Analysis/Utkscan/core/include/Globals.hpp diff --git a/Scan/utkscan/core/include/HighResTimingData.hpp b/Analysis/Utkscan/core/include/HighResTimingData.hpp similarity index 100% rename from Scan/utkscan/core/include/HighResTimingData.hpp rename to Analysis/Utkscan/core/include/HighResTimingData.hpp 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 100% rename from Scan/utkscan/core/include/Identifier.hpp rename to Analysis/Utkscan/core/include/Identifier.hpp 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 100% rename from Scan/utkscan/core/include/RawEvent.hpp rename to Analysis/Utkscan/core/include/RawEvent.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 100% rename from Scan/utkscan/core/include/Trace.hpp rename to Analysis/Utkscan/core/include/Trace.hpp 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 100% rename from Scan/utkscan/core/include/WalkCorrector.hpp rename to Analysis/Utkscan/core/include/WalkCorrector.hpp diff --git a/Scan/utkscan/core/include/pugiconfig.hpp b/Analysis/Utkscan/core/include/pugiconfig.hpp similarity index 100% rename from Scan/utkscan/core/include/pugiconfig.hpp rename to Analysis/Utkscan/core/include/pugiconfig.hpp diff --git a/Scan/utkscan/core/include/pugixml.hpp b/Analysis/Utkscan/core/include/pugixml.hpp similarity index 100% rename from Scan/utkscan/core/include/pugixml.hpp rename to Analysis/Utkscan/core/include/pugixml.hpp 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 100% rename from Scan/utkscan/core/source/CMakeLists.txt rename to Analysis/Utkscan/core/source/CMakeLists.txt 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 100% rename from Scan/utkscan/core/source/ChanEvent.cpp rename to Analysis/Utkscan/core/source/ChanEvent.cpp 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 100% rename from Scan/utkscan/core/source/DetectorDriver.cpp rename to Analysis/Utkscan/core/source/DetectorDriver.cpp diff --git a/Scan/utkscan/core/source/DetectorLibrary.cpp b/Analysis/Utkscan/core/source/DetectorLibrary.cpp similarity index 100% rename from Scan/utkscan/core/source/DetectorLibrary.cpp rename to Analysis/Utkscan/core/source/DetectorLibrary.cpp 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 100% rename from Scan/utkscan/core/source/Globals.cpp rename to Analysis/Utkscan/core/source/Globals.cpp 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 100% rename from Scan/utkscan/core/source/Identifier.cpp rename to Analysis/Utkscan/core/source/Identifier.cpp 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 100% rename from Scan/utkscan/core/source/Trace.cpp rename to Analysis/Utkscan/core/source/Trace.cpp 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 100% rename from Scan/utkscan/core/source/UtkScanInterface.cpp rename to Analysis/Utkscan/core/source/UtkScanInterface.cpp diff --git a/Scan/utkscan/core/source/UtkUnpacker.cpp b/Analysis/Utkscan/core/source/UtkUnpacker.cpp similarity index 100% rename from Scan/utkscan/core/source/UtkUnpacker.cpp rename to Analysis/Utkscan/core/source/UtkUnpacker.cpp diff --git a/Scan/utkscan/core/source/WalkCorrector.cpp b/Analysis/Utkscan/core/source/WalkCorrector.cpp similarity index 100% rename from Scan/utkscan/core/source/WalkCorrector.cpp rename to Analysis/Utkscan/core/source/WalkCorrector.cpp diff --git a/Scan/utkscan/core/source/pugixml.cpp b/Analysis/Utkscan/core/source/pugixml.cpp similarity index 100% rename from Scan/utkscan/core/source/pugixml.cpp rename to Analysis/Utkscan/core/source/pugixml.cpp diff --git a/Scan/utkscan/core/source/utkscan.cpp b/Analysis/Utkscan/core/source/utkscan.cpp similarity index 100% rename from Scan/utkscan/core/source/utkscan.cpp rename to Analysis/Utkscan/core/source/utkscan.cpp 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/Scan/utkscan/core/tests/CMakeLists.txt b/Analysis/Utkscan/core/tests/CMakeLists.txt similarity index 100% rename from Scan/utkscan/core/tests/CMakeLists.txt rename to Analysis/Utkscan/core/tests/CMakeLists.txt diff --git a/Scan/utkscan/core/tests/unittest-Identifier.cpp b/Analysis/Utkscan/core/tests/unittest-Identifier.cpp similarity index 100% rename from Scan/utkscan/core/tests/unittest-Identifier.cpp rename to Analysis/Utkscan/core/tests/unittest-Identifier.cpp diff --git a/Scan/utkscan/core/tests/unittest-WalkCorrector.cpp b/Analysis/Utkscan/core/tests/unittest-WalkCorrector.cpp similarity index 100% rename from Scan/utkscan/core/tests/unittest-WalkCorrector.cpp rename to Analysis/Utkscan/core/tests/unittest-WalkCorrector.cpp 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 100% rename from Scan/utkscan/experiment/include/Anl1471Processor.hpp rename to Analysis/Utkscan/experiment/include/Anl1471Processor.hpp 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 100% rename from Scan/utkscan/experiment/include/TemplateExpProcessor.hpp rename to Analysis/Utkscan/experiment/include/TemplateExpProcessor.hpp diff --git a/Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp b/Analysis/Utkscan/experiment/include/TwoChanTimingProcessor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/TwoChanTimingProcessor.hpp rename to Analysis/Utkscan/experiment/include/TwoChanTimingProcessor.hpp diff --git a/Scan/utkscan/experiment/include/VandleOrnl2012Processor.hpp b/Analysis/Utkscan/experiment/include/VandleOrnl2012Processor.hpp similarity index 100% rename from Scan/utkscan/experiment/include/VandleOrnl2012Processor.hpp rename to Analysis/Utkscan/experiment/include/VandleOrnl2012Processor.hpp 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/Scan/utkscan/experiment/source/Anl1471Processor.cpp b/Analysis/Utkscan/experiment/source/Anl1471Processor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/Anl1471Processor.cpp rename to Analysis/Utkscan/experiment/source/Anl1471Processor.cpp 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/Scan/utkscan/experiment/source/CMakeLists.txt b/Analysis/Utkscan/experiment/source/CMakeLists.txt similarity index 100% rename from Scan/utkscan/experiment/source/CMakeLists.txt rename to Analysis/Utkscan/experiment/source/CMakeLists.txt 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 100% rename from Scan/utkscan/experiment/source/IS600Processor.cpp rename to Analysis/Utkscan/experiment/source/IS600Processor.cpp 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 100% rename from Scan/utkscan/experiment/source/TemplateExpProcessor.cpp rename to Analysis/Utkscan/experiment/source/TemplateExpProcessor.cpp diff --git a/Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp b/Analysis/Utkscan/experiment/source/TwoChanTimingProcessor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/TwoChanTimingProcessor.cpp rename to Analysis/Utkscan/experiment/source/TwoChanTimingProcessor.cpp diff --git a/Scan/utkscan/experiment/source/VandleOrnl2012Processor.cpp b/Analysis/Utkscan/experiment/source/VandleOrnl2012Processor.cpp similarity index 100% rename from Scan/utkscan/experiment/source/VandleOrnl2012Processor.cpp rename to Analysis/Utkscan/experiment/source/VandleOrnl2012Processor.cpp 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 100% rename from Scan/utkscan/processors/source/GeCalibProcessor.cpp rename to Analysis/Utkscan/processors/source/GeCalibProcessor.cpp diff --git a/Scan/utkscan/processors/source/GeProcessor.cpp b/Analysis/Utkscan/processors/source/GeProcessor.cpp similarity index 100% rename from Scan/utkscan/processors/source/GeProcessor.cpp rename to Analysis/Utkscan/processors/source/GeProcessor.cpp 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 100% rename from Scan/utkscan/processors/source/PspmtProcessor.cpp rename to Analysis/Utkscan/processors/source/PspmtProcessor.cpp 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/Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml b/Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml similarity index 100% rename from Scan/utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml rename to Analysis/Utkscan/share/utkscan/cfgs/svp/pixieworkshop-cfd.xml 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/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 similarity index 100% rename from cmake/modules/FindPXI.cmake rename to Cmake/modules/FindPXI.cmake 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 similarity index 100% rename from cmake/modules/FindUnitTest++.cmake rename to Cmake/modules/FindUnitTest++.cmake diff --git a/doc/doxyfile b/Doc/doxyfile similarity index 100% rename from doc/doxyfile rename to Doc/doxyfile 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/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 100% rename from share/plx/systemd/plx.service rename to Share/plx/systemd/plx.service From 7cc078a92f4e78d776d09c79c0a80978a0c9324c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 31 Jan 2017 09:44:11 -0500 Subject: [PATCH 137/255] Adjusting the CMakeLists files for new compilation paths I have also adjusted the name of the different libraries so that they are more explicit. For example, there was PixieCoreStatic, which was renamed to PaassCoreStatic. This makes things slightly more focused on the software that we're building and not on Pixie in general (ignore the P in PAASS). The pugixml software has been moved to ThirdParty. --- Acquisition/CMakeLists.txt | 21 ++++++++ Acquisition/Interface/source/CMakeLists.txt | 3 +- Acquisition/Poll/CMakeLists.txt | 1 - Acquisition/Poll/source/CMakeLists.txt | 4 +- Acquisition/Setup/CMakeLists.txt | 2 +- Analysis/CMakeLists.txt | 13 +++-- Analysis/Resources/source/CMakeLists.txt | 9 ++-- Analysis/ScanLibraries/source/CMakeLists.txt | 20 +++---- Analysis/Utilities/source/CMakeLists.txt | 6 +-- Analysis/Utkscan/CMakeLists.txt | 4 +- Analysis/Utkscan/core/source/CMakeLists.txt | 5 -- CMakeLists.txt | 54 ++++++++----------- Core/source/CMakeLists.txt | 19 +++---- Core/tests/CMakeLists.txt | 2 +- ThirdParty/CMakeLists.txt | 2 + .../include/pugiconfig.hpp | 0 .../core => ThirdParty}/include/pugixml.hpp | 0 ThirdParty/source/CMakeLists.txt | 9 ++++ .../core => ThirdParty}/source/pugixml.cpp | 0 19 files changed, 92 insertions(+), 82 deletions(-) create mode 100644 Acquisition/CMakeLists.txt create mode 100644 ThirdParty/CMakeLists.txt rename {Analysis/Utkscan/core => ThirdParty}/include/pugiconfig.hpp (100%) rename {Analysis/Utkscan/core => ThirdParty}/include/pugixml.hpp (100%) create mode 100644 ThirdParty/source/CMakeLists.txt rename {Analysis/Utkscan/core => ThirdParty}/source/pugixml.cpp (100%) 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/Acquisition/Interface/source/CMakeLists.txt b/Acquisition/Interface/source/CMakeLists.txt index afbf41bac..c571fff15 100644 --- a/Acquisition/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/Acquisition/Poll/CMakeLists.txt b/Acquisition/Poll/CMakeLists.txt index 240248e61..673ea3c38 100644 --- a/Acquisition/Poll/CMakeLists.txt +++ b/Acquisition/Poll/CMakeLists.txt @@ -1,4 +1,3 @@ - include_directories(include) add_subdirectory(source) diff --git a/Acquisition/Poll/source/CMakeLists.txt b/Acquisition/Poll/source/CMakeLists.txt index 86f4a8672..3d6cab51c 100644 --- a/Acquisition/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/Acquisition/Setup/CMakeLists.txt b/Acquisition/Setup/CMakeLists.txt index a2d332d4e..7f7855c04 100644 --- a/Acquisition/Setup/CMakeLists.txt +++ b/Acquisition/Setup/CMakeLists.txt @@ -1,3 +1,3 @@ +include_directories(include) add_subdirectory(source) - add_subdirectory(Traces) diff --git a/Analysis/CMakeLists.txt b/Analysis/CMakeLists.txt index 35a32783d..ad99e74d9 100644 --- a/Analysis/CMakeLists.txt +++ b/Analysis/CMakeLists.txt @@ -10,7 +10,7 @@ endif(USE_GSL) #Everything below is dependent on these two sets of libaries so we include the #headers. include_directories(Resources/include) -include_directories(ScanLib/include) +include_directories(ScanLibraries/include) if(USE_HRIBF) #Find HRIBF Libraries @@ -19,18 +19,17 @@ if(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) + 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(ScanLib) +add_subdirectory(ScanLibraries) add_subdirectory(Resources) #Build utilities. -add_subdirectory(util) - +add_subdirectory(Utilities) if(BUILD_UTKSCAN) - add_subdirectory(utkscan) + add_subdirectory(Utkscan) endif(BUILD_UTKSCAN) \ No newline at end of file diff --git a/Analysis/Resources/source/CMakeLists.txt b/Analysis/Resources/source/CMakeLists.txt index ebc50df5a..7e55755ab 100644 --- a/Analysis/Resources/source/CMakeLists.txt +++ b/Analysis/Resources/source/CMakeLists.txt @@ -3,15 +3,14 @@ set(ResourceSources PolynomialCfd.cpp TraditionalCfd.cpp) if (USE_GSL) if (${GSL_VERSION} GREATER 1.9) - set(ResourceSources ${ResourceSources} Gsl2Fitter.cpp) + list(APPEND ResourceSources Gsl2Fitter.cpp) else (${GSL_VERSION} LESS 2.0) - set(ResourceSources ${ResourceSources} Gsl1Fitter.cpp) + list(APPEND ResourceSources Gsl1Fitter.cpp) endif (${GSL_VERSION} GREATER 1.9) endif (USE_GSL) if (USE_ROOT) - set(ResourceSources ${ResourceSources} RootFitter.cpp - VandleTimingFunction.cpp) + list(APPEND ResourceSources RootFitter.cpp VandleTimingFunction.cpp) endif (USE_ROOT) #Add the sources to the library @@ -20,7 +19,7 @@ add_library(ResourceObjects OBJECT ${ResourceSources}) if (BUILD_SHARED_LIBS) message(STATUS "Building Utility Shared Objects") add_library(UtilityLibrary SHARED $) - target_link_libraries(UtilityLibrary PixieCoreStatic) + target_link_libraries(UtilityLibrary PaassCoreStatic) if (USE_ROOT) target_link_libraries(UtilityLibrary ${ROOT_LIBRARIES}) endif (USE_ROOT) diff --git a/Analysis/ScanLibraries/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt index 674926281..2c2e99346 100644 --- a/Analysis/ScanLibraries/source/CMakeLists.txt +++ b/Analysis/ScanLibraries/source/CMakeLists.txt @@ -1,28 +1,28 @@ #Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp +set(PaassScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp XiaListModeDataEncoder.cpp) if(USE_ROOT) - list(APPEND ScanSources RootScanner.cpp) + list(APPEND PaassScanSources RootScanner.cpp) endif(USE_ROOT) #Add the sources to the library -add_library(ScanObjects OBJECT ${ScanSources}) +add_library(PaassScanObjects OBJECT ${PaassScanSources}) if(BUILD_SHARED_LIBS) message(STATUS "Building Scan Shared Objects") - add_library(Scan SHARED $) - target_link_libraries(Scan PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) + add_library(PaassScan SHARED $) + target_link_libraries(PaassScan PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(Scan ${CURSES_LIBRARIES}) + target_link_libraries(PaassScan ${CURSES_LIBRARIES}) endif() - install(TARGETS Scan DESTINATION lib) + install(TARGETS PaassScan 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}) +add_library(PaassScanStatic STATIC $) +target_link_libraries(PaassScanStatic PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(ScanStatic ${CURSES_LIBRARIES}) + target_link_libraries(PaassScanStatic ${CURSES_LIBRARIES}) endif() diff --git a/Analysis/Utilities/source/CMakeLists.txt b/Analysis/Utilities/source/CMakeLists.txt index e6fe940a4..566a7f952 100644 --- a/Analysis/Utilities/source/CMakeLists.txt +++ b/Analysis/Utilities/source/CMakeLists.txt @@ -6,7 +6,7 @@ if(USE_ROOT AND BUILD_SCOPE) add_executable(scope scope.cpp) endif() - target_link_libraries(scope ScanStatic ${ROOT_LIBRARIES}) + target_link_libraries(scope PaassScanStatic ${ROOT_LIBRARIES}) install(TARGETS scope DESTINATION bin) endif(USE_ROOT AND BUILD_SCOPE) @@ -18,11 +18,11 @@ if(BUILD_SKELETON) add_executable(skeleton Skeleton.cpp) endif() - target_link_libraries(skeleton ScanStatic) + target_link_libraries(skeleton PaassScanStatic) install (TARGETS skeleton DESTINATION bin) endif(BUILD_SKELETON) # Install headReader executable. add_executable(headReader headReader.cpp) -target_link_libraries(headReader ScanStatic) +target_link_libraries(headReader PaassScanStatic) install (TARGETS headReader DESTINATION bin) diff --git a/Analysis/Utkscan/CMakeLists.txt b/Analysis/Utkscan/CMakeLists.txt index 35a82c207..802e9c6ef 100644 --- a/Analysis/Utkscan/CMakeLists.txt +++ b/Analysis/Utkscan/CMakeLists.txt @@ -70,8 +70,8 @@ else(USE_HRIBF) endif(NOT USE_HRIBF) #Add libraries to be linked with utkscan -target_link_libraries(${SCAN_NAME} ${LIBS} ScanStatic ResourceStatic - PixieCoreStatic) +target_link_libraries(${SCAN_NAME} ${LIBS} PaassScanStatic ResourceStatic + PaassCoreStatic ThirdPartyStatic) #If we have GSL installed link if(USE_GSL) diff --git a/Analysis/Utkscan/core/source/CMakeLists.txt b/Analysis/Utkscan/core/source/CMakeLists.txt index 9093a856f..c291d0414 100644 --- a/Analysis/Utkscan/core/source/CMakeLists.txt +++ b/Analysis/Utkscan/core/source/CMakeLists.txt @@ -31,10 +31,6 @@ set (PLOTTING_SOURCES PlotsRegister.cpp ) -set (XMLPARSER_SOURCES - pugixml.cpp -) - if(NOT USE_HRIBF) set(MAIN_SOURCES utkscan.cpp HisFile.cpp) else(USE_HRIBF) @@ -47,5 +43,4 @@ add_library(CoreObjects OBJECT ${CORE_SOURCES} ${CORRELATION_SOURCES} ${PLOTTING_SOURCES} - ${XMLPARSER_SOURCES} ) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6021e156..c8155da21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,11 @@ 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) @@ -52,7 +56,7 @@ 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_SUITE "Build and install Acquisition software" 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) @@ -65,7 +69,6 @@ option(USE_ROOT "Use ROOT" ON) #------------------------------------------------------------------------------ #Definitions with options - #The MCA will write DAMM histograms as output if(USE_DAMM) add_definitions("-D USE_DAMM") @@ -73,9 +76,9 @@ endif() #------------------------------------------------------------------------------ -#Find packages needed for poll2 +#Find packages needed for the #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) @@ -112,8 +115,7 @@ if (BUILD_SUITE) 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) @@ -141,38 +143,24 @@ if (USE_ROOT) endif() #------------------------------------------------------------------------------ -#Build the Core library +#First thing we need to do is build the PaassCoreLibrary. include_directories(Core/include) add_subdirectory(Core) -#Build the scan library -add_subdirectory(Scan) +#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) -#Building polling tools +#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_SUITE) - #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 the setup tools - if (BUILD_SETUP) - include_directories(Setup/include) - add_subdirectory(Setup) - endif() - - #Build poll - add_subdirectory(Poll) + 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/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/tests/CMakeLists.txt b/Core/tests/CMakeLists.txt index aecb8d9f0..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 PixieCoreStatic) +target_link_libraries(CTerminalTest PaassCoreStatic) install (TARGETS CTerminalTest DESTINATION bin) 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/Analysis/Utkscan/core/include/pugiconfig.hpp b/ThirdParty/include/pugiconfig.hpp similarity index 100% rename from Analysis/Utkscan/core/include/pugiconfig.hpp rename to ThirdParty/include/pugiconfig.hpp diff --git a/Analysis/Utkscan/core/include/pugixml.hpp b/ThirdParty/include/pugixml.hpp similarity index 100% rename from Analysis/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..cedd65672 --- /dev/null +++ b/ThirdParty/source/CMakeLists.txt @@ -0,0 +1,9 @@ +set(ThirdPartySources pugixml.cpp) + +add_library(ThirdPartyObjects OBJECT ${ThirdPartySources}) +add_library(ThirdPartyStatic STATIC $) + +if(BUILD_SHARED_LIBS) + add_library(ThirdParty SHARED $) + install(TARGETS ThirdParty DESTINATION lib) +endif(BUILD_SHARED_LIBS) \ No newline at end of file diff --git a/Analysis/Utkscan/core/source/pugixml.cpp b/ThirdParty/source/pugixml.cpp similarity index 100% rename from Analysis/Utkscan/core/source/pugixml.cpp rename to ThirdParty/source/pugixml.cpp From 099c8542ad4262c214e9b59ab9c78e794cdd9685 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 31 Jan 2017 09:56:33 -0500 Subject: [PATCH 138/255] Populating the Resources directory with things that will be useful. --- Analysis/Resources/tests/CMakeLists.txt | 4 ---- CMakeLists.txt | 8 +++++++- Resources/CMakeLists.txt | 3 +++ .../include/HelperEnumerations.hpp | 0 .../Resources => Resources}/include/HelperFunctions.hpp | 0 .../include/UnitTestSampleData.hpp | 0 Resources/source/CMakeLists.txt | 0 Resources/tests/CMakeLists.txt | 3 +++ .../tests/unittest-HelperFunctions.cpp | 0 9 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 Resources/CMakeLists.txt rename {Analysis/Resources => Resources}/include/HelperEnumerations.hpp (100%) rename {Analysis/Resources => Resources}/include/HelperFunctions.hpp (100%) rename {Analysis/Resources => Resources}/include/UnitTestSampleData.hpp (100%) create mode 100644 Resources/source/CMakeLists.txt create mode 100644 Resources/tests/CMakeLists.txt rename {Analysis/Resources => Resources}/tests/unittest-HelperFunctions.cpp (100%) diff --git a/Analysis/Resources/tests/CMakeLists.txt b/Analysis/Resources/tests/CMakeLists.txt index 42539aee6..da282c994 100644 --- a/Analysis/Resources/tests/CMakeLists.txt +++ b/Analysis/Resources/tests/CMakeLists.txt @@ -12,10 +12,6 @@ if (USE_GSL) install(TARGETS unittest-GslFitter DESTINATION bin/unittests) endif (USE_GSL) -add_executable(unittest-HelperFunctions unittest-HelperFunctions.cpp) -target_link_libraries(unittest-HelperFunctions UnitTest++) -install(TARGETS unittest-HelperFunctions DESTINATION bin/unittests) - add_executable(unittest-PolynomialCfd unittest-PolynomialCfd.cpp ../source/PolynomialCfd.cpp) target_link_libraries(unittest-PolynomialCfd UnitTest++) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8155da21..564cf1939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,11 @@ if (USE_ROOT) endif() #------------------------------------------------------------------------------ -#First thing we need to do is build the PaassCoreLibrary. +#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) @@ -153,6 +157,8 @@ include_directories(ThirdParty/include) #fancy logic in the base directory. add_subdirectory(ThirdParty) + + #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_SUITE) 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/Analysis/Resources/include/HelperEnumerations.hpp b/Resources/include/HelperEnumerations.hpp similarity index 100% rename from Analysis/Resources/include/HelperEnumerations.hpp rename to Resources/include/HelperEnumerations.hpp diff --git a/Analysis/Resources/include/HelperFunctions.hpp b/Resources/include/HelperFunctions.hpp similarity index 100% rename from Analysis/Resources/include/HelperFunctions.hpp rename to Resources/include/HelperFunctions.hpp diff --git a/Analysis/Resources/include/UnitTestSampleData.hpp b/Resources/include/UnitTestSampleData.hpp similarity index 100% rename from Analysis/Resources/include/UnitTestSampleData.hpp rename to Resources/include/UnitTestSampleData.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/Analysis/Resources/tests/unittest-HelperFunctions.cpp b/Resources/tests/unittest-HelperFunctions.cpp similarity index 100% rename from Analysis/Resources/tests/unittest-HelperFunctions.cpp rename to Resources/tests/unittest-HelperFunctions.cpp From b24e4440459b3051a4e16ace2c9df8b7d2fe8aa8 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 31 Jan 2017 12:19:45 -0500 Subject: [PATCH 139/255] Changing how 3rd party libraries are built. Fixing main CMakeLists The CMakeLists.txt had a few things that needed tweaked for the code review. I renamed BUILD_SUITE to BUILD_ACQ. This now removes nearly all of the the PixieSuite left overs. I also cleaned up some of the comments. The ThirdParty libraries are now built into individual libraries instead of one big one. This should make it easier for users who only need specific libraries to link against them. --- CMakeLists.txt | 21 +++++++++------------ ThirdParty/source/CMakeLists.txt | 15 +++++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 564cf1939..c3be8d896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,11 +52,11 @@ 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 Acquisition software" 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) @@ -68,15 +68,14 @@ option(USE_ROOT "Use ROOT" ON) #------------------------------------------------------------------------------ -#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 the +#Find packages needed for the software. #Load additional find_package scripts. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/Cmake/modules/") @@ -109,9 +108,9 @@ if(BUILD_UNITTESTS) include_directories(${UNITTEST++_INCLUDE_DIR}) endif(BUILD_UNITTESTS) -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) +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) @@ -128,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) @@ -157,11 +156,9 @@ include_directories(ThirdParty/include) #fancy logic in the base directory. add_subdirectory(ThirdParty) - - #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_SUITE) +if (BUILD_ACQ) add_subdirectory(Acquisition) endif() diff --git a/ThirdParty/source/CMakeLists.txt b/ThirdParty/source/CMakeLists.txt index cedd65672..8cfbf14b1 100644 --- a/ThirdParty/source/CMakeLists.txt +++ b/ThirdParty/source/CMakeLists.txt @@ -1,9 +1,12 @@ -set(ThirdPartySources pugixml.cpp) - -add_library(ThirdPartyObjects OBJECT ${ThirdPartySources}) -add_library(ThirdPartyStatic STATIC $) +#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(ThirdParty SHARED $) - install(TARGETS ThirdParty DESTINATION lib) + add_library(Pugixml SHARED $) + install(TARGETS Pugixml DESTINATION lib) endif(BUILD_SHARED_LIBS) \ No newline at end of file From c8147ea8c500a75e4d04ffa9e0a609b92ef58ba4 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 31 Jan 2017 12:20:03 -0500 Subject: [PATCH 140/255] Forgot to stage a change to the utkscan CMakeLists --- Analysis/Utkscan/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/Utkscan/CMakeLists.txt b/Analysis/Utkscan/CMakeLists.txt index 802e9c6ef..5e273441d 100644 --- a/Analysis/Utkscan/CMakeLists.txt +++ b/Analysis/Utkscan/CMakeLists.txt @@ -71,7 +71,7 @@ endif(NOT USE_HRIBF) #Add libraries to be linked with utkscan target_link_libraries(${SCAN_NAME} ${LIBS} PaassScanStatic ResourceStatic - PaassCoreStatic ThirdPartyStatic) + PaassCoreStatic PugixmlStatic) #If we have GSL installed link if(USE_GSL) From 2d47acad358630f57adeb2739aacce8708772b68 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 1 Feb 2017 10:21:32 -0500 Subject: [PATCH 141/255] Updating doxyfile to accomodate changes to directory structure. --- Doc/doxyfile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Doc/doxyfile b/Doc/doxyfile index df37b8156..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,8 +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 = ./Core cmake doc/pages/ Interface MCA Poll \ - PxiDump Scan Setup +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 @@ -812,11 +812,8 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = Scan/utkscan/core/include/pugiconfig.hpp \ - Scan/utkscan/core/include/pugixml.hpp \ - Scan/utkscan/core/source/pugixml.cpp \ - Scan/utkscan/include/MersenneTwister.hpp \ - 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 @@ -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 From 23f4d92263b699abb89c047d8fa454a0d2574367 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 23 Jan 2017 14:04:49 -0500 Subject: [PATCH 142/255] Tells the user where to go to find more information about the firmware. --- Scan/ScanLib/source/ScanInterface.cpp | 1146 +++++++++++++++++++++++++ 1 file changed, 1146 insertions(+) create mode 100644 Scan/ScanLib/source/ScanInterface.cpp diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp new file mode 100644 index 000000000..fecb384aa --- /dev/null +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -0,0 +1,1146 @@ +/** \file ScanInterface.cpp + * \brief A class to handle reading from various UTK/ORNL pixie16 data formats. + * + * This class is intended to be used as a replacement to the older and unsupported + * 'scanor' program from the UPAK acq library specifically for .ldf files which are + * constructed using the UTK/ORNL pixie16 style. This class also interfaces with poll2 + * shared memory output without the need to use pacman. + * CRT + * + * \author C. R. Thornsberry + * \date Feb. 12th, 2016 + */ +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "Unpacker.hpp" +#include "poll2_socket.h" +#include "CTerminal.h" + +#include "ScanInterface.hpp" + +#ifndef PROG_NAME +#define PROG_NAME "ScanInterface" +#endif + +void start_run_control(ScanInterface *main_){ + main_->RunControl(); +} + +void start_cmd_control(ScanInterface *main_){ + main_->CmdControl(); +} + +///////////////////////////////////////////////////////////////////// +// class optionExt +///////////////////////////////////////////////////////////////////// + +optionExt::optionExt(const char *name_, const int &has_arg_, int *flag_, const int &val_, const std::string &argstr_, const std::string &helpstr_) : + name(name_), has_arg(has_arg_), flag(flag_), val(val_), argstr(argstr_), helpstr(helpstr_), active(false) { +} + +void optionExt::print(const size_t &len_/*=0*/, const std::string &prefix_/*=""*/){ + std::stringstream stream; + stream << prefix_ << "--" << name << " "; + if(val) stream << "(-" << (char)val << ") "; + stream << argstr; + + if(stream.str().length() < len_) + stream << std::string(len_ - stream.str().length(), ' '); + + stream << "- " << helpstr; + std::cout << stream.str() << std::endl; +} + +option optionExt::getOption(){ + struct option output; + output.name = name; + output.has_arg = has_arg; + output.flag = flag; + output.val = val; + return output; +} + +///////////////////////////////////////////////////////////////////// +// class fileInformation +///////////////////////////////////////////////////////////////////// + +bool fileInformation::at(const size_t &index_, std::string &name, std::string &value){ + if(index_ >= parnames.size()){ return false; } + name = parnames.at(index_); + value = parvalues.at(index_); + return true; +} + +template +bool fileInformation::push_back(const std::string & name_, const T &value_, const std::string &units_/*=""*/){ + if(!is_in(name_)){ + std::stringstream stream; + stream << value_; + if(units_.size() > 0){ + stream << " " << units_; + } + parnames.push_back(name_); + parvalues.push_back(stream.str()); + return true; + } + return false; +} + +bool fileInformation::is_in(const std::string & name_){ + for(std::vector::iterator iter = parnames.begin(); iter != parnames.end(); iter++){ + if(name_ == (*iter)){ return true; } + } + return false; +} + +std::string fileInformation::print(const size_t &index_){ + if(index_ >= parnames.size()){ return ""; } + return std::string(parnames.at(index_) + ": " + parvalues.at(index_)); +} + +void fileInformation::clear(){ + parnames.clear(); + parvalues.clear(); +} + +///////////////////////////////////////////////////////////////////// +// class ScanInterface +///////////////////////////////////////////////////////////////////// + +/** Start the scan, if ScanInterface is initialized and is not already running. + * \return Nothing. + */ +void ScanInterface::start_scan(){ + if(!(file_open || shm_mode)) + std::cout << " No input file loaded.\n"; + else if(!input_file.good()) + std::cout << " Error reading from input file!\n"; + else if(input_file.eof()) + std::cout << " Physical end-of-file reached.\n"; + else if(is_running) + std::cout << " Already running.\n"; + else{ + core->Run(); + is_running = true; + total_stopped = false; + if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Waiting for Unpacker..."); } + + // Notify that the user has started the scan. + Notify("START_SCAN"); + } +} + +/** Stop the scan, if it is running. + * \return Nothing. + */ +void ScanInterface::stop_scan(){ + if(!scan_init){ std::cout << " Not initialized!\n"; } + else if(!is_running){ std::cout << " Not running.\n"; } + else{ + core->Stop(); + is_running = false; + if(!batch_mode){ term->SetStatus("\033[0;31m[STOP]\033[0m Acquisition stopped.");} + else{ std::cout << "\033[0;31m[STOP]\033[0m Acquisition stopped.\n"; } + } + + // Notify that the user has stopped the scan. + Notify("STOP_SCAN"); +} + +/** Print a command line argument help dialogue. + * \param[in] name_ The name of the program. + * \return Nothing. + */ +void ScanInterface::help(char *name_){ + SyntaxStr(name_); + std::cout << " Available options:\n"; + for(std::vector::iterator iter = baseOpts.begin(); iter != baseOpts.end(); iter++){ + if(!iter->name) continue; + iter->print(40, " "); + } + for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ + if(!iter->name) continue; + iter->print(40, " "); + } +} + +/** Seek to a specified position in the file. + * \param[in] offset_ The position, with respect to the start of the file, to seek to. + * \return True upon success and false otherwise. + */ +bool ScanInterface::rewind(const unsigned long &offset_/*=0*/){ + if(!scan_init){ return false; } + + // Ensure that the scan is not running. + if(!(file_open || shm_mode)){ + std::cout << " No input file loaded.\n"; + return false; + } + else if(is_running){ + std::cout << " Cannot change file position while scan is running!\n"; + return false; + } + + // Move to the first word in the file. + std::cout << " Seeking to word no. " << offset_ << " in file\n"; + input_file.seekg(offset_*4, input_file.beg); + std::cout << " Input file is now at " << input_file.tellg() << " bytes\n"; + + // Notify that the user has rewound to the start of the file. + Notify("REWIND_FILE"); + + return true; +} + +/** Open a new binary input file for reading. + * \param[in] fname_ Input filename to open for reading. + * \return True upon successfully opening the file and false otherwise. + */ +bool ScanInterface::open_input_file(const std::string &fname_){ + if(is_running){ + std::cout << " ERROR! Unable to open input file while scan is running.\n"; + return false; + } + else if(shm_mode){ + std::cout << " ERROR! Unable to open input file in shm mode.\n"; + return false; + } + + extension = get_extension(fname_, prefix); + if(prefix == ""){ + std::cout << " ERROR! Input filename was not specified!\n"; + return false; + } + + if(extension == "ldf"){ // List data format file + file_format = 0; + } + else if(extension == "pld"){ // Pixie list data file format + file_format = 1; + } + else{ + std::cout << " ERROR! Invalid file format '" << extension << "'\n"; + std::cout << " The current valid data formats are:\n"; + std::cout << " ldf - list data format (HRIBF)\n"; + std::cout << " pld - pixie list data format\n"; + return false; + } + + // Close the previous file, if one is open. + if(file_open){ + std::cout << " Note: Closing previously opened file.\n"; + input_file.close(); + } + + file_open = true; + + // Load the input file. + input_file.open(fname_.c_str(), std::ios::binary); + if(!input_file.is_open() || !input_file.good()){ + std::cout << " ERROR! Failed to open input file '" << fname_ << "'! Check that the path is correct.\n"; + input_file.close(); + file_open = false; + return false; + } + input_file.seekg(0, input_file.end); + file_length = input_file.tellg(); + input_file.seekg(0, input_file.beg); + + if(!shm_mode){ + // Clear the file information container. + finfo.clear(); + + // Start reading the file + // Every poll2 ldf file starts with a DIR buffer followed by a HEAD buffer + int num_buffers; + if(file_format == 0){ + dirbuff.Read(&input_file); + headbuff.Read(&input_file); + + // Store the file information for later use. + finfo.push_back("Run number", dirbuff.GetRunNumber()); + finfo.push_back("Number buffers", num_buffers); + finfo.push_back("Facility", headbuff.GetFacility()); + finfo.push_back("Format", headbuff.GetFormat()); + finfo.push_back("Type", headbuff.GetType()); + finfo.push_back("Date", headbuff.GetDate()); + finfo.push_back("Title", headbuff.GetRunTitle()); + + dirbuff.Print(); + headbuff.Print(); + std::cout << std::endl; + } + else if(file_format == 1){ + pldHead.Read(&input_file); + + max_spill_size = pldHead.GetMaxSpillSize(); + + // Store the file information for later use. + finfo.push_back("Facility", pldHead.GetFacility()); + finfo.push_back("Format", pldHead.GetFormat()); + finfo.push_back("Start", pldHead.GetStartDate()); + finfo.push_back("Stop", pldHead.GetEndDate()); + finfo.push_back("Title", pldHead.GetRunTitle()); + finfo.push_back("Run number", pldHead.GetRunNumber()); + finfo.push_back("Max spill", max_spill_size, "words"); + finfo.push_back("ACQ time", pldHead.GetRunTime(), "seconds"); + + pldHead.Print(); + std::cout << std::endl; + } + } + + // Notify that the user has loaded a new file. + Notify("LOAD_FILE"); + + return true; +} + +/** Add a command line option to the option list. + * \param[in] opt_ The option to add to the list. + * \return Nothing. + */ +void ScanInterface::AddOption(optionExt opt_){ + char tempChar = opt_.val; + if(tempChar){ + if(optstr.find(tempChar) != std::string::npos) + opt_.val = 0x0; + else{ + optstr += tempChar; + if(opt_.has_arg == required_argument) + optstr += ":"; + else if(opt_.has_arg == optional_argument) + optstr += "::"; + } + } + userOpts.push_back(opt_); +} + +/** SyntaxStr is used to print a linux style usage message to the screen. + * Prints a standard usage message by default. + * \param[in] name_ The name of the program. + * \return Nothing. + */ +void ScanInterface::SyntaxStr(char *name_){ + std::cout << " usage: " << name_ << " [options]\n"; +} + +/** Initialize the Unpacker object. + * Does nothing useful by default. + * \param[in] prefix_ String to append to the beginning of system output. + * \return True upon successfully initializing and false otherwise. + */ +bool ScanInterface::Initialize(std::string prefix_){ + if(scan_init){ return false; } + return (scan_init = true); +} + +/** Return a pointer to the Unpacker object to use for data unpacking. + * If no object has been initialized, create a new one. + * \return Pointer to an Unpacker object. + */ +Unpacker *ScanInterface::GetCore(){ + if(!core){ core = new Unpacker(); } + return core; +} + +/** Default constructor. + * \param[in] core_ Pointer to an object derived from Unpacker. + */ +ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ + prefix = ""; + extension = ""; + + // Get the current working directory. + char workingDirectory[1024]; + workDir = std::string(getcwd(workingDirectory, 1024)); + + // Get the home directory. + homeDir = getenv("HOME"); + + maxShmSizeL = 4052; + maxShmSize = maxShmSizeL * 4; + + max_spill_size = 0; + file_format = -1; + + file_start_offset = 0; + num_spills_recvd = 0; + + total_stopped = true; + write_counts = false; + is_running = false; + is_verbose = true; + debug_mode = false; + dry_run_mode = false; + shm_mode = false; + batch_mode = false; + scan_init = false; + file_open = false; + + //Initialize the setup and output file names + output_filename = ""; + setup_filename = ""; + + kill_all = false; + run_ctrl_exit = false; + + poll_server = NULL; + term = NULL; + + // Set the Unpacker pointer, if one is specified. + if(core_){ core = core_; } + else{ core = NULL; } + + //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"), + 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 + ": "; +} + +/// Default destructor. +ScanInterface::~ScanInterface(){ + Close(); +} + +/// Main scan control method. +void ScanInterface::RunControl(){ + // Notify that we are starting run control. + run_ctrl_exit = false; + + // Set debug mode, if enabled. + if(debug_mode){ + pldHead.SetDebugMode(); + pldData.SetDebugMode(); + dirbuff.SetDebugMode(); + headbuff.SetDebugMode(); + databuff.SetDebugMode(); + eofbuff.SetDebugMode(); + } + + while(true){ + if(kill_all){ break; } + + // Now we're ready to read the first data buffer + if(total_stopped){ + // Sleep while waiting for the user to scan more data. + IdleTask(); + usleep(0.1); + continue; + } + else if(shm_mode){ + std::cout << std::endl; + unsigned int data[250000]; // Array for storing spill data. Larger than any RevF spill should be. + unsigned int *shm_data = new unsigned int[maxShmSizeL]; // Array to store the temporary shm data (~16 kB) + int dummy; + int previous_chunk; + int current_chunk; + int total_chunks; + int nWords; + unsigned int nTotalWords; + + bool full_spill = false; + + while(true){ + if(kill_all == true){ + break; + } + else if(!is_running){ + IdleTask(); + usleep(100000); //0.1 seconds + continue; + } + + int select_dummy; + previous_chunk = 0; + current_chunk = 0; + total_chunks = -1; + nTotalWords = 0; + full_spill = true; + + if(!poll_server->Select(dummy)){ + if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Waiting for a spill..."); } + else{ std::cout << "\r\033[0;33m[IDLE]\033[0m Waiting for a spill..."; } + IdleTask(); + continue; + } + + if(!poll_server->Select(select_dummy)){ continue; } // Server timeout + + // Get the spill + while(current_chunk != total_chunks){ + if(!poll_server->Select(select_dummy)){ // Server timeout + std::cout << msgHeader << "Network timeout before recv full spill!\n"; + full_spill = false; + break; + } + + nWords = poll_server->RecvMessage((char*)shm_data, maxShmSize) / 4; // Read from the socket + if(strcmp((char*)shm_data, "$CLOSE_FILE") == 0 || strcmp((char*)shm_data, "$OPEN_FILE") == 0 || strcmp((char*)shm_data, "$KILL_SOCKET") == 0){ continue; } // Poll2 network flags + // Did not read enough bytes + else if(nWords < 2){ + continue; + } + + if(debug_mode){ std::cout << "debug: Received " << nWords << " words from the network\n"; } + memcpy((char *)¤t_chunk, &shm_data[0], 4); + memcpy((char *)&total_chunks, &shm_data[1], 4); + + if(previous_chunk == -1 && current_chunk != 1){ // Started reading in the middle of a spill, ignore the rest of it + if(debug_mode){ std::cout << "debug: Skipping chunk " << current_chunk << " of " << total_chunks << std::endl; } + continue; + } + else if(previous_chunk != current_chunk - 1){ // We missed a spill chunk somewhere + if(debug_mode){ std::cout << "debug: Found chunk " << current_chunk << " but expected chunk " << previous_chunk+1 << std::endl; } + break; + } + + previous_chunk = current_chunk; + + // Copy the shm spill chunk into the data array + if(nTotalWords + 2 + nWords <= 250000){ // This spill chunk will fit into the data buffer + memcpy(&data[nTotalWords], &shm_data[2], (nWords - 2)*4); + nTotalWords += (nWords - 2); + } + else{ + if(debug_mode){ std::cout << "debug: Abnormally full spill buffer with " << nTotalWords + 2 + nWords << " words!\n"; } + break; + } + } + + std::stringstream status; + status << "\033[0;32m" << "[RECV] " << "\033[0m" << nTotalWords << " words"; + if(!batch_mode){ term->SetStatus(status.str()); } + else{ std::cout << "\r" << status.str(); } + + if(debug_mode){ std::cout << "debug: Retrieved spill of " << nTotalWords << " words (" << nTotalWords*4 << " bytes)\n"; } + if(!dry_run_mode && full_spill){ + int word1 = 2, word2 = 9999; + memcpy(&data[nTotalWords], (char *)&word1, 4); + memcpy(&data[nTotalWords+1], (char *)&word2, 4); + core->ReadSpill(data, nTotalWords + 2, is_verbose); + IdleTask(); + } + + if(!full_spill){ std::cout << msgHeader << "Not processing spill fragment!\n"; } + else{ num_spills_recvd++; } + } + + delete[] shm_data; + } + else if(file_format == 0){ + unsigned int *data = NULL; + bool full_spill; + bool bad_spill; + unsigned int nBytes; + + if(!dry_run_mode){ data = new unsigned int[250000]; } + + // Reset the buffer reader to default values. + databuff.Reset(); + + while(true){ + if(kill_all == true){ + break; + } + else if(!is_running){ + IdleTask(); + usleep(100000); //0.1 seconds + continue; + } + + if(!databuff.Read(&input_file, (char*)data, nBytes, 1000000, full_spill, bad_spill, dry_run_mode)){ + if(databuff.GetRetval() == 1){ + if(debug_mode){ std::cout << "debug: Encountered single EOF buffer (end of run).\n"; } + } + else if(databuff.GetRetval() == 2){ + if(debug_mode){ std::cout << "debug: Encountered double EOF buffer (end of file).\n"; } + break; + } + else if(databuff.GetRetval() == 3){ + if(debug_mode){ std::cout << "debug: Encountered unknown ldf buffer type.\n"; } + } + else if(databuff.GetRetval() == 4){ + if(debug_mode){ std::cout << "debug: Encountered invalid spill chunk.\n"; } + } + else if(databuff.GetRetval() == 5){ + if(debug_mode){ std::cout << "debug: Received bad spill footer size.\n"; } + } + else if(databuff.GetRetval() == 6){ + if(debug_mode){ std::cout << "debug: Failed to read buffer from input file.\n"; } + break; + } + continue; + } + + std::stringstream status; + status << "\033[0;32m" << "[READ] " << "\033[0m" << nBytes/4 << " words (" << 100*input_file.tellg()/file_length << "%), "; + status << "GOOD = " << databuff.GetNumChunks() << ", LOST = " << databuff.GetNumMissing(); + if(!batch_mode){ term->SetStatus(status.str()); } + else{ std::cout << "\r" << status.str(); } + + if(full_spill){ + if(debug_mode){ + std::cout << "debug: Retrieved spill of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; + std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; + } + if(!dry_run_mode){ + if(!bad_spill){ + core->ReadSpill(data, nBytes/4, is_verbose); + IdleTask(); + } + else{ std::cout << " WARNING: Spill has been flagged as corrupt, skipping (at word " << input_file.tellg()/4 << " in file)!\n"; } + } + } + else if(debug_mode){ + std::cout << "debug: Retrieved spill fragment of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; + std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; + } + num_spills_recvd++; + } + + if(!dry_run_mode){ delete[] data; } + + if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Finished scanning file."); } + else{ std::cout << std::endl << std::endl; } + } + else if(file_format == 1){ + unsigned int *data = NULL; + unsigned int nBytes; + + if(!dry_run_mode){ data = new unsigned int[max_spill_size+2]; } + + // Reset the buffer reader to default values. + pldData.Reset(); + + while(pldData.Read(&input_file, (char*)data, nBytes, + 4*max_spill_size, dry_run_mode)){ + if(kill_all == true){ + break; + } + else if(!is_running){ + IdleTask(); + usleep(100000); //0.1 seconds + continue; + } + + std::stringstream status; + status << "\033[0;32m" << "[READ] " << "\033[0m" << nBytes/4 << " words (" << 100*input_file.tellg()/file_length << "%)"; + if(!batch_mode){ term->SetStatus(status.str()); } + else{ std::cout << "\r" << status.str(); } + + if(debug_mode){ + std::cout << "debug: Retrieved spill of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; + std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; + } + + if(!dry_run_mode){ + int word1 = 2, word2 = 9999; + memcpy(&data[(nBytes/4)], (char *)&word1, 4); + memcpy(&data[(nBytes/4)+1], (char *)&word2, 4); + core->ReadSpill(data, nBytes/4 + 2, is_verbose); + IdleTask(); + } + num_spills_recvd++; + } + + if(eofbuff.ReadHeader(&input_file)){ + std::cout << msgHeader << "Encountered EOF buffer.\n"; + } + else{ + std::cout << msgHeader << "Failed to find end of file buffer!\n"; + } + + if(!dry_run_mode){ delete[] data; } + + if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Finished scanning file."); } + else{ std::cout << std::endl << std::endl; } + } + else if(file_format == 2){ + } + + // Notify that the scan has completed. + Notify("SCAN_COMPLETE"); + + total_stopped = true; + stop_scan(); + + if(batch_mode){ break; } + } + + // Notify that run control is exiting. + run_ctrl_exit = true; +} + +/// Main command interpreter method. +void ScanInterface::CmdControl(){ + if(!core){ return; } + + std::string cmd = "", arg; + bool waiting_for_run = false; + + while(true){ + if(run_ctrl_exit){ break; } + + if(waiting_for_run){ + if(!is_running){ waiting_for_run = false; } + else{ + term->flush(); // Update the terminal so the user knows something is happening. + sleep(1); // Sleep and wait for the run to finish. + continue; + } + } + + cmd = term->GetCommand(arg); + if(cmd == "_SIGSEGV_"){ + std::cout << "\033[0;31m[SEGMENTATION FAULT]\033[0m\n"; + exit(EXIT_FAILURE); + } + else if(cmd == "CTRL_D"){ + std::cout << msgHeader << "Received EOF (ctrl-d) signal. Exiting...\n"; + cmd = "quit"; + } + else if(cmd == "CTRL_C"){ + std::cout << msgHeader << "Warning! Received SIGINT (ctrl-c) signal.\n"; + continue; + } + else if(cmd == "CTRL_Z"){ + std::cout << msgHeader << "Warning! Received SIGTSTP (ctrl-z) signal.\n"; + continue; + } + term->flush(); + + if(cmd == ""){ continue; } + + // Replace the '~' with the user's home directory. + if(!arg.empty() && arg.find('~') != std::string::npos) + arg.replace(arg.find('~'), 1, homeDir); + + std::vector arguments; + unsigned int p_args = split_str(arg, arguments); + + if(cmd == "quit" || cmd == "exit"){ + stop_scan(); + kill_all = true; + while(!run_ctrl_exit){ sleep(1); } + break; + } + else if(cmd == "version" || cmd == "v"){ + std::cout << " " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n"; + std::cout << " Poll2 Socket v" << POLL2_SOCKET_VERSION << " (" << POLL2_SOCKET_DATE << ")\n"; + std::cout << " HRIBF Buffers v" << HRIBF_BUFFERS_VERSION << " (" << HRIBF_BUFFERS_DATE << ")\n"; + std::cout << " CTerminal v" << CTERMINAL_VERSION << " (" << CTERMINAL_DATE << ")\n"; + } + else if(cmd == "help" || cmd == "h"){ + std::cout << " Help:\n"; + std::cout << " debug - Toggle debug mode flag (default=false)\n"; + std::cout << " quiet - Toggle quiet mode flag (default=false)\n"; + std::cout << " quit - Close the program\n"; + std::cout << " help (h) - Display this dialogue\n"; + std::cout << " version (v) - Display Poll2 version information\n"; + std::cout << " run - Start acquisition\n"; + std::cout << " stop - Stop acquisition\n"; + std::cout << " file - Load an input file\n"; + std::cout << " rewind [offset] - Rewind to the beginning of the file\n"; + std::cout << " sync - Wait for the current run to finish\n"; + CmdHelp(" "); + } + else if(cmd == "run"){ // Start acquisition. + start_scan(); + } + else if(cmd == "stop"){ // Stop acquisition. + stop_scan(); + } + else if(cmd == "debug"){ // Toggle debug mode + if(debug_mode){ + std::cout << msgHeader << "Toggling debug mode OFF\n"; + debug_mode = false; + } + else{ + std::cout << msgHeader << "Toggling debug mode ON\n"; + debug_mode = true; + } + core->SetDebugMode(debug_mode); + } + else if(cmd == "quiet"){ // Toggle quiet mode + if(!is_verbose){ + std::cout << msgHeader << "Toggling quiet mode OFF\n"; + is_verbose = true; + } + else{ + std::cout << msgHeader << "Toggling quiet mode ON\n"; + is_verbose = false; + } + } + else if(cmd == "file"){ // Rewind the file to the start position + if(p_args > 0){ + if(!open_input_file(arguments.at(0))){ + std::cout << msgHeader << "Failed to open input file!\n"; + } + } + else{ + std::cout << msgHeader << "Invalid number of parameters to 'file'\n"; + std::cout << msgHeader << " -SYNTAX- file \n"; + } + } + else if(cmd == "rewind"){ // Rewind the file to the start position + if(p_args > 0){ rewind(strtoul(arguments.at(0).c_str(), NULL, 0)); } + else{ rewind(); } + } + else if(cmd == "sync"){ // Wait until the current run is completed. + if(is_running){ + std::cout << msgHeader << "Waiting for current scan to complete.\n"; + waiting_for_run = true; + } + else{ std::cout << msgHeader << "Scan is not running.\n"; } + } + else if(!ExtraCommands(cmd, arguments)){ // Unrecognized command. Send it to a derived object. + std::cout << msgHeader << "Unknown command '" << cmd << "'\n"; + } + } +} + +/** Setup user options and initialize all required objects. + * \param[in] argc Number of arguments passed from the command line. + * \param[in] argv Array of strings passed as arguments from the command line. + * \return True upon success and false otherwise. + */ +bool ScanInterface::Setup(int argc, char *argv[]){ + if(scan_init) + return false; + + debug_mode = false; + 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. + this->ArgHelp(); + + // Build the vector of all command line options. + for(std::vector::iterator iter = baseOpts.begin(); iter != baseOpts.end(); iter++){ + longOpts.push_back(iter->getOption()); + } + for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ + longOpts.push_back(iter->getOption()); + } + + // Append all zeros onto the option list. Required for getopt_long. + struct option zero_opt { 0, 0, 0, 0 }; + longOpts.push_back(zero_opt); + + int idx = 0; + int retval = 0; + + //getopt_long is not POSIX compliant. It is provided by GNU. This may mean + //that we are not compatible with some systems. If we have enough + //complaints we can either change it to getopt, or implement our own class. + while ( (retval = getopt_long(argc, argv, optstr.c_str(), longOpts.data(), &idx)) != -1) { + if(retval == 0x0){ // Long option + if(strcmp("config", longOpts[idx].name) == 0) { + setup_filename = optarg; + } + else if(strcmp("counts", longOpts[idx].name) == 0) { + write_counts = true; + } + else if(strcmp("debug", longOpts[idx].name) == 0 ) { + debug_mode = true; + } + else if(strcmp("dry-run", longOpts[idx].name) == 0) { + dry_run_mode = true; + } + 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){ + iter->active = true; + if(optarg) + iter->argument = std::string(optarg); + break; + } + } + } + } + else if(retval == 0x3F){ // Unknown option, '?' + return false; + } + else{ // Single character option. + switch(retval) { + case 'b' : + batch_mode = true; + break; + case 'c' : + setup_filename = optarg; + break; + case 'f' : + firmware = optarg; + break; + case 'h' : + help(argv[0]); + return false; + case 'i' : + input_filename = optarg; + break; + case 'o' : + output_filename = optarg; + break; + case 'q' : + is_verbose = false; + break; + case 's': + file_format = 0; + shm_mode = true; + break; + case 'v' : + std::cout << " " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n" ; + std::cout << " Poll2 Socket v" << POLL2_SOCKET_VERSION << " (" << POLL2_SOCKET_DATE << ")\n"; + std::cout << " HRIBF Buffers v" << HRIBF_BUFFERS_VERSION << " (" << HRIBF_BUFFERS_DATE << ")\n"; + std::cout << " CTerminal v" << CTERMINAL_VERSION << " (" << CTERMINAL_DATE << ")\n"; + return false; + default : + for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ + if(retval == iter->val){ + iter->active = true; + if(optarg) + iter->argument = std::string(optarg); + break; + } + } + break; + } + } + }//while + + // If a pointer to an Unpacker derived class is not specified, call the + // extern function GetCore() to get a pointer to a new object. + if(!core) + GetCore(); + + // 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(); + + // Parse for any extra arguments that are known to the derived class. + ExtraArguments(); + + // Initialize everything. + std::cout << msgHeader << "Initializing derived class.\n"; + if(!Initialize(msgHeader)){ // Failed to initialize the object. Clean up and exit. + std::cout << " FATAL ERROR! Failed to initialize derived class!\n"; + std::cout << "\nCleaning up...\n"; + return false; + } + +#ifndef USE_HRIBF + if(shm_mode){ + poll_server = new Server(); + if(!poll_server->Init(5555, 1)){ + std::cout << " FATAL ERROR! Failed to open shm socket 5555!\n"; + std::cout << "\nCleaning up...\n"; + return false; + } + if(batch_mode){ + std::cout << msgHeader << "Unable to enable batch mode for shared-memory mode!\n"; + batch_mode = false; + } + } + + // Initialize the terminal. + if(!batch_mode){ + term = new Terminal(); + term->Initialize(); + term->SetCommandHistory(("."+progName+".cmd").c_str()); + term->SetPrompt((progName+" $ ").c_str()); + term->AddStatusWindow(); + term->SetStatus("\033[0;31m[STOP]\033[0m Acquisition stopped."); + } + + std::cout << "\n " << PROG_NAME << " v" << SCAN_VERSION << "\n"; + std::cout << " == == == == == \n\n"; + + if(debug_mode){ std::cout << msgHeader << "Using debug mode.\n\n"; } + if(dry_run_mode){ std::cout << msgHeader << "Doing a dry run.\n\n"; } + if(shm_mode){ + std::cout << msgHeader << "Using shared-memory mode.\n\n"; + std::cout << msgHeader << "Listening on poll2 SHM port 5555\n\n"; + } + + // Load the input file, if the user has supplied a filename. + if(!shm_mode && !input_filename.empty()){ + std::cout << msgHeader << "Using filename " << input_filename << ".\n"; + if(open_input_file(input_filename)){ + // Start the scan. + start_scan(); + } + else{ std::cout << msgHeader << "Failed to load input file!\n"; } + } +#endif + + // Do any last minute initialization. + try { + FinalInitialization(); + } + catch(...) { + std::cout << "\nFinal initialization failed!\n"; + } + + return (scan_init=true); +} + +/** Run the scan program. + * This should be called from main(). + * \return Integer return value. 0 on success and 1 otherwise. + */ +int ScanInterface::Execute(){ +#ifndef USE_HRIBF + if(!scan_init){ + std::cout << " FATAL ERROR! ScanInterface is not initialized!\n"; + return 1; + } + + // Seek to the beginning of the file. + if(file_start_offset != 0){ rewind(); } + + // Process the file. + if(!batch_mode){ + // Start the run control thread + std::cout << "\n Starting data control thread\n"; + std::thread runctrl(start_run_control, this); + + // Start the command control thread. This needs to be the last thing we do to + // initialize, so the user cannot enter commands before setup is complete + std::cout << " Starting command thread\n\n"; + std::thread comctrl(start_cmd_control, this); + + // Synchronize the threads and wait for completion + comctrl.join(); + runctrl.join(); + } + else{ start_run_control(this); } +#endif + return 0; +} + +/** Shutdown cleanly. Uninitialize the ScanInterface object. + * \return True upon success and false if ScanInterface has not been initialized. + */ +bool ScanInterface::Close(){ + if(!scan_init){ return false; } +#ifndef USE_HRIBF + // Close the socket and restore the terminal + if(!batch_mode){ + term->Close(); + } + + // Only close the server if this is shared memory mode. Otherwise + // the server would never have been initialized. + if(shm_mode){ poll_server->Close(); } + + //Reprint the leader as the carriage was returned + std::cout << "Running " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n"; + + std::cout << msgHeader << "Retrieved " << num_spills_recvd << " spills!\n"; + + if(input_file.good()){ + input_file.close(); + } + + // Clean up detector driver + std::cout << "\n" << msgHeader << "Cleaning up...\n"; + + // Show the number of lost spill chunks. + std::cout << msgHeader << "Read " << databuff.GetNumChunks() << " spill chunks.\n"; + std::cout << msgHeader << "Lost at least " << databuff.GetNumMissing() << " spill chunks.\n"; + + if(write_counts) + core->Write(); + + if(poll_server){ delete poll_server; } + if(term){ delete term; } +#endif + if(core){ delete core; } + + scan_init = false; + return true; +} + +/** Get the file extension from an input filename string. + * \param[in] filename_ The full input filename path. + * \param[out] prefix The input filename path without the file extension. + * \return The file extension string. + */ +std::string get_extension(std::string filename_, std::string &prefix){ + size_t count = 0; + size_t last_index = 0; + std::string output = ""; + prefix = ""; + + if(filename_.find('.') != std::string::npos){ + // Find the final period in the filename + for(count = 0; count < filename_.size(); count++){ + if(filename_[count] == '.'){ last_index = count; } + } + + // Get the filename prefix and the extension + for(size_t i = 0; i < count; i++){ + if(i < last_index){ prefix += filename_[i]; } + else if(i > last_index){ output += filename_[i]; } + } + } + else{ // The filename has no extension. + prefix = filename_; + } + + return output; +} From ac6ece88524e6c93a8b84fff9e2e605cf3361ff7 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Thu, 26 Jan 2017 07:48:31 -0500 Subject: [PATCH 143/255] Adjusting output to tell user where they can locally find info. --- Scan/ScanLib/source/ScanInterface.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp index fecb384aa..49e31d673 100644 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ b/Scan/ScanLib/source/ScanInterface.cpp @@ -409,7 +409,10 @@ ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ 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"), + 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"), From 23e15bff750cf9924bd099cb27a1e39f07d695e2 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 1 Feb 2017 10:25:50 -0500 Subject: [PATCH 144/255] Accounting for changes in the directory structure. --- .../ScanLibraries/source/ScanInterface.cpp | 5 +- Scan/ScanLib/source/ScanInterface.cpp | 1149 ----------------- 2 files changed, 4 insertions(+), 1150 deletions(-) delete mode 100644 Scan/ScanLib/source/ScanInterface.cpp diff --git a/Analysis/ScanLibraries/source/ScanInterface.cpp b/Analysis/ScanLibraries/source/ScanInterface.cpp index fecb384aa..49e31d673 100644 --- a/Analysis/ScanLibraries/source/ScanInterface.cpp +++ b/Analysis/ScanLibraries/source/ScanInterface.cpp @@ -409,7 +409,10 @@ ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ 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"), + 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"), diff --git a/Scan/ScanLib/source/ScanInterface.cpp b/Scan/ScanLib/source/ScanInterface.cpp deleted file mode 100644 index 49e31d673..000000000 --- a/Scan/ScanLib/source/ScanInterface.cpp +++ /dev/null @@ -1,1149 +0,0 @@ -/** \file ScanInterface.cpp - * \brief A class to handle reading from various UTK/ORNL pixie16 data formats. - * - * This class is intended to be used as a replacement to the older and unsupported - * 'scanor' program from the UPAK acq library specifically for .ldf files which are - * constructed using the UTK/ORNL pixie16 style. This class also interfaces with poll2 - * shared memory output without the need to use pacman. - * CRT - * - * \author C. R. Thornsberry - * \date Feb. 12th, 2016 - */ -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "Unpacker.hpp" -#include "poll2_socket.h" -#include "CTerminal.h" - -#include "ScanInterface.hpp" - -#ifndef PROG_NAME -#define PROG_NAME "ScanInterface" -#endif - -void start_run_control(ScanInterface *main_){ - main_->RunControl(); -} - -void start_cmd_control(ScanInterface *main_){ - main_->CmdControl(); -} - -///////////////////////////////////////////////////////////////////// -// class optionExt -///////////////////////////////////////////////////////////////////// - -optionExt::optionExt(const char *name_, const int &has_arg_, int *flag_, const int &val_, const std::string &argstr_, const std::string &helpstr_) : - name(name_), has_arg(has_arg_), flag(flag_), val(val_), argstr(argstr_), helpstr(helpstr_), active(false) { -} - -void optionExt::print(const size_t &len_/*=0*/, const std::string &prefix_/*=""*/){ - std::stringstream stream; - stream << prefix_ << "--" << name << " "; - if(val) stream << "(-" << (char)val << ") "; - stream << argstr; - - if(stream.str().length() < len_) - stream << std::string(len_ - stream.str().length(), ' '); - - stream << "- " << helpstr; - std::cout << stream.str() << std::endl; -} - -option optionExt::getOption(){ - struct option output; - output.name = name; - output.has_arg = has_arg; - output.flag = flag; - output.val = val; - return output; -} - -///////////////////////////////////////////////////////////////////// -// class fileInformation -///////////////////////////////////////////////////////////////////// - -bool fileInformation::at(const size_t &index_, std::string &name, std::string &value){ - if(index_ >= parnames.size()){ return false; } - name = parnames.at(index_); - value = parvalues.at(index_); - return true; -} - -template -bool fileInformation::push_back(const std::string & name_, const T &value_, const std::string &units_/*=""*/){ - if(!is_in(name_)){ - std::stringstream stream; - stream << value_; - if(units_.size() > 0){ - stream << " " << units_; - } - parnames.push_back(name_); - parvalues.push_back(stream.str()); - return true; - } - return false; -} - -bool fileInformation::is_in(const std::string & name_){ - for(std::vector::iterator iter = parnames.begin(); iter != parnames.end(); iter++){ - if(name_ == (*iter)){ return true; } - } - return false; -} - -std::string fileInformation::print(const size_t &index_){ - if(index_ >= parnames.size()){ return ""; } - return std::string(parnames.at(index_) + ": " + parvalues.at(index_)); -} - -void fileInformation::clear(){ - parnames.clear(); - parvalues.clear(); -} - -///////////////////////////////////////////////////////////////////// -// class ScanInterface -///////////////////////////////////////////////////////////////////// - -/** Start the scan, if ScanInterface is initialized and is not already running. - * \return Nothing. - */ -void ScanInterface::start_scan(){ - if(!(file_open || shm_mode)) - std::cout << " No input file loaded.\n"; - else if(!input_file.good()) - std::cout << " Error reading from input file!\n"; - else if(input_file.eof()) - std::cout << " Physical end-of-file reached.\n"; - else if(is_running) - std::cout << " Already running.\n"; - else{ - core->Run(); - is_running = true; - total_stopped = false; - if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Waiting for Unpacker..."); } - - // Notify that the user has started the scan. - Notify("START_SCAN"); - } -} - -/** Stop the scan, if it is running. - * \return Nothing. - */ -void ScanInterface::stop_scan(){ - if(!scan_init){ std::cout << " Not initialized!\n"; } - else if(!is_running){ std::cout << " Not running.\n"; } - else{ - core->Stop(); - is_running = false; - if(!batch_mode){ term->SetStatus("\033[0;31m[STOP]\033[0m Acquisition stopped.");} - else{ std::cout << "\033[0;31m[STOP]\033[0m Acquisition stopped.\n"; } - } - - // Notify that the user has stopped the scan. - Notify("STOP_SCAN"); -} - -/** Print a command line argument help dialogue. - * \param[in] name_ The name of the program. - * \return Nothing. - */ -void ScanInterface::help(char *name_){ - SyntaxStr(name_); - std::cout << " Available options:\n"; - for(std::vector::iterator iter = baseOpts.begin(); iter != baseOpts.end(); iter++){ - if(!iter->name) continue; - iter->print(40, " "); - } - for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ - if(!iter->name) continue; - iter->print(40, " "); - } -} - -/** Seek to a specified position in the file. - * \param[in] offset_ The position, with respect to the start of the file, to seek to. - * \return True upon success and false otherwise. - */ -bool ScanInterface::rewind(const unsigned long &offset_/*=0*/){ - if(!scan_init){ return false; } - - // Ensure that the scan is not running. - if(!(file_open || shm_mode)){ - std::cout << " No input file loaded.\n"; - return false; - } - else if(is_running){ - std::cout << " Cannot change file position while scan is running!\n"; - return false; - } - - // Move to the first word in the file. - std::cout << " Seeking to word no. " << offset_ << " in file\n"; - input_file.seekg(offset_*4, input_file.beg); - std::cout << " Input file is now at " << input_file.tellg() << " bytes\n"; - - // Notify that the user has rewound to the start of the file. - Notify("REWIND_FILE"); - - return true; -} - -/** Open a new binary input file for reading. - * \param[in] fname_ Input filename to open for reading. - * \return True upon successfully opening the file and false otherwise. - */ -bool ScanInterface::open_input_file(const std::string &fname_){ - if(is_running){ - std::cout << " ERROR! Unable to open input file while scan is running.\n"; - return false; - } - else if(shm_mode){ - std::cout << " ERROR! Unable to open input file in shm mode.\n"; - return false; - } - - extension = get_extension(fname_, prefix); - if(prefix == ""){ - std::cout << " ERROR! Input filename was not specified!\n"; - return false; - } - - if(extension == "ldf"){ // List data format file - file_format = 0; - } - else if(extension == "pld"){ // Pixie list data file format - file_format = 1; - } - else{ - std::cout << " ERROR! Invalid file format '" << extension << "'\n"; - std::cout << " The current valid data formats are:\n"; - std::cout << " ldf - list data format (HRIBF)\n"; - std::cout << " pld - pixie list data format\n"; - return false; - } - - // Close the previous file, if one is open. - if(file_open){ - std::cout << " Note: Closing previously opened file.\n"; - input_file.close(); - } - - file_open = true; - - // Load the input file. - input_file.open(fname_.c_str(), std::ios::binary); - if(!input_file.is_open() || !input_file.good()){ - std::cout << " ERROR! Failed to open input file '" << fname_ << "'! Check that the path is correct.\n"; - input_file.close(); - file_open = false; - return false; - } - input_file.seekg(0, input_file.end); - file_length = input_file.tellg(); - input_file.seekg(0, input_file.beg); - - if(!shm_mode){ - // Clear the file information container. - finfo.clear(); - - // Start reading the file - // Every poll2 ldf file starts with a DIR buffer followed by a HEAD buffer - int num_buffers; - if(file_format == 0){ - dirbuff.Read(&input_file); - headbuff.Read(&input_file); - - // Store the file information for later use. - finfo.push_back("Run number", dirbuff.GetRunNumber()); - finfo.push_back("Number buffers", num_buffers); - finfo.push_back("Facility", headbuff.GetFacility()); - finfo.push_back("Format", headbuff.GetFormat()); - finfo.push_back("Type", headbuff.GetType()); - finfo.push_back("Date", headbuff.GetDate()); - finfo.push_back("Title", headbuff.GetRunTitle()); - - dirbuff.Print(); - headbuff.Print(); - std::cout << std::endl; - } - else if(file_format == 1){ - pldHead.Read(&input_file); - - max_spill_size = pldHead.GetMaxSpillSize(); - - // Store the file information for later use. - finfo.push_back("Facility", pldHead.GetFacility()); - finfo.push_back("Format", pldHead.GetFormat()); - finfo.push_back("Start", pldHead.GetStartDate()); - finfo.push_back("Stop", pldHead.GetEndDate()); - finfo.push_back("Title", pldHead.GetRunTitle()); - finfo.push_back("Run number", pldHead.GetRunNumber()); - finfo.push_back("Max spill", max_spill_size, "words"); - finfo.push_back("ACQ time", pldHead.GetRunTime(), "seconds"); - - pldHead.Print(); - std::cout << std::endl; - } - } - - // Notify that the user has loaded a new file. - Notify("LOAD_FILE"); - - return true; -} - -/** Add a command line option to the option list. - * \param[in] opt_ The option to add to the list. - * \return Nothing. - */ -void ScanInterface::AddOption(optionExt opt_){ - char tempChar = opt_.val; - if(tempChar){ - if(optstr.find(tempChar) != std::string::npos) - opt_.val = 0x0; - else{ - optstr += tempChar; - if(opt_.has_arg == required_argument) - optstr += ":"; - else if(opt_.has_arg == optional_argument) - optstr += "::"; - } - } - userOpts.push_back(opt_); -} - -/** SyntaxStr is used to print a linux style usage message to the screen. - * Prints a standard usage message by default. - * \param[in] name_ The name of the program. - * \return Nothing. - */ -void ScanInterface::SyntaxStr(char *name_){ - std::cout << " usage: " << name_ << " [options]\n"; -} - -/** Initialize the Unpacker object. - * Does nothing useful by default. - * \param[in] prefix_ String to append to the beginning of system output. - * \return True upon successfully initializing and false otherwise. - */ -bool ScanInterface::Initialize(std::string prefix_){ - if(scan_init){ return false; } - return (scan_init = true); -} - -/** Return a pointer to the Unpacker object to use for data unpacking. - * If no object has been initialized, create a new one. - * \return Pointer to an Unpacker object. - */ -Unpacker *ScanInterface::GetCore(){ - if(!core){ core = new Unpacker(); } - return core; -} - -/** Default constructor. - * \param[in] core_ Pointer to an object derived from Unpacker. - */ -ScanInterface::ScanInterface(Unpacker *core_/*=NULL*/){ - prefix = ""; - extension = ""; - - // Get the current working directory. - char workingDirectory[1024]; - workDir = std::string(getcwd(workingDirectory, 1024)); - - // Get the home directory. - homeDir = getenv("HOME"); - - maxShmSizeL = 4052; - maxShmSize = maxShmSizeL * 4; - - max_spill_size = 0; - file_format = -1; - - file_start_offset = 0; - num_spills_recvd = 0; - - total_stopped = true; - write_counts = false; - is_running = false; - is_verbose = true; - debug_mode = false; - dry_run_mode = false; - shm_mode = false; - batch_mode = false; - scan_init = false; - file_open = false; - - //Initialize the setup and output file names - output_filename = ""; - setup_filename = ""; - - kill_all = false; - run_ctrl_exit = false; - - poll_server = NULL; - term = NULL; - - // Set the Unpacker pointer, if one is specified. - if(core_){ core = core_; } - else{ core = NULL; } - - //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 + ": "; -} - -/// Default destructor. -ScanInterface::~ScanInterface(){ - Close(); -} - -/// Main scan control method. -void ScanInterface::RunControl(){ - // Notify that we are starting run control. - run_ctrl_exit = false; - - // Set debug mode, if enabled. - if(debug_mode){ - pldHead.SetDebugMode(); - pldData.SetDebugMode(); - dirbuff.SetDebugMode(); - headbuff.SetDebugMode(); - databuff.SetDebugMode(); - eofbuff.SetDebugMode(); - } - - while(true){ - if(kill_all){ break; } - - // Now we're ready to read the first data buffer - if(total_stopped){ - // Sleep while waiting for the user to scan more data. - IdleTask(); - usleep(0.1); - continue; - } - else if(shm_mode){ - std::cout << std::endl; - unsigned int data[250000]; // Array for storing spill data. Larger than any RevF spill should be. - unsigned int *shm_data = new unsigned int[maxShmSizeL]; // Array to store the temporary shm data (~16 kB) - int dummy; - int previous_chunk; - int current_chunk; - int total_chunks; - int nWords; - unsigned int nTotalWords; - - bool full_spill = false; - - while(true){ - if(kill_all == true){ - break; - } - else if(!is_running){ - IdleTask(); - usleep(100000); //0.1 seconds - continue; - } - - int select_dummy; - previous_chunk = 0; - current_chunk = 0; - total_chunks = -1; - nTotalWords = 0; - full_spill = true; - - if(!poll_server->Select(dummy)){ - if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Waiting for a spill..."); } - else{ std::cout << "\r\033[0;33m[IDLE]\033[0m Waiting for a spill..."; } - IdleTask(); - continue; - } - - if(!poll_server->Select(select_dummy)){ continue; } // Server timeout - - // Get the spill - while(current_chunk != total_chunks){ - if(!poll_server->Select(select_dummy)){ // Server timeout - std::cout << msgHeader << "Network timeout before recv full spill!\n"; - full_spill = false; - break; - } - - nWords = poll_server->RecvMessage((char*)shm_data, maxShmSize) / 4; // Read from the socket - if(strcmp((char*)shm_data, "$CLOSE_FILE") == 0 || strcmp((char*)shm_data, "$OPEN_FILE") == 0 || strcmp((char*)shm_data, "$KILL_SOCKET") == 0){ continue; } // Poll2 network flags - // Did not read enough bytes - else if(nWords < 2){ - continue; - } - - if(debug_mode){ std::cout << "debug: Received " << nWords << " words from the network\n"; } - memcpy((char *)¤t_chunk, &shm_data[0], 4); - memcpy((char *)&total_chunks, &shm_data[1], 4); - - if(previous_chunk == -1 && current_chunk != 1){ // Started reading in the middle of a spill, ignore the rest of it - if(debug_mode){ std::cout << "debug: Skipping chunk " << current_chunk << " of " << total_chunks << std::endl; } - continue; - } - else if(previous_chunk != current_chunk - 1){ // We missed a spill chunk somewhere - if(debug_mode){ std::cout << "debug: Found chunk " << current_chunk << " but expected chunk " << previous_chunk+1 << std::endl; } - break; - } - - previous_chunk = current_chunk; - - // Copy the shm spill chunk into the data array - if(nTotalWords + 2 + nWords <= 250000){ // This spill chunk will fit into the data buffer - memcpy(&data[nTotalWords], &shm_data[2], (nWords - 2)*4); - nTotalWords += (nWords - 2); - } - else{ - if(debug_mode){ std::cout << "debug: Abnormally full spill buffer with " << nTotalWords + 2 + nWords << " words!\n"; } - break; - } - } - - std::stringstream status; - status << "\033[0;32m" << "[RECV] " << "\033[0m" << nTotalWords << " words"; - if(!batch_mode){ term->SetStatus(status.str()); } - else{ std::cout << "\r" << status.str(); } - - if(debug_mode){ std::cout << "debug: Retrieved spill of " << nTotalWords << " words (" << nTotalWords*4 << " bytes)\n"; } - if(!dry_run_mode && full_spill){ - int word1 = 2, word2 = 9999; - memcpy(&data[nTotalWords], (char *)&word1, 4); - memcpy(&data[nTotalWords+1], (char *)&word2, 4); - core->ReadSpill(data, nTotalWords + 2, is_verbose); - IdleTask(); - } - - if(!full_spill){ std::cout << msgHeader << "Not processing spill fragment!\n"; } - else{ num_spills_recvd++; } - } - - delete[] shm_data; - } - else if(file_format == 0){ - unsigned int *data = NULL; - bool full_spill; - bool bad_spill; - unsigned int nBytes; - - if(!dry_run_mode){ data = new unsigned int[250000]; } - - // Reset the buffer reader to default values. - databuff.Reset(); - - while(true){ - if(kill_all == true){ - break; - } - else if(!is_running){ - IdleTask(); - usleep(100000); //0.1 seconds - continue; - } - - if(!databuff.Read(&input_file, (char*)data, nBytes, 1000000, full_spill, bad_spill, dry_run_mode)){ - if(databuff.GetRetval() == 1){ - if(debug_mode){ std::cout << "debug: Encountered single EOF buffer (end of run).\n"; } - } - else if(databuff.GetRetval() == 2){ - if(debug_mode){ std::cout << "debug: Encountered double EOF buffer (end of file).\n"; } - break; - } - else if(databuff.GetRetval() == 3){ - if(debug_mode){ std::cout << "debug: Encountered unknown ldf buffer type.\n"; } - } - else if(databuff.GetRetval() == 4){ - if(debug_mode){ std::cout << "debug: Encountered invalid spill chunk.\n"; } - } - else if(databuff.GetRetval() == 5){ - if(debug_mode){ std::cout << "debug: Received bad spill footer size.\n"; } - } - else if(databuff.GetRetval() == 6){ - if(debug_mode){ std::cout << "debug: Failed to read buffer from input file.\n"; } - break; - } - continue; - } - - std::stringstream status; - status << "\033[0;32m" << "[READ] " << "\033[0m" << nBytes/4 << " words (" << 100*input_file.tellg()/file_length << "%), "; - status << "GOOD = " << databuff.GetNumChunks() << ", LOST = " << databuff.GetNumMissing(); - if(!batch_mode){ term->SetStatus(status.str()); } - else{ std::cout << "\r" << status.str(); } - - if(full_spill){ - if(debug_mode){ - std::cout << "debug: Retrieved spill of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; - std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; - } - if(!dry_run_mode){ - if(!bad_spill){ - core->ReadSpill(data, nBytes/4, is_verbose); - IdleTask(); - } - else{ std::cout << " WARNING: Spill has been flagged as corrupt, skipping (at word " << input_file.tellg()/4 << " in file)!\n"; } - } - } - else if(debug_mode){ - std::cout << "debug: Retrieved spill fragment of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; - std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; - } - num_spills_recvd++; - } - - if(!dry_run_mode){ delete[] data; } - - if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Finished scanning file."); } - else{ std::cout << std::endl << std::endl; } - } - else if(file_format == 1){ - unsigned int *data = NULL; - unsigned int nBytes; - - if(!dry_run_mode){ data = new unsigned int[max_spill_size+2]; } - - // Reset the buffer reader to default values. - pldData.Reset(); - - while(pldData.Read(&input_file, (char*)data, nBytes, - 4*max_spill_size, dry_run_mode)){ - if(kill_all == true){ - break; - } - else if(!is_running){ - IdleTask(); - usleep(100000); //0.1 seconds - continue; - } - - std::stringstream status; - status << "\033[0;32m" << "[READ] " << "\033[0m" << nBytes/4 << " words (" << 100*input_file.tellg()/file_length << "%)"; - if(!batch_mode){ term->SetStatus(status.str()); } - else{ std::cout << "\r" << status.str(); } - - if(debug_mode){ - std::cout << "debug: Retrieved spill of " << nBytes << " bytes (" << nBytes/4 << " words)\n"; - std::cout << "debug: Read up to word number " << input_file.tellg()/4 << " in input file\n"; - } - - if(!dry_run_mode){ - int word1 = 2, word2 = 9999; - memcpy(&data[(nBytes/4)], (char *)&word1, 4); - memcpy(&data[(nBytes/4)+1], (char *)&word2, 4); - core->ReadSpill(data, nBytes/4 + 2, is_verbose); - IdleTask(); - } - num_spills_recvd++; - } - - if(eofbuff.ReadHeader(&input_file)){ - std::cout << msgHeader << "Encountered EOF buffer.\n"; - } - else{ - std::cout << msgHeader << "Failed to find end of file buffer!\n"; - } - - if(!dry_run_mode){ delete[] data; } - - if(!batch_mode){ term->SetStatus("\033[0;33m[IDLE]\033[0m Finished scanning file."); } - else{ std::cout << std::endl << std::endl; } - } - else if(file_format == 2){ - } - - // Notify that the scan has completed. - Notify("SCAN_COMPLETE"); - - total_stopped = true; - stop_scan(); - - if(batch_mode){ break; } - } - - // Notify that run control is exiting. - run_ctrl_exit = true; -} - -/// Main command interpreter method. -void ScanInterface::CmdControl(){ - if(!core){ return; } - - std::string cmd = "", arg; - bool waiting_for_run = false; - - while(true){ - if(run_ctrl_exit){ break; } - - if(waiting_for_run){ - if(!is_running){ waiting_for_run = false; } - else{ - term->flush(); // Update the terminal so the user knows something is happening. - sleep(1); // Sleep and wait for the run to finish. - continue; - } - } - - cmd = term->GetCommand(arg); - if(cmd == "_SIGSEGV_"){ - std::cout << "\033[0;31m[SEGMENTATION FAULT]\033[0m\n"; - exit(EXIT_FAILURE); - } - else if(cmd == "CTRL_D"){ - std::cout << msgHeader << "Received EOF (ctrl-d) signal. Exiting...\n"; - cmd = "quit"; - } - else if(cmd == "CTRL_C"){ - std::cout << msgHeader << "Warning! Received SIGINT (ctrl-c) signal.\n"; - continue; - } - else if(cmd == "CTRL_Z"){ - std::cout << msgHeader << "Warning! Received SIGTSTP (ctrl-z) signal.\n"; - continue; - } - term->flush(); - - if(cmd == ""){ continue; } - - // Replace the '~' with the user's home directory. - if(!arg.empty() && arg.find('~') != std::string::npos) - arg.replace(arg.find('~'), 1, homeDir); - - std::vector arguments; - unsigned int p_args = split_str(arg, arguments); - - if(cmd == "quit" || cmd == "exit"){ - stop_scan(); - kill_all = true; - while(!run_ctrl_exit){ sleep(1); } - break; - } - else if(cmd == "version" || cmd == "v"){ - std::cout << " " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n"; - std::cout << " Poll2 Socket v" << POLL2_SOCKET_VERSION << " (" << POLL2_SOCKET_DATE << ")\n"; - std::cout << " HRIBF Buffers v" << HRIBF_BUFFERS_VERSION << " (" << HRIBF_BUFFERS_DATE << ")\n"; - std::cout << " CTerminal v" << CTERMINAL_VERSION << " (" << CTERMINAL_DATE << ")\n"; - } - else if(cmd == "help" || cmd == "h"){ - std::cout << " Help:\n"; - std::cout << " debug - Toggle debug mode flag (default=false)\n"; - std::cout << " quiet - Toggle quiet mode flag (default=false)\n"; - std::cout << " quit - Close the program\n"; - std::cout << " help (h) - Display this dialogue\n"; - std::cout << " version (v) - Display Poll2 version information\n"; - std::cout << " run - Start acquisition\n"; - std::cout << " stop - Stop acquisition\n"; - std::cout << " file - Load an input file\n"; - std::cout << " rewind [offset] - Rewind to the beginning of the file\n"; - std::cout << " sync - Wait for the current run to finish\n"; - CmdHelp(" "); - } - else if(cmd == "run"){ // Start acquisition. - start_scan(); - } - else if(cmd == "stop"){ // Stop acquisition. - stop_scan(); - } - else if(cmd == "debug"){ // Toggle debug mode - if(debug_mode){ - std::cout << msgHeader << "Toggling debug mode OFF\n"; - debug_mode = false; - } - else{ - std::cout << msgHeader << "Toggling debug mode ON\n"; - debug_mode = true; - } - core->SetDebugMode(debug_mode); - } - else if(cmd == "quiet"){ // Toggle quiet mode - if(!is_verbose){ - std::cout << msgHeader << "Toggling quiet mode OFF\n"; - is_verbose = true; - } - else{ - std::cout << msgHeader << "Toggling quiet mode ON\n"; - is_verbose = false; - } - } - else if(cmd == "file"){ // Rewind the file to the start position - if(p_args > 0){ - if(!open_input_file(arguments.at(0))){ - std::cout << msgHeader << "Failed to open input file!\n"; - } - } - else{ - std::cout << msgHeader << "Invalid number of parameters to 'file'\n"; - std::cout << msgHeader << " -SYNTAX- file \n"; - } - } - else if(cmd == "rewind"){ // Rewind the file to the start position - if(p_args > 0){ rewind(strtoul(arguments.at(0).c_str(), NULL, 0)); } - else{ rewind(); } - } - else if(cmd == "sync"){ // Wait until the current run is completed. - if(is_running){ - std::cout << msgHeader << "Waiting for current scan to complete.\n"; - waiting_for_run = true; - } - else{ std::cout << msgHeader << "Scan is not running.\n"; } - } - else if(!ExtraCommands(cmd, arguments)){ // Unrecognized command. Send it to a derived object. - std::cout << msgHeader << "Unknown command '" << cmd << "'\n"; - } - } -} - -/** Setup user options and initialize all required objects. - * \param[in] argc Number of arguments passed from the command line. - * \param[in] argv Array of strings passed as arguments from the command line. - * \return True upon success and false otherwise. - */ -bool ScanInterface::Setup(int argc, char *argv[]){ - if(scan_init) - return false; - - debug_mode = false; - 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. - this->ArgHelp(); - - // Build the vector of all command line options. - for(std::vector::iterator iter = baseOpts.begin(); iter != baseOpts.end(); iter++){ - longOpts.push_back(iter->getOption()); - } - for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ - longOpts.push_back(iter->getOption()); - } - - // Append all zeros onto the option list. Required for getopt_long. - struct option zero_opt { 0, 0, 0, 0 }; - longOpts.push_back(zero_opt); - - int idx = 0; - int retval = 0; - - //getopt_long is not POSIX compliant. It is provided by GNU. This may mean - //that we are not compatible with some systems. If we have enough - //complaints we can either change it to getopt, or implement our own class. - while ( (retval = getopt_long(argc, argv, optstr.c_str(), longOpts.data(), &idx)) != -1) { - if(retval == 0x0){ // Long option - if(strcmp("config", longOpts[idx].name) == 0) { - setup_filename = optarg; - } - else if(strcmp("counts", longOpts[idx].name) == 0) { - write_counts = true; - } - else if(strcmp("debug", longOpts[idx].name) == 0 ) { - debug_mode = true; - } - else if(strcmp("dry-run", longOpts[idx].name) == 0) { - dry_run_mode = true; - } - 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){ - iter->active = true; - if(optarg) - iter->argument = std::string(optarg); - break; - } - } - } - } - else if(retval == 0x3F){ // Unknown option, '?' - return false; - } - else{ // Single character option. - switch(retval) { - case 'b' : - batch_mode = true; - break; - case 'c' : - setup_filename = optarg; - break; - case 'f' : - firmware = optarg; - break; - case 'h' : - help(argv[0]); - return false; - case 'i' : - input_filename = optarg; - break; - case 'o' : - output_filename = optarg; - break; - case 'q' : - is_verbose = false; - break; - case 's': - file_format = 0; - shm_mode = true; - break; - case 'v' : - std::cout << " " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n" ; - std::cout << " Poll2 Socket v" << POLL2_SOCKET_VERSION << " (" << POLL2_SOCKET_DATE << ")\n"; - std::cout << " HRIBF Buffers v" << HRIBF_BUFFERS_VERSION << " (" << HRIBF_BUFFERS_DATE << ")\n"; - std::cout << " CTerminal v" << CTERMINAL_VERSION << " (" << CTERMINAL_DATE << ")\n"; - return false; - default : - for(std::vector::iterator iter = userOpts.begin(); iter != userOpts.end(); iter++){ - if(retval == iter->val){ - iter->active = true; - if(optarg) - iter->argument = std::string(optarg); - break; - } - } - break; - } - } - }//while - - // If a pointer to an Unpacker derived class is not specified, call the - // extern function GetCore() to get a pointer to a new object. - if(!core) - GetCore(); - - // 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(); - - // Parse for any extra arguments that are known to the derived class. - ExtraArguments(); - - // Initialize everything. - std::cout << msgHeader << "Initializing derived class.\n"; - if(!Initialize(msgHeader)){ // Failed to initialize the object. Clean up and exit. - std::cout << " FATAL ERROR! Failed to initialize derived class!\n"; - std::cout << "\nCleaning up...\n"; - return false; - } - -#ifndef USE_HRIBF - if(shm_mode){ - poll_server = new Server(); - if(!poll_server->Init(5555, 1)){ - std::cout << " FATAL ERROR! Failed to open shm socket 5555!\n"; - std::cout << "\nCleaning up...\n"; - return false; - } - if(batch_mode){ - std::cout << msgHeader << "Unable to enable batch mode for shared-memory mode!\n"; - batch_mode = false; - } - } - - // Initialize the terminal. - if(!batch_mode){ - term = new Terminal(); - term->Initialize(); - term->SetCommandHistory(("."+progName+".cmd").c_str()); - term->SetPrompt((progName+" $ ").c_str()); - term->AddStatusWindow(); - term->SetStatus("\033[0;31m[STOP]\033[0m Acquisition stopped."); - } - - std::cout << "\n " << PROG_NAME << " v" << SCAN_VERSION << "\n"; - std::cout << " == == == == == \n\n"; - - if(debug_mode){ std::cout << msgHeader << "Using debug mode.\n\n"; } - if(dry_run_mode){ std::cout << msgHeader << "Doing a dry run.\n\n"; } - if(shm_mode){ - std::cout << msgHeader << "Using shared-memory mode.\n\n"; - std::cout << msgHeader << "Listening on poll2 SHM port 5555\n\n"; - } - - // Load the input file, if the user has supplied a filename. - if(!shm_mode && !input_filename.empty()){ - std::cout << msgHeader << "Using filename " << input_filename << ".\n"; - if(open_input_file(input_filename)){ - // Start the scan. - start_scan(); - } - else{ std::cout << msgHeader << "Failed to load input file!\n"; } - } -#endif - - // Do any last minute initialization. - try { - FinalInitialization(); - } - catch(...) { - std::cout << "\nFinal initialization failed!\n"; - } - - return (scan_init=true); -} - -/** Run the scan program. - * This should be called from main(). - * \return Integer return value. 0 on success and 1 otherwise. - */ -int ScanInterface::Execute(){ -#ifndef USE_HRIBF - if(!scan_init){ - std::cout << " FATAL ERROR! ScanInterface is not initialized!\n"; - return 1; - } - - // Seek to the beginning of the file. - if(file_start_offset != 0){ rewind(); } - - // Process the file. - if(!batch_mode){ - // Start the run control thread - std::cout << "\n Starting data control thread\n"; - std::thread runctrl(start_run_control, this); - - // Start the command control thread. This needs to be the last thing we do to - // initialize, so the user cannot enter commands before setup is complete - std::cout << " Starting command thread\n\n"; - std::thread comctrl(start_cmd_control, this); - - // Synchronize the threads and wait for completion - comctrl.join(); - runctrl.join(); - } - else{ start_run_control(this); } -#endif - return 0; -} - -/** Shutdown cleanly. Uninitialize the ScanInterface object. - * \return True upon success and false if ScanInterface has not been initialized. - */ -bool ScanInterface::Close(){ - if(!scan_init){ return false; } -#ifndef USE_HRIBF - // Close the socket and restore the terminal - if(!batch_mode){ - term->Close(); - } - - // Only close the server if this is shared memory mode. Otherwise - // the server would never have been initialized. - if(shm_mode){ poll_server->Close(); } - - //Reprint the leader as the carriage was returned - std::cout << "Running " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n"; - - std::cout << msgHeader << "Retrieved " << num_spills_recvd << " spills!\n"; - - if(input_file.good()){ - input_file.close(); - } - - // Clean up detector driver - std::cout << "\n" << msgHeader << "Cleaning up...\n"; - - // Show the number of lost spill chunks. - std::cout << msgHeader << "Read " << databuff.GetNumChunks() << " spill chunks.\n"; - std::cout << msgHeader << "Lost at least " << databuff.GetNumMissing() << " spill chunks.\n"; - - if(write_counts) - core->Write(); - - if(poll_server){ delete poll_server; } - if(term){ delete term; } -#endif - if(core){ delete core; } - - scan_init = false; - return true; -} - -/** Get the file extension from an input filename string. - * \param[in] filename_ The full input filename path. - * \param[out] prefix The input filename path without the file extension. - * \return The file extension string. - */ -std::string get_extension(std::string filename_, std::string &prefix){ - size_t count = 0; - size_t last_index = 0; - std::string output = ""; - prefix = ""; - - if(filename_.find('.') != std::string::npos){ - // Find the final period in the filename - for(count = 0; count < filename_.size(); count++){ - if(filename_[count] == '.'){ last_index = count; } - } - - // Get the filename prefix and the extension - for(size_t i = 0; i < count; i++){ - if(i < last_index){ prefix += filename_[i]; } - else if(i > last_index){ output += filename_[i]; } - } - } - else{ // The filename has no extension. - prefix = filename_; - } - - return output; -} From b5d2036ca0ac4370fbdb67ab5f8fe63e20a0d204 Mon Sep 17 00:00:00 2001 From: "Cory R. Thornsberry" Date: Wed, 1 Feb 2017 11:09:35 -0600 Subject: [PATCH 145/255] Fixed incorrect DATA buffer size due to spill footer Previously, the ldf DATA buffer writer incorrectly handled occurances where the spill footer could not fit in the current buffer. This was causing certain DATA buffers to have a number of words less than 8194 and, in turn, causing the ldf reader to get out of position. --- Core/source/hribf_buffers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/source/hribf_buffers.cpp b/Core/source/hribf_buffers.cpp index 07ecf74e5..3f698db57 100644 --- a/Core/source/hribf_buffers.cpp +++ b/Core/source/hribf_buffers.cpp @@ -704,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_); } From 976d769e904003234708ce6f40088f0ba76b05ee Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 1 Feb 2017 16:39:04 -0500 Subject: [PATCH 146/255] Resolves #72 We added a method to convert from IEEE Floating point standard number to human readable decimal number. Added a unit test for this funciton, and fixed the ouput in set2ascii. We did this so that we could use these number in calculations, and verfications of settings. --- Acquisition/PxiDump/source/set2root.cpp | 8 +++++- Resources/include/HelperFunctions.hpp | 27 ++++++++++++++++++++ Resources/tests/unittest-HelperFunctions.cpp | 6 +++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Acquisition/PxiDump/source/set2root.cpp b/Acquisition/PxiDump/source/set2root.cpp index ce5246a16..27e99d676 100644 --- a/Acquisition/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/Resources/include/HelperFunctions.hpp b/Resources/include/HelperFunctions.hpp index e2e0d1a4b..5ae145bf8 100644 --- a/Resources/include/HelperFunctions.hpp +++ b/Resources/include/HelperFunctions.hpp @@ -432,4 +432,31 @@ namespace TraceFunctions { } } + +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/tests/unittest-HelperFunctions.cpp b/Resources/tests/unittest-HelperFunctions.cpp index 9c6939eff..5b06b7d53 100644 --- a/Resources/tests/unittest-HelperFunctions.cpp +++ b/Resources/tests/unittest-HelperFunctions.cpp @@ -178,6 +178,12 @@ TEST(TestCalculateTailRatio) { 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 From c2935def25c1b4c84259bee9226403690f98241e Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 1 Feb 2017 07:05:35 -0500 Subject: [PATCH 147/255] Fixing compiler warnings in utkscan --- .../Utkscan/processors/source/GeCalibProcessor.cpp | 2 +- Analysis/Utkscan/processors/source/GeProcessor.cpp | 2 +- .../Utkscan/processors/source/PspmtProcessor.cpp | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Analysis/Utkscan/processors/source/GeCalibProcessor.cpp b/Analysis/Utkscan/processors/source/GeCalibProcessor.cpp index efa54eb4b..4838c936a 100644 --- a/Analysis/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/Analysis/Utkscan/processors/source/GeProcessor.cpp b/Analysis/Utkscan/processors/source/GeProcessor.cpp index 1be841b62..5e016e5de 100644 --- a/Analysis/Utkscan/processors/source/GeProcessor.cpp +++ b/Analysis/Utkscan/processors/source/GeProcessor.cpp @@ -402,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; diff --git a/Analysis/Utkscan/processors/source/PspmtProcessor.cpp b/Analysis/Utkscan/processors/source/PspmtProcessor.cpp index 908845904..452b6ca8d 100644 --- a/Analysis/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); } From bb22b1d87e73a1e8c9a75a9138b28b318f7df0be Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 3 Feb 2017 09:11:47 -0600 Subject: [PATCH 148/255] Resolved an initialization error in HisDrr.cpp --- Acquisition/MCA/source/HisDrr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Acquisition/MCA/source/HisDrr.cpp b/Acquisition/MCA/source/HisDrr.cpp index 56ffec8be..bb33bb4e7 100644 --- a/Acquisition/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...) From 2445d4f9c936db2d2b33590f44e46f44b6123fed Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 09:38:09 -0500 Subject: [PATCH 149/255] Fixes #207 - Adding missing header into the files These missing headers caused compilation issues on some computers. --- Acquisition/Interface/source/PixieInterface.cpp | 1 + Acquisition/Poll/source/poll2_core.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Acquisition/Interface/source/PixieInterface.cpp b/Acquisition/Interface/source/PixieInterface.cpp index e5924bd7e..a14e1858d 100644 --- a/Acquisition/Interface/source/PixieInterface.cpp +++ b/Acquisition/Interface/source/PixieInterface.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/Acquisition/Poll/source/poll2_core.cpp b/Acquisition/Poll/source/poll2_core.cpp index 4ac8cd7fc..208a444ea 100644 --- a/Acquisition/Poll/source/poll2_core.cpp +++ b/Acquisition/Poll/source/poll2_core.cpp @@ -19,7 +19,9 @@ #include #include #include +#include #include + #include #include #include From 79a5efe773035313b080d3d033471eae3635714f Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 3 Feb 2017 09:15:20 -0600 Subject: [PATCH 150/255] Changed default install directory. Changed to ../install from build. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3be8d896..c599ec899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ endif() 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}") From 55cde6479c404250e1b151fc8838a0f39105b25b Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 3 Feb 2017 09:25:27 -0600 Subject: [PATCH 151/255] Corrected messages in FindPXI.cmake Some messages were not set to STATUS causing them to appear on the screen in ccmake. --- Cmake/modules/FindPXI.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cmake/modules/FindPXI.cmake b/Cmake/modules/FindPXI.cmake index 9121132c7..d196fa62f 100644 --- a/Cmake/modules/FindPXI.cmake +++ b/Cmake/modules/FindPXI.cmake @@ -191,13 +191,13 @@ function(PXI_CONFIG) if (NUM_MATCHES EQUAL 1) if (${MODULE_TYPE} MATCHES "unknown") message(STATUS "WARNING: Incomplete module type (${MODULE_TYPE}) found in:") - message(" ${FIRMWARE_DIR}") + 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(" ${FIRMWARE_DIR}") + 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") @@ -227,7 +227,7 @@ function(PXI_CONFIG) set(ERROR TRUE) message(STATUS "WARNING: Unable to autocomplete ${MODULE_TYPE} configuration!") endif (NOT ERROR) - message(" Unique ${KEY} file (${GLOB_EXPR}) not found!") + 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") From e3718f9cbf106522992093f166c1008c2bd30492 Mon Sep 17 00:00:00 2001 From: Sean Burcher Date: Fri, 3 Feb 2017 15:51:55 -0600 Subject: [PATCH 152/255] Added headers to the columns in monitor. --- Acquisition/Poll/source/monitor.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Acquisition/Poll/source/monitor.cpp b/Acquisition/Poll/source/monitor.cpp index 8549970d8..1fb0fa9f8 100644 --- a/Acquisition/Poll/source/monitor.cpp +++ b/Acquisition/Poll/source/monitor.cpp @@ -214,7 +214,17 @@ int main(){ << std::setfill('-') << ""; } std::cout << "|\n"; + + std::cout << " | "; + for(unsigned int j = 0; j < (unsigned int)num_modules; j++){ + std::cout << "ICR "; + std::cout << " OCR "; + std::cout << " Data "; + std::cout << " Total | "; + } + std::cout << "\n"; + for(unsigned int i = 0; i < 16; i++){ std::cout << "C" << std::setw(2) << std:: setfill('0') << i << "|"; for(unsigned int j = 0; j < (unsigned int)num_modules; j++){ From a958af02976753a6dd5fdeaf2ea2782fd8ea4da8 Mon Sep 17 00:00:00 2001 From: Karl Smith Date: Fri, 3 Feb 2017 13:18:17 -0600 Subject: [PATCH 153/255] Renamed FindPXI to FindXIA Also, renamed all PXI variables to XIA. --- Acquisition/Interface/source/CMakeLists.txt | 4 +- CMakeLists.txt | 16 ++--- .../modules/{FindPXI.cmake => FindXIA.cmake} | 64 +++++++++---------- README.md | 10 +-- 4 files changed, 47 insertions(+), 47 deletions(-) rename Cmake/modules/{FindPXI.cmake => FindXIA.cmake} (86%) diff --git a/Acquisition/Interface/source/CMakeLists.txt b/Acquisition/Interface/source/CMakeLists.txt index c571fff15..f8afd3d44 100644 --- a/Acquisition/Interface/source/CMakeLists.txt +++ b/Acquisition/Interface/source/CMakeLists.txt @@ -2,8 +2,8 @@ set(Interface_SOURCES PixieInterface.cpp Lock.cpp) add_library(PixieInterface STATIC ${Interface_SOURCES}) -#Order is important, PXI before PLX -target_link_libraries(PixieInterface PaassCoreStatic ${PXI_LIBRARIES} +#Order is important, XIA before PLX +target_link_libraries(PixieInterface PaassCoreStatic ${XIA_LIBRARIES} ${PLX_LIBRARIES}) set(Support_SOURCES PixieSupport.cpp) diff --git a/CMakeLists.txt b/CMakeLists.txt index c599ec899..439f36a7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,7 @@ find_package (Threads REQUIRED) find_package (PLX) #Find the Pixie Firmware -find_package (PXI) +find_package (XIA) #Find curses library used for poll2/scan/skeleton/scope/etc if(USE_NCURSES) @@ -109,21 +109,21 @@ if(BUILD_UNITTESTS) endif(BUILD_UNITTESTS) if (BUILD_ACQ) - if(NOT BUILD_ACQ_ATTEMPTED AND NOT PLX_FOUND AND NOT PXI_FOUND) + if(NOT BUILD_ACQ_ATTEMPTED AND NOT PLX_FOUND AND NOT XIA_FOUND) set (BUILD_ACQ OFF CACHE BOOL "Build and install PixieSuite" FORCE) - else (PLX_FOUND OR PXI_FOUND) + else (PLX_FOUND OR XIA_FOUND) #Find the PLX Library find_package(PLX REQUIRED) link_directories(${PLX_LIBRARY_DIR}) #Find the Pixie Firmware - find_package(PXI REQUIRED) - include_directories(${PXI_INCLUDE_DIR}) - link_directories(${PXI_LIBRARY_DIR}) + find_package(XIA REQUIRED) + include_directories(${XIA_INCLUDE_DIR}) + link_directories(${XIA_LIBRARY_DIR}) #Create pixie.cfg and copy slot_def.set as well as default.set to current.set - PXI_CONFIG() - #Use the cmake script created by PXI_CONFIG to install the files it + XIA_CONFIG() + #Use the cmake script created by XIA_CONFIG to install the files it #created when make cfg is typed add_custom_target(config ${CMAKE_COMMAND} -P pixie_cfg.cmake) endif() diff --git a/Cmake/modules/FindPXI.cmake b/Cmake/modules/FindXIA.cmake similarity index 86% rename from Cmake/modules/FindPXI.cmake rename to Cmake/modules/FindXIA.cmake index d196fa62f..52db5b3c4 100644 --- a/Cmake/modules/FindPXI.cmake +++ b/Cmake/modules/FindXIA.cmake @@ -1,46 +1,46 @@ -# Find the PXI Library +# Find the XIA Library # # Sets the usual variables expected for find_package scripts: # -# PXI_LIBRARY_DIR -# PXI_FOUND - true if PXI was found. +# XIA_LIBRARY_DIR +# XIA_FOUND - true if XIA 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) +#This permits the user to change the XIA_ROOT_DIR and have subsequent paths updated. +unset(XIA_LIBRARY_DIR CACHE) #Find the library path by looking for the library. -find_path(PXI_LIBRARY_DIR +find_path(XIA_LIBRARY_DIR NAMES libPixie16App.a libPixie16Sys.a - HINTS ${PXI_ROOT_DIR} + HINTS ${XIA_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) +get_filename_component(XIA_LIBRARY_DIR "${XIA_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.") +if(NOT XIA_FIRMWARE_DIR) + get_filename_component(XIA_FIRMWARE_DIR "${XIA_LIBRARY_DIR}/../.." REALPATH) +endif(NOT XIA_FIRMWARE_DIR) +set(XIA_FIRMWARE_DIR ${XIA_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. +# Support the REQUIRED and QUIET arguments, and set XIA_FOUND if found. include (FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS (PXI DEFAULT_MSG PXI_LIBRARY_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (XIA DEFAULT_MSG XIA_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) +if (XIA_FOUND) + set (XIA_INCLUDE_DIR ${XIA_LIBRARY_DIR}/inc ${XIA_LIBRARY_DIR}/sys ${XIA_LIBRARY_DIR}/app) + set(XIA_LIBRARIES -lPixie16App -lPixie16Sys) endif() -function(PXI_CONFIG) +function(XIA_CONFIG) message(STATUS "Creating Pixie configuration.") - get_filename_component(PXI_ROOT_DIR "${PXI_LIBRARY_DIR}/.." REALPATH) + get_filename_component(XIA_ROOT_DIR "${XIA_LIBRARY_DIR}/.." REALPATH) #create an installer that can be invoked by #add_custom_target(config ${CMAKE_COMMAND} -P pixie_cfg.cmake) @@ -73,7 +73,7 @@ function(PXI_CONFIG) 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") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/pixie.cfg "PixieBaseDir\t\t${XIA_ROOT_DIR}\n") #Following are lists of keys and the glob expr to find the files set(CONFIG_NAME CrateConfig SlotFile DspSetFile) @@ -90,7 +90,7 @@ function(PXI_CONFIG) #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}) + file(GLOB FILE_MATCHES RELATIVE ${XIA_ROOT_DIR} ${XIA_ROOT_DIR}/${GLOB_EXPR}) #Check that a unique match was found list(LENGTH FILE_MATCHES NUM_MATCHES) @@ -107,14 +107,14 @@ function(PXI_CONFIG) if (${KEY} MATCHES "SlotFile") if (NUM_MATCHES EQUAL 1) - configure_file(${PXI_ROOT_DIR}/${FILE_MATCHES} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + configure_file(${XIA_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) + configure_file(${XIA_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 @@ -138,18 +138,18 @@ function(PXI_CONFIG) 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}") + if(NOT EXISTS ${XIA_FIRMWARE_DIR}) + message(WARNING "Configuration Error - Invalid Pixie firmware directory: ${XIA_FIRMWARE_DIR}") return() - endif(NOT EXISTS ${PXI_FIRMWARE_DIR}) - subdirlist(PXI_FIRMWARE_DIRS ${PXI_FIRMWARE_DIR}) + endif(NOT EXISTS ${XIA_FIRMWARE_DIR}) + subdirlist(XIA_FIRMWARE_DIRS ${XIA_FIRMWARE_DIR}) #remove directories without subdirectories firmware and dsp. - foreach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + foreach(FIRMWARE_DIR ${XIA_FIRMWARE_DIRS}) if (NOT (EXISTS ${FIRMWARE_DIR}/firmware OR EXISTS ${FIRMWARE_FIR}/dsp)) - list(REMOVE_ITEM PXI_FIRMWARE_DIRS ${FIRMWARE_DIR}) + list(REMOVE_ITEM XIA_FIRMWARE_DIRS ${FIRMWARE_DIR}) endif (NOT (EXISTS ${FIRMWARE_DIR}/firmware OR EXISTS ${FIRMWARE_FIR}/dsp)) - endforeach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + endforeach(FIRMWARE_DIR ${XIA_FIRMWARE_DIRS}) #Following are lists of keys and the glob expr to find the files set(CONFIG_NAME SpFpgaFile ComFpgaFile DspConfFile DspVarFile) @@ -160,7 +160,7 @@ function(PXI_CONFIG) dsp/Pixie16DSP*.var #DspVarFile ) - foreach(FIRMWARE_DIR ${PXI_FIRMWARE_DIRS}) + foreach(FIRMWARE_DIR ${XIA_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) @@ -240,7 +240,7 @@ function(PXI_CONFIG) #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}) + endforeach(FIRMWARE_DIR ${XIA_FIRMWARE_DIRS}) endfunction() diff --git a/README.md b/README.md index f97d9c6cc..902c753e6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ through a PACMAN interface (recommended). ###Required * ncurses * PLX -* PXI +* XIA * gcc v4.4.6+ * cmake v2.8.8+ @@ -45,16 +45,16 @@ through a PACMAN interface (recommended). ##Installation (assuming admin rights) 1. (admin) Install PLX software: `/opt/plx//` 2. (admin) Create the PLX link: `ln -s /opt/plx//PlxSdk /opt/plx/current` -3. (admin) Install PXI firmware files: `/opt/xia/firmware/` -4. (admin) Change PXI firmware directory group to acq: `chgrp -R acq /opt/xia/firmware/` +3. (admin) Install XIA firmware files: `/opt/xia/firmware/` +4. (admin) Change XIA firmware directory group to acq: `chgrp -R acq /opt/xia/firmware/` 5. (admin) Add acquisition user to acq group : `usermod -a -G acq ` -6. (admin) Create the PXI link: `ln -s /opt/xia/firmware/ /opt/xia/current` +6. (admin) Create the XIA link: `ln -s /opt/xia/firmware/ /opt/xia/current` 7. In PixieSuite2 base directory create the "build" directory: "`mkdir build`" 8. Change to build directory and execute cmake: `cmake ../` 9. If all goes well, "`make clean && make && sudo make install && sudo make config`". Default install directory is `PixieSuite2/exec` -*You should ensure that the PLX version and PXI firmware versions are compatable!* +*You should ensure that the PLX version and XIA firmware versions are compatable!* ###Options for CMAKE Compilation * -DCMAKE\_INSTALL\_PREFIX (default PixieSuite2/exec) From 3a8f9951f1d7f9305eca3aa348725f453ab57cd4 Mon Sep 17 00:00:00 2001 From: pixie16 Date: Mon, 6 Feb 2017 12:55:04 -0600 Subject: [PATCH 154/255] I changed the MAX_FILE_SIZE defintion (Line 55) from 4GB (4294967296) to 2GB (2147483648) --- Acquisition/Poll/source/poll2_core.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Acquisition/Poll/source/poll2_core.cpp b/Acquisition/Poll/source/poll2_core.cpp index 208a444ea..a4eced847 100644 --- a/Acquisition/Poll/source/poll2_core.cpp +++ b/Acquisition/Poll/source/poll2_core.cpp @@ -51,8 +51,8 @@ // Adjusted to help alleviate the issue with data corruption #define POLL_TRIES 100 -// 4 GB. Maximum allowable .ldf file size in bytes -#define MAX_FILE_SIZE 4294967296ll +// 2 GB. Maximum allowable .ldf file size in bytes +#define MAX_FILE_SIZE 2147483648ll // Length of shm packet header (in bytes) #define PKT_HEAD_LEN 8 @@ -466,6 +466,7 @@ int Poll::write_data(word_t *data, unsigned int nWords){ } // Handle the writing of buffers to the file + //65552 = 8194 * 4 * 2 , 2 EOF buffers are need 8194 words at 4 bytes per word std::streampos current_filesize = output_file.GetFilesize(); if(current_filesize + (std::streampos)(4*nWords + 65552) > MAX_FILE_SIZE){ // Adding nWords plus 2 EOF buffers to the file will push it over MAX_FILE_SIZE. From 456b9ca77a10f910bd779c767b9ffde94d96cc52 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 6 Feb 2017 14:08:33 -0500 Subject: [PATCH 155/255] Adding in new CMake module to allow for dependent options Including this module allows us to have the USE_GSL option depend on the BUILD_UTKSCAN option. We no longer have the issue where the two are decoupled and this resolves the error that we previously had. --- Analysis/CMakeLists.txt | 3 ++- CMakeLists.txt | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Analysis/CMakeLists.txt b/Analysis/CMakeLists.txt index ad99e74d9..1beccdd4b 100644 --- a/Analysis/CMakeLists.txt +++ b/Analysis/CMakeLists.txt @@ -1,5 +1,6 @@ option(USE_HRIBF "Use HRIBF library for scan base." OFF) -option(USE_GSL "Use GSL for Pulse Fitting" OFF) +CMAKE_DEPENDENT_OPTION(USE_GSL "Compile with GSL" ON "BUILD_UTKSCAN" OFF) +mark_as_advanced(USE_GSL) #Check if GSL is installed if(USE_GSL) diff --git a/CMakeLists.txt b/CMakeLists.txt index 439f36a7f..590901e66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,9 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug") endif(CMAKE_BUILD_TYPE MATCHES "Debug") #------------------------------------------------------------------------------ +#We are going to include this additional module here since it could be useful +#when setting all of the following options. +include(CMakeDependentOption) #Install options option(BUILD_ACQ "Build and install Acquisition software" ON) From 7bd69e430b9176a71d6950693a188aeb0ed08ed2 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Tue, 7 Feb 2017 09:50:53 -0500 Subject: [PATCH 156/255] Adding additional check on GSL in the utkscan CMakeLists The GSL flag can be disabled by an advanced user. This would not throw an error until the linking stage. The new addition will catch this error much sooner and provide the user with some information about what happened. --- Analysis/Utkscan/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Analysis/Utkscan/CMakeLists.txt b/Analysis/Utkscan/CMakeLists.txt index 5e273441d..44abea382 100644 --- a/Analysis/Utkscan/CMakeLists.txt +++ b/Analysis/Utkscan/CMakeLists.txt @@ -1,3 +1,7 @@ +if (NOT USE_GSL) + message(FATAL_ERROR "GSL is required to build Utkscan!") +endif (NOT USE_GSL) + #CMake file for UTKScan. option(UTKSCAN_GAMMA_GATES "Gamma-Gamma gates in GeProcessor" OFF) option(UTKSCAN_ONLINE "Options for online scans" OFF) From 66a032d016a36205fa40bdd1e268b68148b5365e Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 30 Jan 2017 08:36:35 -0500 Subject: [PATCH 157/255] Renaming Clear method to Initialize since that's what it's used for. --- Scan/ScanLib/include/XiaData.hpp | 262 +++++++++++++++++++++++++++++++ Scan/ScanLib/source/XiaData.cpp | 23 +++ 2 files changed, 285 insertions(+) create mode 100644 Scan/ScanLib/include/XiaData.hpp create mode 100644 Scan/ScanLib/source/XiaData.cpp diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp new file mode 100644 index 000000000..cb6383786 --- /dev/null +++ b/Scan/ScanLib/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/Scan/ScanLib/source/XiaData.cpp b/Scan/ScanLib/source/XiaData.cpp new file mode 100644 index 000000000..90527e606 --- /dev/null +++ b/Scan/ScanLib/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 From bdad124d897676e013b73675a14c3ebfb0d91d2c Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Mon, 30 Jan 2017 08:38:52 -0500 Subject: [PATCH 158/255] Replacing ChannelEvent with ProcessedXiaData to make it more clear. The previous name wasn't clear exactly what was supposed to be stored in the class. The ProcessedXiaData class is now derived from XiaData. This eliminates the need for us to repeat a bunch of the methods for getting and setting things. In addition, it's now clearer what this class actually it. It stores processed XiaData objects. --- Scan/ScanLib/include/ProcessedXiaData.hpp | 39 +++++++++++++++++++++++ Scan/ScanLib/source/CMakeLists.txt | 28 ++++++++++++++++ Scan/ScanLib/source/ProcessedXiaData.cpp | 7 ++++ 3 files changed, 74 insertions(+) create mode 100644 Scan/ScanLib/include/ProcessedXiaData.hpp create mode 100644 Scan/ScanLib/source/CMakeLists.txt create mode 100644 Scan/ScanLib/source/ProcessedXiaData.cpp diff --git a/Scan/ScanLib/include/ProcessedXiaData.hpp b/Scan/ScanLib/include/ProcessedXiaData.hpp new file mode 100644 index 000000000..b1f786518 --- /dev/null +++ b/Scan/ScanLib/include/ProcessedXiaData.hpp @@ -0,0 +1,39 @@ +///@file ProcessedXiaData.hpp +///@brief An XiaData object that has undergone additional processing. +///@author S. V. Paulauskas and C. R. Thornsberry +///@date December 2, 2016 +#ifndef PIXIESUITE_PROCESSEDXIADATA_HPP +#define PIXIESUITE_PROCESSEDXIADATA_HPP +#include + +#include "XiaData.hpp" + +///This class contains additional information about the XiaData after +/// additional processing has been done. The processing includes, but is not +/// limited to energy/time calibrations, high resolution timing analysis, +/// trace analysis, etc. +class ProcessedXiaData : public XiaData { +public: + /// Default constructor. + ProcessedXiaData() {Clear();} + + /// Constructor from XiaData. ProcessedXiaData will take ownership via + /// the unique pointer. + ProcessedXiaData(XiaData *event) { + data_ = event; + } + + /// Default Destructor. + ~ProcessedXiaData(){}; +private: + ///A pointer to the XiaData + XiaData *data_; + + /// Clear all variables and clear the trace vector and arrays. + void Initialize(){}; + + bool isIgnored_; /// Ignore this event. + bool isValidData; /// True if the high resolution energy and time are valid. + double hires_time; /// High resolution time taken from pulse fits (in ns). +}; +#endif //PIXIESUITE_PROCESSEDXIADATA_HPP diff --git a/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt new file mode 100644 index 000000000..674926281 --- /dev/null +++ b/Scan/ScanLib/source/CMakeLists.txt @@ -0,0 +1,28 @@ +#Set the scan sources that we will make a lib out of +set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp + ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp + XiaListModeDataEncoder.cpp) + +if(USE_ROOT) + list(APPEND ScanSources RootScanner.cpp) +endif(USE_ROOT) + +#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/ProcessedXiaData.cpp b/Scan/ScanLib/source/ProcessedXiaData.cpp new file mode 100644 index 000000000..4cf31e203 --- /dev/null +++ b/Scan/ScanLib/source/ProcessedXiaData.cpp @@ -0,0 +1,7 @@ +///@file ProcessedXiaData.cpp +///@author S. V. Paulauskas (from C. R. Thornsberry's work) +///@date December 2, 2016 + +#include + +#include "ProcessedXiaData.hpp" From 9ceb910f16c03c9fb0772872e557a0f8deb29e39 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Wed, 1 Feb 2017 11:59:21 -0500 Subject: [PATCH 159/255] Moving the modified files on this branch to the proper location. --- .../include/ProcessedXiaData.hpp | 0 Analysis/ScanLibraries/source/CMakeLists.txt | 20 +- .../source/ProcessedXiaData.cpp | 0 Scan/ScanLib/include/XiaData.hpp | 262 ------------------ Scan/ScanLib/source/CMakeLists.txt | 28 -- Scan/ScanLib/source/XiaData.cpp | 23 -- 6 files changed, 10 insertions(+), 323 deletions(-) rename {Scan/ScanLib => Analysis/ScanLibraries}/include/ProcessedXiaData.hpp (100%) rename {Scan/ScanLib => Analysis/ScanLibraries}/source/ProcessedXiaData.cpp (100%) delete mode 100644 Scan/ScanLib/include/XiaData.hpp delete mode 100644 Scan/ScanLib/source/CMakeLists.txt delete mode 100644 Scan/ScanLib/source/XiaData.cpp diff --git a/Scan/ScanLib/include/ProcessedXiaData.hpp b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp similarity index 100% rename from Scan/ScanLib/include/ProcessedXiaData.hpp rename to Analysis/ScanLibraries/include/ProcessedXiaData.hpp diff --git a/Analysis/ScanLibraries/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt index 2c2e99346..674926281 100644 --- a/Analysis/ScanLibraries/source/CMakeLists.txt +++ b/Analysis/ScanLibraries/source/CMakeLists.txt @@ -1,28 +1,28 @@ #Set the scan sources that we will make a lib out of -set(PaassScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp +set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp XiaListModeDataEncoder.cpp) if(USE_ROOT) - list(APPEND PaassScanSources RootScanner.cpp) + list(APPEND ScanSources RootScanner.cpp) endif(USE_ROOT) #Add the sources to the library -add_library(PaassScanObjects OBJECT ${PaassScanSources}) +add_library(ScanObjects OBJECT ${ScanSources}) if(BUILD_SHARED_LIBS) message(STATUS "Building Scan Shared Objects") - add_library(PaassScan SHARED $) - target_link_libraries(PaassScan PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) + add_library(Scan SHARED $) + target_link_libraries(Scan PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(PaassScan ${CURSES_LIBRARIES}) + target_link_libraries(Scan ${CURSES_LIBRARIES}) endif() - install(TARGETS PaassScan DESTINATION lib) + install(TARGETS Scan 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}) +add_library(ScanStatic STATIC $) +target_link_libraries(ScanStatic PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(PaassScanStatic ${CURSES_LIBRARIES}) + target_link_libraries(ScanStatic ${CURSES_LIBRARIES}) endif() diff --git a/Scan/ScanLib/source/ProcessedXiaData.cpp b/Analysis/ScanLibraries/source/ProcessedXiaData.cpp similarity index 100% rename from Scan/ScanLib/source/ProcessedXiaData.cpp rename to Analysis/ScanLibraries/source/ProcessedXiaData.cpp diff --git a/Scan/ScanLib/include/XiaData.hpp b/Scan/ScanLib/include/XiaData.hpp deleted file mode 100644 index cb6383786..000000000 --- a/Scan/ScanLib/include/XiaData.hpp +++ /dev/null @@ -1,262 +0,0 @@ -///@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/Scan/ScanLib/source/CMakeLists.txt b/Scan/ScanLib/source/CMakeLists.txt deleted file mode 100644 index 674926281..000000000 --- a/Scan/ScanLib/source/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -#Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp - ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp - XiaListModeDataEncoder.cpp) - -if(USE_ROOT) - list(APPEND ScanSources RootScanner.cpp) -endif(USE_ROOT) - -#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 90527e606..000000000 --- a/Scan/ScanLib/source/XiaData.cpp +++ /dev/null @@ -1,23 +0,0 @@ -///@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 From 5c747b0ac91a8e070d7f1d98fdee9c9951defd7b Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:05:09 -0500 Subject: [PATCH 160/255] Making the Trace class more generic moving to ScanLibraries The trace class was a little to steeped in the old style of pixie_scan. I have removed a number of junk methods that were related to plotting and made this a more generalized container for trace related data. The Getters and Setters now have the same signatures as the functions in the TraceFunctions namespace. This will allow people to use these functions more easily. I have also removed the maps that used to contain integer and double data. These didnt't make much sense in the new framework. In addition, it was more difficult to understand what information was being stored in the trace. --- Analysis/ScanLibraries/include/Trace.hpp | 141 ++++++++++++ Analysis/ScanLibraries/tests/CMakeLists.txt | 11 +- .../ScanLibraries/tests/unittest-Trace.cpp | 59 +++++ Analysis/Utkscan/core/include/Trace.hpp | 203 ------------------ Analysis/Utkscan/core/source/CMakeLists.txt | 1 - Analysis/Utkscan/core/source/Trace.cpp | 56 ----- Resources/include/UnitTestSampleData.hpp | 8 +- 7 files changed, 216 insertions(+), 263 deletions(-) create mode 100644 Analysis/ScanLibraries/include/Trace.hpp create mode 100644 Analysis/ScanLibraries/tests/unittest-Trace.cpp delete mode 100644 Analysis/Utkscan/core/include/Trace.hpp delete mode 100644 Analysis/Utkscan/core/source/Trace.cpp diff --git a/Analysis/ScanLibraries/include/Trace.hpp b/Analysis/ScanLibraries/include/Trace.hpp new file mode 100644 index 000000000..6a71f72d6 --- /dev/null +++ b/Analysis/ScanLibraries/include/Trace.hpp @@ -0,0 +1,141 @@ +///@file Trace.hpp +///@brief A simple class to store the traces. +///@author S. Liddick, D. T. Miller, S. V. Paualuskas +///@date Long time ago. +#ifndef __TRACE_HPP__ +#define __TRACE_HPP__ + +#include +#include +#include +#include + +/// @brief This defines a more extensible implementation of a digitized trace. +/// The class is derived from a vector of unsigned integers. This is the basic +/// form of a trace from most digitizers. The Trace class enables processed +/// information about the trace (such as the baseline, integral, etc.). +/// +/// We also store information about the Waveform. The waveform is the part +/// of the trace that actually contains information about the signal that +/// was captured. This excludes the baseline. +class Trace : public std::vector { +public: + ///Default constructor + 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) {} + + ///@return Returns a std::pair containing the average and + /// standard deviation of the baseline as the .first and .second + /// respectively. + std::pair GetBaselineInfo() const { return baseline_; } + + ///@return Returns the waveform sans baseline + std::vector GetTraceSansBaseline() const { + return traceSansBaseline_; } + + ///@return Returns the energy sums that were set. + std::vector GetEnergySums() const { return esums_; } + + ///@return Returns a std::pair containing the + /// position of the maximum value in the trace and the amplitude of the + /// maximum that's been extrapolated and baseline subtracted as the .first + /// and .second respectively. + std::pair GetExtrapolatedMaxInfo() const { + return extrapolatedMax_; } + + ///@return Returns a std::pair containing the + /// position of the maximum value in the trace and the amplitude of the + /// maximum that's been baseline subtracted as the .first and .second + /// respectively. + std::pair GetMaxInfo() const { return max_; } + + ///@return The value of the QDC for the waveform + double GetQdc() const { return qdc_; } + + ///@return Returns the Trigger Filter that was set. + std::vector GetTriggerFilter() const { return trigFilter_; } + + ///@return Returns the baseline subtracted waveform found inside the trace. + std::vector GetWaveform() { + return std::vector(traceSansBaseline_.begin() + + waveformRange_.first, + traceSansBaseline_.begin() + + waveformRange_.second); } + + ///@return The bounds of the waveform in the trace + std::pair GetWaveformRange() const { + return waveformRange_; } + + ///@return Returns the waveform with the baseline + std::vector GetWaveformWithBaseline() { + return std::vector(begin() + waveformRange_.first, + begin() + waveformRange_.second); } + + ///@return True if the trace was saturated + bool IsSaturated() { return isSaturated_; } + + ///Sets the baseline information for the trace (average and standard + /// deviation) + ///@param[in] a : The pair containing the average and + /// standard deviation. + void SetBaseline(const std::pair &a) { baseline_ = a; } + + ///Sets the baseline subtracted trace. + ///@param[in] a : The vector that we are going to assign. + void SetTraceSansBaseline(const std::vector &a) { + traceSansBaseline_ = 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; } + + ///Sets the maximum information for the trace (position and baseline + /// subtracted extraploated value) + ///@param[in] a : The pair containing the position and + /// baseline subtracted extrapolated value. + void SetExtrapolatedMax(const std::pair &a) { + extrapolatedMax_ = a; } + + ///Sets the isSaturated_ private variable. + ///@param[in] a : Sets to true if the trace was flagged as saturated by + /// the electronics. + void SetIsSaturated(const bool &a) { isSaturated_ = a; } + + ///Sets the maximum information for the trace (position and baseline + /// subtracted value) + ///@param[in] a : The pair containing the position and + /// baseline subtracted value. + void SetMax(const std::pair &a) { max_ = a; } + + ///Sets the value of the QDC that was calculated from the waveform + ///@param[in] a : The value that we are going to set + void SetQdc(const double &a) { qdc_ = 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 bounds for the waveform + ///@param[in] a : the range we want to set + void SetWaveformRange(const std::pair &a) { + waveformRange_ = a; } + +private: + bool isSaturated_; ///< True if the trace was flagged as saturated. + + double qdc_; ///< The qdc that was calculated from the waveform. + + std::pair baseline_; ///< Baseline Average and Std. Dev. + std::pair max_; ///< Max position and value sans baseline + std::pair extrapolatedMax_; ///< Max position and extrapolated value + std::pair waveformRange_; ///< Waveform Range + + std::vector traceSansBaseline_; ///< Baseline subtracted trace + std::vector trigFilter_; ///< The trigger filter for the trace + std::vector esums_; ///< The Energy sums calculated from the trace +}; + +#endif // __TRACE_H_ \ No newline at end of file diff --git a/Analysis/ScanLibraries/tests/CMakeLists.txt b/Analysis/ScanLibraries/tests/CMakeLists.txt index f4ac7581a..e04d6b979 100644 --- a/Analysis/ScanLibraries/tests/CMakeLists.txt +++ b/Analysis/ScanLibraries/tests/CMakeLists.txt @@ -1,3 +1,4 @@ +################################################################################ add_executable(unittest-XiaListModeDataDecoder unittest-XiaListModeDataDecoder.cpp ../source/XiaData.cpp @@ -6,6 +7,7 @@ add_executable(unittest-XiaListModeDataDecoder target_link_libraries(unittest-XiaListModeDataDecoder UnitTest++ ${LIBS}) install(TARGETS unittest-XiaListModeDataDecoder DESTINATION bin/unittests) +################################################################################ add_executable(unittest-XiaListModeDataEncoder unittest-XiaListModeDataEncoder.cpp ../source/XiaData.cpp @@ -14,6 +16,7 @@ add_executable(unittest-XiaListModeDataEncoder target_link_libraries(unittest-XiaListModeDataEncoder UnitTest++ ${LIBS}) install(TARGETS unittest-XiaListModeDataEncoder DESTINATION bin/unittests) +################################################################################ add_executable(unittest-XiaListModeDataMask unittest-XiaListModeDataMask.cpp ../source/XiaData.cpp @@ -21,6 +24,12 @@ add_executable(unittest-XiaListModeDataMask 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 +install(TARGETS unittest-XiaData DESTINATION bin/unittests) + +################################################################################ +add_executable(unittest-Trace unittest-Trace.cpp) +target_link_libraries(unittest-Trace UnitTest++ ${LIBS}) +install(TARGETS unittest-Trace DESTINATION bin/unittests) \ No newline at end of file diff --git a/Analysis/ScanLibraries/tests/unittest-Trace.cpp b/Analysis/ScanLibraries/tests/unittest-Trace.cpp new file mode 100644 index 000000000..58940da39 --- /dev/null +++ b/Analysis/ScanLibraries/tests/unittest-Trace.cpp @@ -0,0 +1,59 @@ +///@file unittest-Trace.cpp +///@brief A program that will execute unit tests on Trace +///@author S. V. Paulauskas +///@date February 3, 2017 +#include + +#include + +#include + +#include "UnitTestSampleData.hpp" +#include "Trace.hpp" + +using namespace std; +using namespace unittest_trace_variables; +using namespace unittest_decoded_data; + +TEST_FIXTURE(Trace, TestingGettersAndSetters){ + SetBaseline(baseline_pair); + CHECK_EQUAL(baseline_pair.first, GetBaselineInfo().first); + CHECK_EQUAL(baseline_pair.second, GetBaselineInfo().second); + + SetMax(max_pair); + CHECK_EQUAL(max_pair.first, GetMaxInfo().first); + CHECK_EQUAL(max_pair.second, GetMaxInfo().second); + + SetWaveformRange(waveform_range); + CHECK_EQUAL(waveform_range.first, GetWaveformRange().first); + CHECK_EQUAL(waveform_range.second, GetWaveformRange().second); + + SetTraceSansBaseline(trace_sans_baseline); + CHECK_ARRAY_EQUAL(trace_sans_baseline, GetTraceSansBaseline(), + trace_sans_baseline.size()); + + CHECK_ARRAY_EQUAL(waveform, GetWaveform(), waveform.size()); + + SetTriggerFilter(trace_sans_baseline); + CHECK_ARRAY_EQUAL(trace_sans_baseline, GetTriggerFilter(), + trace_sans_baseline.size()); + + SetEnergySums(waveform); + CHECK_ARRAY_EQUAL(waveform, GetEnergySums(), waveform.size()); + + SetQdc(100.); + CHECK_EQUAL(100., GetQdc()); + + SetExtrapolatedMax(extrapolated_maximum_pair); + CHECK_EQUAL(extrapolated_maximum_pair.first, + GetExtrapolatedMaxInfo().first); + CHECK_EQUAL(extrapolated_maximum_pair.second, + GetExtrapolatedMaxInfo().second); + + SetIsSaturated(true); + CHECK(IsSaturated()); +} + +int main(int argv, char *argc[]) { + return (UnitTest::RunAllTests()); +} \ No newline at end of file diff --git a/Analysis/Utkscan/core/include/Trace.hpp b/Analysis/Utkscan/core/include/Trace.hpp deleted file mode 100644 index 131d80389..000000000 --- a/Analysis/Utkscan/core/include/Trace.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/** \file Trace.hpp - * \brief A simple class to store the traces. - * - * A simple class to store the traces. - * Used instead of a typedef so additional functionality can be added later. - */ -#ifndef __TRACE_HPP__ -#define __TRACE_HPP__ - -#include -#include -#include -#include - -#include - -#include "DammPlotIds.hpp" -#include "Globals.hpp" -#include "Plots.hpp" -#include "PlotsRegister.hpp" - -//! \brief Store the information for a trace -class Trace : public std::vector { -public: - /** Default constructor */ - 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) {} - - /** 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)); - } - - /** 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)); - } - - /** 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) - doubleTraceData[name] = value; - else - 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) - intTraceData[name] = value; - else - InsertValue(name, value); - } - - /** Checks to see if a parameter has a value - * \param [in] name : the name of the parameter to check for - * \return true if the value exists in the trace */ - bool HasValue(const std::string &name) const { - return (doubleTraceData.count(name) > 0 || - intTraceData.count(name) > 0); - } - - /** Returns the value of the requested parameter - * \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) - return (*doubleTraceData.find(name)).second; - if (intTraceData.count(name) > 0) - return (*intTraceData.find(name)).second; - return (NAN); - } - - /** \return Returns the waveform found inside the trace */ - 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) { - histo.DeclareHistogram1D(dammId, xSize, title); - } - - /*! \brief Declares a 2D 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] 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) { - histo.DeclareHistogram2D(dammId, xSize, ySize, title); - } - - /*! \brief Implementation of the plot command to interface with the DAMM - * routines - * - * This is also done in the EventProcessor class, redundant? - * \param [in] dammId : The histogram number to plot into - * \param [in] val1 : The x value to plot - * \param [in] val2 : The y value to plot (if 2D histogram) - * \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 { - 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 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; } - -private: - //!< 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 - - /** 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/Analysis/Utkscan/core/source/CMakeLists.txt b/Analysis/Utkscan/core/source/CMakeLists.txt index c291d0414..ee87d8849 100644 --- a/Analysis/Utkscan/core/source/CMakeLists.txt +++ b/Analysis/Utkscan/core/source/CMakeLists.txt @@ -14,7 +14,6 @@ set(CORE_SOURCES # StatsData.cpp TimingCalibrator.cpp TimingMapBuilder.cpp - Trace.cpp UtkScanInterface.cpp UtkUnpacker.cpp WalkCorrector.cpp diff --git a/Analysis/Utkscan/core/source/Trace.cpp b/Analysis/Utkscan/core/source/Trace.cpp deleted file mode 100644 index 08edeaa83..000000000 --- a/Analysis/Utkscan/core/source/Trace.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** \file Trace.cpp - * \brief Implement how to do our usual tricks with traces - */ -#include -#include -#include -#include - -#include "Trace.hpp" - -using namespace std; - -namespace dammIds { - namespace trace { - } -} - -///This creates the static instance of the Plots class before main. This may -///cause a static initialization order fiasco. Be AWARE!! -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, (int)at(i)); - } -} - -void Trace::Plot(int id, int row) { - for (size_type i=0; i < size(); 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((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((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., (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., (int)at(i) - offset)); - } -} diff --git a/Resources/include/UnitTestSampleData.hpp b/Resources/include/UnitTestSampleData.hpp index facfd2c2b..96a62734c 100644 --- a/Resources/include/UnitTestSampleData.hpp +++ b/Resources/include/UnitTestSampleData.hpp @@ -183,11 +183,14 @@ namespace unittest_trace_variables { 19.2571, 18.2571 }; + //This is the range of the waveform in the trace. + static const std::pair waveform_range(71, 86); + //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); + trace_sans_baseline.begin() + waveform_range.first, + trace_sans_baseline.begin() + waveform_range.second); //An empty data vector to test error checking. static const std::vector empty_vector_uint; @@ -232,6 +235,7 @@ namespace unittest_trace_variables { //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); From 3c8c0baf4aa65ddcb22c35929d72f4f23bd32658 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:45:31 -0500 Subject: [PATCH 161/255] Updating Trace class with a few more methods There were a few things that I forgot to add to the trace class. Most notably the phase. --- Analysis/ScanLibraries/include/Trace.hpp | 27 ++++++++++++------- .../ScanLibraries/tests/unittest-Trace.cpp | 3 +++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Analysis/ScanLibraries/include/Trace.hpp b/Analysis/ScanLibraries/include/Trace.hpp index 6a71f72d6..ee7dbce4a 100644 --- a/Analysis/ScanLibraries/include/Trace.hpp +++ b/Analysis/ScanLibraries/include/Trace.hpp @@ -32,10 +32,6 @@ class Trace : public std::vector { /// respectively. std::pair GetBaselineInfo() const { return baseline_; } - ///@return Returns the waveform sans baseline - std::vector GetTraceSansBaseline() const { - return traceSansBaseline_; } - ///@return Returns the energy sums that were set. std::vector GetEnergySums() const { return esums_; } @@ -52,9 +48,16 @@ class Trace : public std::vector { /// respectively. std::pair GetMaxInfo() const { return max_; } + ///@return The phase of the trace. + double GetPhase() const { return phase_; } + ///@return The value of the QDC for the waveform double GetQdc() const { return qdc_; } + ///@return Returns the waveform sans baseline + std::vector GetTraceSansBaseline() const { + return traceSansBaseline_; } + ///@return Returns the Trigger Filter that was set. std::vector GetTriggerFilter() const { return trigFilter_; } @@ -83,11 +86,6 @@ class Trace : public std::vector { /// standard deviation. void SetBaseline(const std::pair &a) { baseline_ = a; } - ///Sets the baseline subtracted trace. - ///@param[in] a : The vector that we are going to assign. - void SetTraceSansBaseline(const std::vector &a) { - traceSansBaseline_ = 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; } @@ -110,10 +108,20 @@ class Trace : public std::vector { /// baseline subtracted value. void SetMax(const std::pair &a) { max_ = a; } + ///Sets the sub-sampling phase of the trace. + ///@param[in] a : The value of the phase that we want to set. This + /// comes from a fit or CFD analysis of the trace. + void SetPhase(const double &a) { phase_ = a; } + ///Sets the value of the QDC that was calculated from the waveform ///@param[in] a : The value that we are going to set void SetQdc(const double &a) { qdc_ = a; } + ///Sets the baseline subtracted trace. + ///@param[in] a : The vector that we are going to assign. + void SetTraceSansBaseline(const std::vector &a) { + traceSansBaseline_ = 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; } @@ -126,6 +134,7 @@ class Trace : public std::vector { private: bool isSaturated_; ///< True if the trace was flagged as saturated. + double phase_; ///< The sub-sampling phase of the trace. double qdc_; ///< The qdc that was calculated from the waveform. std::pair baseline_; ///< Baseline Average and Std. Dev. diff --git a/Analysis/ScanLibraries/tests/unittest-Trace.cpp b/Analysis/ScanLibraries/tests/unittest-Trace.cpp index 58940da39..bc6fdd077 100644 --- a/Analysis/ScanLibraries/tests/unittest-Trace.cpp +++ b/Analysis/ScanLibraries/tests/unittest-Trace.cpp @@ -52,6 +52,9 @@ TEST_FIXTURE(Trace, TestingGettersAndSetters){ SetIsSaturated(true); CHECK(IsSaturated()); + + SetPhase(100.); + CHECK_EQUAL(100., GetPhase()); } int main(int argv, char *argc[]) { From ffa4073910b8adb3071d6854a6657676f68d2390 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:46:36 -0500 Subject: [PATCH 162/255] Updating the CMakeLists for the ScanLibraries It seems that this got reverted to the old version before the library names were changed. I've fixed this since it was causing failed compilations of Skeleton. --- Analysis/ScanLibraries/source/CMakeLists.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Analysis/ScanLibraries/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt index 674926281..2c2e99346 100644 --- a/Analysis/ScanLibraries/source/CMakeLists.txt +++ b/Analysis/ScanLibraries/source/CMakeLists.txt @@ -1,28 +1,28 @@ #Set the scan sources that we will make a lib out of -set(ScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp +set(PaassScanSources ScanInterface.cpp Unpacker.cpp XiaData.cpp ChannelData.cpp ChannelEvent.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp XiaListModeDataEncoder.cpp) if(USE_ROOT) - list(APPEND ScanSources RootScanner.cpp) + list(APPEND PaassScanSources RootScanner.cpp) endif(USE_ROOT) #Add the sources to the library -add_library(ScanObjects OBJECT ${ScanSources}) +add_library(PaassScanObjects OBJECT ${PaassScanSources}) if(BUILD_SHARED_LIBS) message(STATUS "Building Scan Shared Objects") - add_library(Scan SHARED $) - target_link_libraries(Scan PixieCoreStatic ${CMAKE_THREAD_LIBS_INIT}) + add_library(PaassScan SHARED $) + target_link_libraries(PaassScan PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(Scan ${CURSES_LIBRARIES}) + target_link_libraries(PaassScan ${CURSES_LIBRARIES}) endif() - install(TARGETS Scan DESTINATION lib) + install(TARGETS PaassScan 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}) +add_library(PaassScanStatic STATIC $) +target_link_libraries(PaassScanStatic PaassCoreStatic ${CMAKE_THREAD_LIBS_INIT}) if (${CURSES_FOUND}) - target_link_libraries(ScanStatic ${CURSES_LIBRARIES}) + target_link_libraries(PaassScanStatic ${CURSES_LIBRARIES}) endif() From fc5be736e1208a2bba8c51dc26c361cfca7d6f34 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:49:33 -0500 Subject: [PATCH 163/255] ProcessedXiaData now contains the Trace class. Adding Methods. The Trace class was added here since it's the logical place for it to be carried around. This also mimics what was previously done in utkscan::ChanEvent, and the ChannelEvent class. I've also added some new methods to the class for walk corrections, energy calibrations, etc. These are data that have been massaged in some way. --- .../include/ProcessedXiaData.hpp | 58 +++++++++++++++---- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp index b1f786518..251f28427 100644 --- a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp +++ b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp @@ -4,8 +4,8 @@ ///@date December 2, 2016 #ifndef PIXIESUITE_PROCESSEDXIADATA_HPP #define PIXIESUITE_PROCESSEDXIADATA_HPP -#include +#include "Trace.hpp" #include "XiaData.hpp" ///This class contains additional information about the XiaData after @@ -15,25 +15,61 @@ class ProcessedXiaData : public XiaData { public: /// Default constructor. - ProcessedXiaData() {Clear();} + ProcessedXiaData() {} /// Constructor from XiaData. ProcessedXiaData will take ownership via - /// the unique pointer. + /// the unique pointer. We also assign the trace to the Trace class and + /// set the saturation flag in the Trace. This will allow people to + /// access this information should the Trace be passed separately from + /// the rest of the data. ProcessedXiaData(XiaData *event) { data_ = event; + trace_ = data_->GetTrace(); + trace_.SetIsSaturated(data_->IsSaturated()); } /// Default Destructor. - ~ProcessedXiaData(){}; + ~ProcessedXiaData() {}; + + ///\return The calibrated energy for the channel + double GetCalibratedEnergy() const { return calibratedEnergy_; } + + ///\return The Walk corrected time of the channel + double GetWalkCorrectedTime() const { return walkCorrectedTime_; } + + ///\return The sub-sampling arrival time of the signal in nanoseconds. + double GetHighResTimeInNs() const { return highResTimeInNs_; } + + ///Set the calibrated energy + ///@param [in] a : the calibrated energy + void SetCalibratedEnergy(const double &a) { calibratedEnergy_ = a; } + + ///Set to True if we would like to ignore this channel + ///@param[in] a : The value that we want to set + void SetIsIgnored(const bool &a) { isIgnored_ = a; } + + ///Set to true if the energy and time are not bogus values. + ///@param[in] a : The value that we would like to set + void SetIsValidData(const bool &a) { isValidData_; } + + ///Set the high resolution time (Filter time (sans CFD) + phase ) + ///@param [in] a : the high resolution time + void SetHighResTime(const double &a) { highResTimeInNs_ = a; } + + ///Set the Walk corrected time + ///@param [in] a : the walk corrected time */ + void SetWalkCorrectedTime(const double &a) { walkCorrectedTime_ = a; } + private: - ///A pointer to the XiaData - XiaData *data_; + XiaData *data_; ///< A pointer to the XiaData that we now own. + Trace trace_; ///< A Trace object to handle the Trace related stuff. - /// Clear all variables and clear the trace vector and arrays. - void Initialize(){}; + bool isIgnored_; ///< True if we ignore this event. + bool isValidData_; ///< True if the energy and High Res time are valid. - bool isIgnored_; /// Ignore this event. - bool isValidData; /// True if the high resolution energy and time are valid. - double hires_time; /// High resolution time taken from pulse fits (in ns). + double calibratedEnergy_; ///< The energy after calibration + double highResTimeInNs_; ///< High Res time taken from pulse fits (in ns). + double walkCorrectedTime_; ///< The time after walk corrections }; + #endif //PIXIESUITE_PROCESSEDXIADATA_HPP From 834d74f3c8a749b88e8c50d91d7f837c9af101e2 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:54:12 -0500 Subject: [PATCH 164/255] Removing ChannelData and ChannelEvent from compilation These have been replaced with ProcessedXiaData --- Analysis/ScanLibraries/source/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Analysis/ScanLibraries/source/CMakeLists.txt b/Analysis/ScanLibraries/source/CMakeLists.txt index 2c2e99346..446eaec5e 100644 --- a/Analysis/ScanLibraries/source/CMakeLists.txt +++ b/Analysis/ScanLibraries/source/CMakeLists.txt @@ -1,6 +1,6 @@ #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 +set(PaassScanSources ProcessedXiaData.cpp ScanInterface.cpp Unpacker.cpp + XiaData.cpp XiaListModeDataMask.cpp XiaListModeDataDecoder.cpp XiaListModeDataEncoder.cpp) if(USE_ROOT) From 39dfd66d79c8d7dc59fdc8f96e3a8050cbc2d9b7 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 13:54:44 -0500 Subject: [PATCH 165/255] Fixing assignment in ProcessedXiaData::SetIsValidData --- Analysis/ScanLibraries/include/ProcessedXiaData.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp index 251f28427..f6c70870c 100644 --- a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp +++ b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp @@ -50,7 +50,7 @@ class ProcessedXiaData : public XiaData { ///Set to true if the energy and time are not bogus values. ///@param[in] a : The value that we would like to set - void SetIsValidData(const bool &a) { isValidData_; } + void SetIsValidData(const bool &a) { isValidData_ = a; } ///Set the high resolution time (Filter time (sans CFD) + phase ) ///@param [in] a : the high resolution time From e1af4208d03cf78d46b11175ddb1ee63a1216d05 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 14:03:07 -0500 Subject: [PATCH 166/255] Adding in the GetTrace() method. This overrides the one from the parent --- Analysis/ScanLibraries/include/ProcessedXiaData.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp index f6c70870c..3495e5224 100644 --- a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp +++ b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp @@ -34,12 +34,15 @@ class ProcessedXiaData : public XiaData { ///\return The calibrated energy for the channel double GetCalibratedEnergy() const { return calibratedEnergy_; } - ///\return The Walk corrected time of the channel - double GetWalkCorrectedTime() const { return walkCorrectedTime_; } - ///\return The sub-sampling arrival time of the signal in nanoseconds. double GetHighResTimeInNs() const { return highResTimeInNs_; } + ///\return The Trace object. + Trace GetTrace() const { return trace_; } + + ///\return The Walk corrected time of the channel + double GetWalkCorrectedTime() const { return walkCorrectedTime_; } + ///Set the calibrated energy ///@param [in] a : the calibrated energy void SetCalibratedEnergy(const double &a) { calibratedEnergy_ = a; } From c603c89517a8465b1043df9b1302539de770ec27 Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 14:33:03 -0500 Subject: [PATCH 167/255] Changing the way the Trace is accessed. We create two different methods for accessing the Trace. One will provide a constant reference to the Trace that we can alter. The other will provide a reference to a constant memory block that we cannot alter. --- Analysis/ScanLibraries/include/ProcessedXiaData.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp index 3495e5224..46de546a1 100644 --- a/Analysis/ScanLibraries/include/ProcessedXiaData.hpp +++ b/Analysis/ScanLibraries/include/ProcessedXiaData.hpp @@ -31,16 +31,19 @@ class ProcessedXiaData : public XiaData { /// Default Destructor. ~ProcessedXiaData() {}; - ///\return The calibrated energy for the channel + ///@return The calibrated energy for the channel double GetCalibratedEnergy() const { return calibratedEnergy_; } - ///\return The sub-sampling arrival time of the signal in nanoseconds. + ///@return The sub-sampling arrival time of the signal in nanoseconds. double GetHighResTimeInNs() const { return highResTimeInNs_; } - ///\return The Trace object. - Trace GetTrace() const { return trace_; } + ///@return A constant reference to the trace. + const Trace& GetTrace() const { return trace_; } - ///\return The Walk corrected time of the channel + ///@return An editable trace. + Trace& GetTrace() { return trace_; } + + ///@return The Walk corrected time of the channel double GetWalkCorrectedTime() const { return walkCorrectedTime_; } ///Set the calibrated energy From 3cdb6176292cd09955fbc7e31a6da48c4efe42ad Mon Sep 17 00:00:00 2001 From: "S.V. Paulauskas" Date: Fri, 3 Feb 2017 14:33:33 -0500 Subject: [PATCH 168/255] Fitting using scope now works as it should. --- Analysis/Utilities/include/scope.hpp | 4 +- Analysis/Utilities/source/scope.cpp | 182 +++++++++++++++------------ 2 files changed, 106 insertions(+), 80 deletions(-) diff --git a/Analysis/Utilities/include/scope.hpp b/Analysis/Utilities/include/scope.hpp index c2151eed4..ac572571a 100644 --- a/Analysis/Utilities/include/scope.hpp +++ b/Analysis/Utilities/include/scope.hpp @@ -11,7 +11,7 @@ #include "RootScanner.hpp" -class ChannelEvent; +class ProcessedXiaData; class TGraph; class TH2F; class TF1; @@ -207,7 +207,7 @@ class scopeScanner : public RootScanner { bool performCfd_; std::vector x_vals; - std::deque chanEvents_; /// chanEvents_; /// // PixieCore libraries -#include "ChannelEvent.hpp" +#include "ProcessedXiaData.hpp" #include "HelperFunctions.hpp" -#include "XiaData.hpp" // Local files #include "scope.hpp" @@ -36,6 +35,10 @@ #define ADC_TIME_STEP 4 // ns #define SLEEP_WAIT 1E4 // When not in shared memory mode, length of time to wait after gSystem->ProcessEvents is called (in us). +using namespace std; +using namespace TraceFunctions; + + /**The Paulauskas function is described in NIM A 737 (22), with a slight * adaptation. We use a step function such that f(x < phase) = baseline. * In addition, we also we formulate gamma such that the gamma in the paper is @@ -99,8 +102,8 @@ void scopeUnpacker::ProcessRawEvent(ScanInterface *addr_/*=NULL*/){ // Pass this event to the correct processor double maximum = - TraceFunctions::FindMaximum(current_event->GetTrace(), - current_event->GetTrace().size()).second; + FindMaximum(current_event->GetTrace(), + current_event->GetTrace().size()).second; if(current_event->GetModuleNumber() == mod_ && current_event->GetChannelNumber() == chan_){ //Check threhsold. if (maximum < threshLow_) { @@ -190,14 +193,14 @@ void scopeScanner::ResetGraph(unsigned int size) { graph->SetMarkerStyle(kFullDotSmall); 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"; + cout << msgHeader << "Changing trace length from " << x_vals.size()*ADC_TIME_STEP << " to " << size*ADC_TIME_STEP << " ns.\n"; x_vals.resize(size); for(size_t index = 0; index < x_vals.size(); index++) x_vals[index] = ADC_TIME_STEP * index; } hist->SetBins(x_vals.size(), x_vals.front(), x_vals.back() + ADC_TIME_STEP, 1, 0, 1); - std::stringstream stream; + stringstream stream; stream << "M" << ((scopeUnpacker*)core)->GetMod() << "C" << ((scopeUnpacker*)core)->GetChan(); graph->SetTitle(stream.str().c_str()); hist->SetTitle(stream.str().c_str()); @@ -211,11 +214,16 @@ void scopeScanner::Plot(){ if(chanEvents_.size() < numAvgWaveforms_) return; - if(chanEvents_.front()->size != x_vals.size()){ // The length of the trace has changed. + unsigned int traceSize = chanEvents_.front()->GetTrace().size(); + + if(traceSize != x_vals.size()){ // The length + // of the + // trace + // has changed. resetGraph_ = true; } if (resetGraph_) { - ResetGraph(chanEvents_.front()->size); + ResetGraph(traceSize); ResetZoom(); for (int i=0;i<2;i++) { histAxis[i][0] = 1E9; @@ -226,8 +234,8 @@ void scopeScanner::Plot(){ //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->GetTrace().at(i)); + for (size_t i = 0; i < traceSize; ++i) { + graph->SetPoint(index, x_vals[i], chanEvents_.front()->GetTrace().at(i)); index++; } @@ -235,13 +243,15 @@ void scopeScanner::Plot(){ graph->Draw("AP0"); - float lowVal = (chanEvents_.front()->max_index - fitLow_) * ADC_TIME_STEP; - float highVal = (chanEvents_.front()->max_index + fitHigh_) * ADC_TIME_STEP; + float lowVal = (chanEvents_.front()->GetTrace().GetMaxInfo().first - + fitLow_) * ADC_TIME_STEP; + float highVal = (chanEvents_.front()->GetTrace().GetMaxInfo().first + + fitHigh_) * ADC_TIME_STEP; ///@TODO Renable the CFD with the proper functionality. /* if(performCfd_){ - ChannelEvent *evt = chanEvents_.front(); + ProcessedXiaData *evt = chanEvents_.front(); // Find the zero-crossing of the cfd waveform. float cfdCrossing = evt->AnalyzeCFD(cfdF_); @@ -252,8 +262,8 @@ void scopeScanner::Plot(){ // 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)); + cfdPol3->SetParameter(2, evt->cfdPar[2]/pow(ADC_TIME_STEP, 2.0)); + cfdPol3->SetParameter(3, evt->cfdPar[3]/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); @@ -264,7 +274,7 @@ void scopeScanner::Plot(){ // 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->SetParameter(2, evt->cfdPar[6]/pow(ADC_TIME_STEP, 2.0)); cfdPol2->SetRange((evt->cfdIndex - 1)*ADC_TIME_STEP, (evt->cfdIndex + 1)*ADC_TIME_STEP); cfdPol2->Draw("SAME"); } @@ -272,17 +282,21 @@ void scopeScanner::Plot(){ if(performFit_){ paulauskasFunc->SetRange(lowVal, highVal); - paulauskasFunc->SetParameters(chanEvents_.front()->baseline, 0.5 * chanEvents_.front()->qdc, lowVal, 0.5, 0.1); - paulauskasFunc->FixParameter(0, chanEvents_.front()->baseline); + paulauskasFunc->SetParameters( + chanEvents_.front()->GetTrace().GetBaselineInfo().first, + 0.5 * chanEvents_.front()->GetTrace().GetQdc(), + lowVal, 0.5, 0.1); + paulauskasFunc->FixParameter( + 0, chanEvents_.front()->GetTrace().GetBaselineInfo().first); graph->Fit(paulauskasFunc,"QMER"); } } else { //For multiple events with make a 2D histogram and plot the profile on top. //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->GetTrace().begin(), evt->event->GetTrace().end()); - float evtMax = *std::max_element(evt->event->GetTrace().begin(), evt->event->GetTrace().end()); + ProcessedXiaData* evt = chanEvents_.at(i); + float evtMin = *min_element(evt->GetTrace().begin(), evt->GetTrace().end()); + float evtMax = *max_element(evt->GetTrace().begin(), evt->GetTrace().end()); evtMin -= fabs(0.1 * evtMax); evtMax += fabs(0.1 * evtMax); if (evtMin < histAxis[1][0]) histAxis[1][0] = evtMin; @@ -297,9 +311,9 @@ void scopeScanner::Plot(){ //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->GetTrace()[i]); + ProcessedXiaData* evt = chanEvents_.at(i); + for (size_t i=0; i < evt->GetTrace().size(); ++i) { + hist->Fill(x_vals[i], evt->GetTrace()[i]); } } @@ -312,8 +326,12 @@ void scopeScanner::Plot(){ if(performFit_){ paulauskasFunc->SetRange(lowVal, highVal); - paulauskasFunc->SetParameters(chanEvents_.front()->baseline, 0.5 * chanEvents_.front()->qdc, lowVal, 0.5, 0.2); - paulauskasFunc->FixParameter(0, chanEvents_.front()->baseline); + paulauskasFunc->SetParameters( + chanEvents_.front()->GetTrace().GetBaselineInfo().first, + 0.5 * chanEvents_.front()->GetTrace().GetQdc(), + lowVal, 0.5, 0.2); + paulauskasFunc->FixParameter( + 0, chanEvents_.front()->GetTrace().GetBaselineInfo().first); prof->Fit(paulauskasFunc,"QMER"); } @@ -356,11 +374,11 @@ void scopeScanner::Plot(){ * \param[in] prefix_ String to append to the beginning of system output. * \return True upon successfully initializing and false otherwise. */ -bool scopeScanner::Initialize(std::string prefix_){ +bool scopeScanner::Initialize(string prefix_){ if(init){ return false; } // Print a small welcome message. - std::cout << " Displaying traces for mod = " << ((scopeUnpacker*)core)->GetMod() << ", chan = " << ((scopeUnpacker*)core)->GetChan() << ".\n"; + cout << " Displaying traces for mod = " << ((scopeUnpacker*)core)->GetMod() << ", chan = " << ((scopeUnpacker*)core)->GetChan() << ".\n"; return (init = true); } @@ -369,16 +387,16 @@ bool scopeScanner::Initialize(std::string prefix_){ * \param[in] code_ The notification code passed from ScanInterface methods. * \return Nothing. */ -void scopeScanner::Notify(const std::string &code_/*=""*/){ +void scopeScanner::Notify(const string &code_/*=""*/){ if(code_ == "START_SCAN"){ ClearEvents(); acqRun_ = true; } else if(code_ == "STOP_SCAN"){ acqRun_ = false; } - else if(code_ == "SCAN_COMPLETE"){ std::cout << msgHeader << "Scan complete.\n"; } - else if(code_ == "LOAD_FILE"){ std::cout << msgHeader << "File loaded.\n"; } + else if(code_ == "SCAN_COMPLETE"){ cout << msgHeader << "Scan complete.\n"; } + else if(code_ == "LOAD_FILE"){ cout << msgHeader << "File loaded.\n"; } else if(code_ == "REWIND_FILE"){ } - else{ std::cout << msgHeader << "Unknown notification code '" << code_ << "'!\n"; } + else{ cout << msgHeader << "Unknown notification code '" << code_ << "'!\n"; } } /** Return a pointer to the Unpacker object to use for data unpacking. @@ -399,13 +417,21 @@ bool scopeScanner::AddEvent(XiaData *event_){ if(!event_){ return false; } //Get the first event int the FIFO. - ChannelEvent *channel_event = new ChannelEvent(event_); + ProcessedXiaData *channel_event = new ProcessedXiaData(event_); //Process the waveform. - ///@TODO : Renable this with the Helper functions. - //channel_event->ComputeBaseline(); - //channel_event->FindQDC(); - + ///@TODO This needs cleaned up quite a bit to make it more generalized + /// and remove some of the magic numbers. + channel_event->GetTrace().SetBaseline(CalculateBaseline + (channel_event->GetTrace(), + make_pair(0, 10))); + channel_event->GetTrace().SetMax(FindMaximum + (channel_event->GetTrace(), + channel_event->GetTrace().size())); + channel_event->GetTrace().SetQdc(CalculateQdc + (channel_event->GetTrace(), + make_pair(5,15))); + //Push the channel event into the deque. chanEvents_.push_back(channel_event); @@ -461,19 +487,19 @@ void scopeScanner::ClearEvents(){ * \param[in] prefix_ String to append at the start of any output. Not used by default. * \return Nothing. */ -void scopeScanner::CmdHelp(const std::string &prefix_/*=""*/){ - std::cout << " set - Set the module and channel of signal of interest (default = 0, 0).\n"; - std::cout << " stop - Stop the acquistion.\n"; - std::cout << " run - Run the acquistion.\n"; - std::cout << " single - Perform a single capture.\n"; - std::cout << " thresh [high] - Set the plotting window for trace maximum.\n"; - std::cout << " fit - Turn on fitting of waveform. Set to \"off\" to disable.\n"; - std::cout << " cfd [F=0.5] [D=1] [L=1] - Turn on cfd analysis of waveform. Set [F] to \"off\" to disable.\n"; - std::cout << " avg - Set the number of waveforms to average.\n"; - std::cout << " save - Save the next trace to the specified file name..\n"; - std::cout << " delay [time] - Set the delay between drawing traces (in seconds, default = 1 s).\n"; - std::cout << " log - Toggle log/linear mode on the y-axis.\n"; - std::cout << " clear - Clear all stored traces and start over.\n"; +void scopeScanner::CmdHelp(const string &prefix_/*=""*/){ + cout << " set - Set the module and channel of signal of interest (default = 0, 0).\n"; + cout << " stop - Stop the acquistion.\n"; + cout << " run - Run the acquistion.\n"; + cout << " single - Perform a single capture.\n"; + cout << " thresh [high] - Set the plotting window for trace maximum.\n"; + cout << " fit - Turn on fitting of waveform. Set to \"off\" to disable.\n"; + cout << " cfd [F=0.5] [D=1] [L=1] - Turn on cfd analysis of waveform. Set [F] to \"off\" to disable.\n"; + cout << " avg - Set the number of waveforms to average.\n"; + cout << " save - Save the next trace to the specified file name..\n"; + cout << " delay [time] - Set the delay between drawing traces (in seconds, default = 1 s).\n"; + cout << " log - Toggle log/linear mode on the y-axis.\n"; + cout << " clear - Clear all stored traces and start over.\n"; } /** ArgHelp is used to allow a derived class to add a command line option @@ -492,7 +518,7 @@ void scopeScanner::ArgHelp(){ * \return Nothing. */ void scopeScanner::SyntaxStr(char *name_){ - std::cout << " usage: " << std::string(name_) << " [options]\n"; + cout << " usage: " << string(name_) << " [options]\n"; } /** ExtraArguments is used to send command line arguments to classes derived @@ -503,9 +529,9 @@ void scopeScanner::SyntaxStr(char *name_){ */ void scopeScanner::ExtraArguments(){ if(userOpts.at(0).active) - std::cout << msgHeader << "Set module to (" << ((scopeUnpacker*)core)->SetMod(atoi(userOpts.at(0).argument.c_str())) << ").\n"; + cout << msgHeader << "Set module to (" << ((scopeUnpacker*)core)->SetMod(atoi(userOpts.at(0).argument.c_str())) << ").\n"; if(userOpts.at(1).active) - std::cout << msgHeader << "Set channel to (" << ((scopeUnpacker*)core)->SetChan(atoi(userOpts.at(1).argument.c_str())) << ").\n"; + cout << msgHeader << "Set channel to (" << ((scopeUnpacker*)core)->SetChan(atoi(userOpts.at(1).argument.c_str())) << ").\n"; } /** ExtraCommands is used to send command strings to classes derived @@ -515,7 +541,7 @@ void scopeScanner::ExtraArguments(){ * \param[out] arg_ Vector or arguments to the user command. * \return True if the command was recognized and false otherwise. */ -bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vector &args_){ +bool scopeScanner::ExtraCommands(const string &cmd_, vector &args_){ if(cmd_ == "set"){ // Toggle debug mode if(args_.size() == 2){ // Clear all events from the event deque. @@ -528,8 +554,8 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vector \n"; + cout << msgHeader << "Invalid number of parameters to 'set'\n"; + cout << msgHeader << " -SYNTAX- set \n"; } } else if(cmd_ == "single") { @@ -545,30 +571,30 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vectorSetThreshHigh(atoi(args_.at(1).c_str())); } else { - std::cout << msgHeader << "Invalid number of parameters to 'thresh'\n"; - std::cout << msgHeader << " -SYNTAX- thresh [upperThresh]\n"; + cout << msgHeader << "Invalid number of parameters to 'thresh'\n"; + cout << msgHeader << " -SYNTAX- thresh [upperThresh]\n"; } } else if (cmd_ == "fit") { if (args_.size() >= 1 && args_.at(0) == "off") { // Turn root fitting off. if(performFit_){ - std::cout << msgHeader << "Disabling root fitting.\n"; + cout << msgHeader << "Disabling root fitting.\n"; delete graph->GetListOfFunctions()->FindObject(paulauskasFunc->GetName()); GetCanvas()->Update(); performFit_ = false; } - else{ std::cout << msgHeader << "Fitting is not enabled.\n"; } + else{ cout << msgHeader << "Fitting is not enabled.\n"; } } else if (args_.size() == 2) { // Turn root fitting on. fitLow_ = atoi(args_.at(0).c_str()); fitHigh_ = atoi(args_.at(1).c_str()); - std::cout << msgHeader << "Setting root fitting range to [" << fitLow_ << ", " << fitHigh_ << "].\n"; + cout << msgHeader << "Setting root fitting range to [" << fitLow_ << ", " << fitHigh_ << "].\n"; performFit_ = true; } else { - std::cout << msgHeader << "Invalid number of parameters to 'fit'\n"; - std::cout << msgHeader << " -SYNTAX- fit \n"; - std::cout << msgHeader << " -SYNTAX- fit off\n"; + cout << msgHeader << "Invalid number of parameters to 'fit'\n"; + cout << msgHeader << " -SYNTAX- fit \n"; + cout << msgHeader << " -SYNTAX- fit off\n"; } } else if (cmd_ == "cfd") { @@ -579,10 +605,10 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vector\n"; + cout << msgHeader << "Invalid number of parameters to 'avg'\n"; + cout << msgHeader << " -SYNTAX- avg \n"; } } else if(cmd_ == "save") { @@ -617,30 +643,30 @@ bool scopeScanner::ExtraCommands(const std::string &cmd_, std::vector\n"; + cout << msgHeader << "Invalid number of parameters to 'save'\n"; + cout << msgHeader << " -SYNTAX- save \n"; } } else if(cmd_ == "delay"){ if(args_.size() == 1){ delay_ = atoi(args_.at(0).c_str()); } else{ - std::cout << msgHeader << "Invalid number of parameters to 'delay'\n"; - std::cout << msgHeader << " -SYNTAX- delay