updated to PixieSDK3.3. pixieDAQ can get ADC trace
This commit is contained in:
parent
0f15317886
commit
11875af9f9
4
Makefile
4
Makefile
|
@ -30,9 +30,11 @@ LIBS = $(APIBASE)libPixie16Api.so $(APIBASE)libPixieSDK.a $(PLXBASE)PlxApi.a
|
|||
all: test example pixieDAQ
|
||||
|
||||
example : example.o
|
||||
@echo "-------- making example"
|
||||
$(CC) $(INCFLAGS) example.o $(LIBS) -o example
|
||||
|
||||
example.o : example.cpp
|
||||
@echo "-------- making example.o"
|
||||
$(CC) $(CFLAGS) $(INCFLAGS) example.cpp
|
||||
|
||||
|
||||
|
@ -57,7 +59,7 @@ pixieDAQ : pixieDAQ.o Pixie16Class.o pixieDict.o
|
|||
|
||||
pixieDAQ.o : pixieDAQ.cpp pixieDAQ.h
|
||||
@echo "--------- creating pcm "
|
||||
@rootcling -f pixieDict.cxx -c pixieDAQ.h pixieDAQLinkDef.h
|
||||
@rootcling -f pixieDict.cxx -c pixieDAQ.h -p $(INCFLAGS) pixieDAQLinkDef.h
|
||||
@echo "--------- creating pixieDAQ.o"
|
||||
$(CC) $(CFLAGS) $(INCFLAGS) pixieDAQ.cpp Pixie16Class.cpp pixieDict.cxx $(ROOT_FLAG)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#This must start at 2 and proceed sequentially at the moment
|
||||
# slot modID fpgaID
|
||||
S 2 0 25
|
||||
S 3 1 25
|
||||
#S 3 1 25
|
||||
|
||||
##########################################################################################################
|
||||
## FPGA Files ID ##
|
||||
|
@ -19,11 +19,18 @@ S 3 1 25
|
|||
##########################################################################################################
|
||||
|
||||
#250MHz 16-bit
|
||||
F 25 0 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/syspixie16_revfgeneral_adc250mhz_r33339.bin
|
||||
F 25 1 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/fippixie16_revfgeneral_12b250m_r42081.bin
|
||||
F 25 2 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.ldr
|
||||
F 25 3 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.var
|
||||
F 25 4 /usr/opt/Pixie16/Pixie-16_FSU_Custom_Firmware_06022020/Configuration/Pixie16_FSU_Sample_Setup.set
|
||||
F 25 0 /usr/opt/Pixie16/pixie16_revf_general_16b250m_35921_2017-01-09/firmware/syspixie16_revfgeneral_adc250mhz_r33339.bin
|
||||
F 25 1 /usr/opt/Pixie16/pixie16_revf_general_16b250m_35921_2017-01-09/firmware/fippixie16_revfgeneral_16b250m_r36563.bin
|
||||
F 25 2 /usr/opt/Pixie16/pixie16_revf_general_16b250m_35921_2017-01-09/dsp/Pixie16DSP_revfgeneral_16b250m_r35921.ldr
|
||||
F 25 3 /usr/opt/Pixie16/pixie16_revf_general_16b250m_35921_2017-01-09/dsp/Pixie16DSP_revfgeneral_16b250m_r35921.var
|
||||
F 25 4 /home/ryan/Pixie16/ryan/test_ryan.set
|
||||
|
||||
#250MHz 12-bit
|
||||
F 12 0 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/syspixie16_revfgeneral_adc250mhz_r33339.bin
|
||||
F 12 1 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/fippixie16_revfgeneral_12b250m_r42081.bin
|
||||
F 12 2 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.ldr
|
||||
F 12 3 /usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.var
|
||||
F 12 4 /home/ryan/Pixie16/ryan/test_ryan.set
|
||||
|
||||
########################################################################################################################
|
||||
#120 space buffer limit
|
||||
|
|
|
@ -39,17 +39,14 @@ Pixie16::Pixie16(){
|
|||
isRunning = false;
|
||||
retval = 0;
|
||||
|
||||
if( LoadConfigFile() == 0 ) {
|
||||
retval = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
CheckDriver();
|
||||
if( retval > 0 ) CheckHardware();
|
||||
|
||||
if( retval > 0 ){
|
||||
LoadConfigFile("");
|
||||
|
||||
LoadConfigFile();
|
||||
|
||||
if( retval > 0 ) {
|
||||
BootDigitizers();
|
||||
|
||||
nFIFOWords = 0;
|
||||
|
@ -58,13 +55,14 @@ Pixie16::Pixie16(){
|
|||
|
||||
data = new DataBlock();
|
||||
nextWord = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pixie16::~Pixie16(){
|
||||
|
||||
retval = Pixie16ExitSystem(NumModules);
|
||||
CheckError("Pixie16ExitSystem");
|
||||
CloseDigitizers();
|
||||
|
||||
delete PXISlotMap;
|
||||
delete ch2ns;
|
||||
|
@ -82,7 +80,7 @@ Pixie16::~Pixie16(){
|
|||
}
|
||||
|
||||
|
||||
bool Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
||||
void Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
||||
|
||||
/************************************************************
|
||||
* this method is copy and modified from J.M. Allmond (ORNL)
|
||||
|
@ -110,7 +108,8 @@ bool Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
|||
|
||||
if ((fprconfig = fopen(fileName.c_str(), "r")) == NULL) {
|
||||
fprintf(stderr, "Error, cannot open input file %s\n", fileName.c_str());
|
||||
return false;
|
||||
retval = -1;
|
||||
return ;
|
||||
}
|
||||
|
||||
NumModules = 0;
|
||||
|
@ -149,7 +148,8 @@ bool Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
|||
break;
|
||||
}else {
|
||||
printf("Error in reading %s : bad id or format\n", fileName.c_str());
|
||||
return -1;
|
||||
retval = -2;
|
||||
return;
|
||||
}
|
||||
}else if(line[i]=='\n'){
|
||||
if(verbose) printf("\n");
|
||||
|
@ -171,10 +171,11 @@ bool Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
|||
DSPParFile = new char* [NumModules];
|
||||
DSPVarFile = new char* [NumModules];
|
||||
|
||||
|
||||
OfflineMode = 0;
|
||||
BootPattern = 0x7F;
|
||||
|
||||
ch2ns = new unsigned short [NumModules];
|
||||
|
||||
for ( int i = 0 ; i < NumModules ; i++){
|
||||
|
||||
PXISlotMap[i] = tempPXISlotMap[i];
|
||||
|
@ -202,7 +203,7 @@ bool Pixie16::LoadConfigFile(bool verbose, std::string fileName){
|
|||
printf(" DSP Par : %s \n", DSPParFile[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
int Pixie16::CheckError(std::string operation){
|
||||
|
@ -258,7 +259,8 @@ void Pixie16::GetDigitizerInfo(unsigned short modID){
|
|||
unsigned int ModSerNum;
|
||||
unsigned short ModADCBits;
|
||||
unsigned short ModADCMSPS;
|
||||
retval = Pixie16ReadModuleInfo(modID, &ModRev, &ModSerNum, &ModADCBits, &ModADCMSPS);
|
||||
unsigned short numChannels;
|
||||
retval = Pixie16ReadModuleInfo(modID, &ModRev, &ModSerNum, &ModADCBits, &ModADCMSPS, &numChannels);
|
||||
|
||||
if( CheckError("Pixie16ReadModuleInfo") < 0 ) return ;
|
||||
|
||||
|
@ -267,6 +269,7 @@ void Pixie16::GetDigitizerInfo(unsigned short modID){
|
|||
printf(" Serial Num : %d \n", ModSerNum);
|
||||
printf(" ADC Bits : %d \n", ModADCBits);
|
||||
printf("ADC sampling rate : %d \n", ModADCMSPS);
|
||||
printf(" # channels : %d \n", numChannels);
|
||||
|
||||
ch2ns[modID] = 1000/ModADCMSPS;
|
||||
|
||||
|
@ -307,6 +310,10 @@ void Pixie16::BootDigitizers(){
|
|||
|
||||
}
|
||||
|
||||
void Pixie16::CloseDigitizers(){
|
||||
retval = Pixie16ExitSystem(NumModules);
|
||||
CheckError("Pixie16ExitSystem");
|
||||
}
|
||||
|
||||
void Pixie16::AdjustOffset(){
|
||||
|
||||
|
@ -608,9 +615,9 @@ void Pixie16::PrintChannelAllSettings(unsigned short modID, unsigned short ch){
|
|||
|
||||
void Pixie16::PrintChannelsMainSettings(unsigned short modID){
|
||||
|
||||
printf("====+=====+======+========+========+===========+==========+==========+==========+========+========+=========+======+====== \n");
|
||||
printf("====+=====+======+========+========+===========+==========+==========+==========+========+========+=========+=======+====== \n");
|
||||
printf(" ch | En | Gain | Trig_L | Trig_G | Threshold | Polarity | Energy_L | Energy_G | Tau | Trace | Trace_d | Voff | BL \n");
|
||||
printf("----+-----+------+--------+--------+-----------+----------+----------+----------+--------+--------+---------+------+------ \n");
|
||||
printf("----+-----+------+--------+--------+-----------+----------+----------+----------+--------+--------+---------+-------+------ \n");
|
||||
for( int ch = 0; ch < 16; ch ++){
|
||||
printf(" %2d |", ch);
|
||||
printf(" %3s |", GetChannelOnOff(modID, ch) ? "On" : "Off" );
|
||||
|
@ -629,7 +636,7 @@ void Pixie16::PrintChannelsMainSettings(unsigned short modID){
|
|||
printf(" %7s |", "Off");
|
||||
printf(" %7s |", "Off");
|
||||
}
|
||||
printf(" %4.2f |", GetChannelVOffset(modID, ch));
|
||||
printf(" %5.2f |", GetChannelVOffset(modID, ch));
|
||||
printf(" %4.2f %% \n", GetChannelBaseLinePrecent(modID, ch));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,13 +88,14 @@ public:
|
|||
bool IsRunning() {return isRunning;}
|
||||
|
||||
///======================== startup
|
||||
bool LoadConfigFile( bool verbose = false, std::string fileName = "Pixie16.config");
|
||||
void LoadConfigFile( bool verbose = false, std::string fileName = "Pixie16.config");
|
||||
|
||||
void CheckDriver();
|
||||
void CheckHardware();
|
||||
|
||||
void GetDigitizerInfo(unsigned short modID);
|
||||
void BootDigitizers();
|
||||
void CloseDigitizers();
|
||||
|
||||
unsigned short GetCh2ns(unsigned short modID) {return ch2ns[modID];}
|
||||
|
||||
|
|
737
example.cpp
737
example.cpp
File diff suppressed because it is too large
Load Diff
917
example_3.2.cpp
Normal file
917
example_3.2.cpp
Normal file
|
@ -0,0 +1,917 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
/*
|
||||
* Copyright 2021 XIA LLC, All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file example_pixie16api.cpp
|
||||
* @brief Demonstrates how to use the Pixie16Api functions to communicate with Pixie-16 modules.
|
||||
*
|
||||
* We demonstrate both the PixieSDK implementation using `Pixie16Api.so` and the Legacy C
|
||||
* implementation using `Pixie16App.so`. The only difference between using one library over the
|
||||
* other is in the header definitions.
|
||||
*
|
||||
* The `Pixie16Api.so` includes all the goodness that comes with using the C++ implementation
|
||||
* just with a convenient C wrapper. Users don't have as much control over the nitty-gritty details
|
||||
* of the PixieSDK. We've intentionally limited this to prevent this backward compatible API from
|
||||
* growing out of hand. We **really** recommend that you link your code directly with `PixieSDK.a`.
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <args/args.hxx>
|
||||
#include <nolhmann/json.hpp>
|
||||
#include <pixie16/pixie16.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
struct LOG {
|
||||
explicit LOG(const std::string& type) {
|
||||
type_ = type;
|
||||
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
|
||||
std::chrono::milliseconds now2 =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
|
||||
char timeBuffer[80];
|
||||
std::strftime(timeBuffer, 80, "%FT%T", gmtime(¤tTime));
|
||||
|
||||
std::stringstream tmp;
|
||||
tmp << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << "Z";
|
||||
|
||||
datetime_ = tmp.str();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const LOG& log) {
|
||||
os << log.datetime_ << " - " << log.type_ << " - ";
|
||||
return os;
|
||||
}
|
||||
|
||||
std::string type_;
|
||||
std::string datetime_;
|
||||
};
|
||||
|
||||
struct module_config {
|
||||
unsigned short slot;
|
||||
unsigned short number;
|
||||
std::string com_fpga_config;
|
||||
std::string sp_fpga_config;
|
||||
std::string dsp_code;
|
||||
std::string dsp_par;
|
||||
std::string dsp_var;
|
||||
};
|
||||
|
||||
typedef std::vector<module_config> module_configs;
|
||||
|
||||
struct configuration {
|
||||
module_configs modules;
|
||||
std::vector<unsigned short> slot_def;
|
||||
unsigned short num_modules() const {
|
||||
return static_cast<unsigned short>(modules.size());
|
||||
}
|
||||
};
|
||||
|
||||
std::string generate_filename(const unsigned int& module_number, const std::string& type,
|
||||
const std::string& ext) {
|
||||
#ifndef LEGACY_EXAMPLE
|
||||
static const std::string file_prefix = "pixie16api-module";
|
||||
#else
|
||||
static const std::string file_prefix = "pixie16app-module";
|
||||
#endif
|
||||
return file_prefix + std::to_string(module_number) + "-" + type + "." + ext;
|
||||
}
|
||||
|
||||
void verify_json_module(const nlohmann::json& mod) {
|
||||
if (!mod.contains("slot")) {
|
||||
throw std::invalid_argument("Missing slot definition in configuration element.");
|
||||
}
|
||||
|
||||
if (!mod.contains("dsp")) {
|
||||
throw std::invalid_argument("Missing dsp object in configuration element.");
|
||||
}
|
||||
|
||||
if (!mod["dsp"].contains("ldr") || !mod["dsp"].contains("var") || !mod["dsp"].contains("par")) {
|
||||
throw std::invalid_argument(
|
||||
"Missing dsp object in configuration element: ldr, dsp, or par.");
|
||||
}
|
||||
|
||||
if (!mod.contains("fpga")) {
|
||||
throw std::invalid_argument("Missing fpga object in configuration element.");
|
||||
}
|
||||
|
||||
if (!mod["fpga"].contains("fippi") || !mod["fpga"].contains("sys")) {
|
||||
throw std::invalid_argument("Missing fpga firmware definition (fippi or sys).");
|
||||
}
|
||||
}
|
||||
|
||||
void read_config(const std::string& config_file_name, configuration& cfg) {
|
||||
std::ifstream input(config_file_name, std::ios::in);
|
||||
if (input.fail()) {
|
||||
throw std::ios_base::failure("open: " + config_file_name + ": " + std::strerror(errno));
|
||||
}
|
||||
|
||||
nlohmann::json jf = nlohmann::json::parse(input);
|
||||
input.close();
|
||||
|
||||
if (jf.empty() || jf.size() > SYS_MAX_NUM_MODULES) {
|
||||
throw std::invalid_argument("invalid number of modules");
|
||||
}
|
||||
|
||||
cfg.slot_def.clear();
|
||||
for (const auto& module : jf) {
|
||||
verify_json_module(module);
|
||||
|
||||
cfg.slot_def.push_back(module["slot"]);
|
||||
|
||||
module_config mod_cfg;
|
||||
mod_cfg.slot = module["slot"];
|
||||
mod_cfg.number = static_cast<unsigned short>(cfg.slot_def.size() - 1);
|
||||
mod_cfg.com_fpga_config = module["fpga"]["sys"];
|
||||
mod_cfg.sp_fpga_config = module["fpga"]["fippi"];
|
||||
mod_cfg.dsp_code = module["dsp"]["ldr"];
|
||||
mod_cfg.dsp_par = module["dsp"]["par"];
|
||||
mod_cfg.dsp_var = module["dsp"]["var"];
|
||||
cfg.modules.push_back(mod_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
bool verify_api_return_value(const int& val, const std::string& func_name,
|
||||
const bool& print_success = true) {
|
||||
if (val < 0) {
|
||||
std::cout << LOG("ERROR") << func_name << " failed with Error Code " << val << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (print_success)
|
||||
std::cout << LOG("INFO") << func_name << " finished successfully." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool output_statistics_data(const unsigned short& mod_num, const std::string& type) {
|
||||
#ifndef LEGACY_EXAMPLE
|
||||
std::vector<unsigned int> stats(Pixie16GetStatisticsSize(), 0);
|
||||
#else
|
||||
std::vector<unsigned int> stats(N_DSP_PAR - DSP_IO_BORDER, 0);
|
||||
#endif
|
||||
if (!verify_api_return_value(Pixie16ReadStatisticsFromModule(stats.data(), mod_num),
|
||||
"Pixie16ReadStatisticsFromModule", false))
|
||||
return false;
|
||||
|
||||
std::ofstream bin_output(generate_filename(mod_num, type, "bin"),
|
||||
std::ios::binary | std::ios::out);
|
||||
bin_output.write(reinterpret_cast<char*>(stats.data()), sizeof(unsigned int) * stats.size());
|
||||
bin_output.close();
|
||||
|
||||
std::ofstream csv_output(generate_filename(mod_num, type, "csv"), std::ios::out);
|
||||
csv_output << "channel,real_time,live_time,input_count_rate,output_count_rate" << std::endl;
|
||||
|
||||
auto real_time = Pixie16ComputeRealTime(stats.data(), mod_num);
|
||||
|
||||
std::cout << LOG("INFO") << "Begin Statistics for Module " << mod_num << std::endl;
|
||||
std::cout << LOG("INFO") << "Real Time: " << real_time << std::endl;
|
||||
for (unsigned int chan = 0; chan < NUMBER_OF_CHANNELS; chan++) {
|
||||
auto live_time = Pixie16ComputeLiveTime(stats.data(), mod_num, chan);
|
||||
auto icr = Pixie16ComputeInputCountRate(stats.data(), mod_num, chan);
|
||||
auto ocr = Pixie16ComputeOutputCountRate(stats.data(), mod_num, chan);
|
||||
|
||||
std::cout << LOG("INFO") << "Channel " << chan << " LiveTime: " << live_time << std::endl;
|
||||
std::cout << LOG("INFO") << "Channel " << chan << " Input Count Rate: " << icr << std::endl;
|
||||
std::cout << LOG("INFO") << "Channel " << chan << " Output Count Rate: " << ocr
|
||||
<< std::endl;
|
||||
|
||||
csv_output << chan << "," << real_time << "," << live_time << "," << icr << "," << ocr
|
||||
<< std::endl;
|
||||
}
|
||||
std::cout << LOG("INFO") << "End Statistics for Module " << mod_num << std::endl;
|
||||
csv_output.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool save_dsp_pars(const std::string& filename) {
|
||||
std::cout << LOG("INFO") << "Saving DSP Parameters to " << filename << "." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16SaveDSPParametersToFile(filename.c_str()),
|
||||
"Pixie16SaveDSPParametersToFile"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_adjust_offsets(const module_config& module) {
|
||||
std::cout << LOG("INFO") << "Adjusting baseline offset for Module " << module.number << "."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16AdjustOffsets(module.number),
|
||||
"Pixie16AdjustOffsets for Module " +
|
||||
std::to_string(module.number)))
|
||||
return false;
|
||||
if (!save_dsp_pars(module.dsp_par))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_baseline_capture(const unsigned short& module_number) {
|
||||
std::cout << LOG("INFO") << "Starting baseline capture for Module " << module_number
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16AcquireBaselines(module_number), "Pixie16AcquireBaselines"))
|
||||
return false;
|
||||
|
||||
double baselines[NUMBER_OF_CHANNELS][MAX_NUM_BASELINES];
|
||||
double timestamps[MAX_NUM_BASELINES];
|
||||
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||
std::cout << LOG("INFO") << "Acquiring baselines for Channel " << i << std::endl;
|
||||
if (!verify_api_return_value(Pixie16ReadSglChanBaselines(baselines[i], timestamps,
|
||||
MAX_NUM_BASELINES, module_number,
|
||||
i),
|
||||
"Pixie16ReadsglChanBaselines"))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream ofstream1(generate_filename(module_number, "baselines", "csv"));
|
||||
ofstream1 << "bin,timestamp,";
|
||||
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||
if (i != NUMBER_OF_CHANNELS - 1)
|
||||
ofstream1 << "Chan" << i << ",";
|
||||
else
|
||||
ofstream1 << "Chan" << i;
|
||||
}
|
||||
ofstream1 << std::endl;
|
||||
|
||||
for (unsigned int i = 0; i < MAX_NUM_BASELINES; i++) {
|
||||
ofstream1 << i << "," << timestamps[i] << ",";
|
||||
for (unsigned int k = 0; k < NUMBER_OF_CHANNELS; k++) {
|
||||
if (k != NUMBER_OF_CHANNELS - 1)
|
||||
ofstream1 << baselines[k][i] << ",";
|
||||
else
|
||||
ofstream1 << baselines[k][i];
|
||||
}
|
||||
ofstream1 << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_list_mode_run(const configuration& cfg, const double& runtime_in_seconds) {
|
||||
std::cout << LOG("INFO") << "Starting list mode data run for " << runtime_in_seconds << " s."
|
||||
<< std::endl;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to read SYNCH_WAIT in Module 0."
|
||||
<< std::endl;
|
||||
unsigned int parData;
|
||||
if (!verify_api_return_value(Pixie16ReadSglModPar("SYNCH_WAIT", &parData, 0),
|
||||
"Pixie16ReadSglModPar - SYNC_WAIT"))
|
||||
return false;
|
||||
std::cout << LOG("INFO") << "SYNCH_WAIT in Module 0. = " << parData
|
||||
<< std::endl;
|
||||
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16ReadSglModPar to read IN_SYNCH in Module 0."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16ReadSglModPar("IN_SYNCH", &parData, 0),
|
||||
"Pixie16ReadSglModPar - IN_SYNC"))
|
||||
return false;
|
||||
std::cout << LOG("INFO") << "IN_SYNCH in Module 0. = " << parData
|
||||
<< std::endl;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write SYNCH_WAIT = 1 in Module 0."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16WriteSglModPar("SYNCH_WAIT", 1, 0),
|
||||
"Pixie16WriteSglModPar - SYNC_WAIT"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write IN_SYNCH = 0 in Module 0."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16WriteSglModPar("IN_SYNCH", 0, 0),
|
||||
"Pixie16WriteSglModPar - IN_SYNC"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16StartListModeRun." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16StartListModeRun(cfg.num_modules(), LIST_MODE_RUN, NEW_RUN),
|
||||
"Pixie16StartListModeRun"))
|
||||
return false;
|
||||
|
||||
std::vector<std::ofstream*> output_streams(cfg.num_modules());
|
||||
for (unsigned short i = 0; i < cfg.num_modules(); i++) {
|
||||
output_streams[i] = new std::ofstream(generate_filename(i, "list-mode", "evt"),
|
||||
std::ios::out | std::ios::binary);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> data(EXTERNAL_FIFO_LENGTH, 0);
|
||||
unsigned int num_fifo_words = 0;
|
||||
|
||||
std::cout << LOG("INFO") << "Collecting data for " << runtime_in_seconds << " s." << std::endl;
|
||||
std::chrono::steady_clock::time_point run_start_time = std::chrono::steady_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
std::chrono::steady_clock::now() - run_start_time)
|
||||
.count() < runtime_in_seconds) {
|
||||
// for (unsigned short mod_num = 0; mod_num < cfg.num_modules(); mod_num++) {
|
||||
for (unsigned short mod_num = 0; mod_num < 1; mod_num++) {
|
||||
if (Pixie16CheckRunStatus(mod_num) == 1) {
|
||||
if (!verify_api_return_value(
|
||||
Pixie16CheckExternalFIFOStatus(&num_fifo_words, mod_num),
|
||||
"Pixie16CheckExternalFIFOStatus", false))
|
||||
return false;
|
||||
|
||||
if (double(num_fifo_words) / EXTERNAL_FIFO_LENGTH > 0.2) {
|
||||
std::cout << LOG("INFO") << "External FIFO has " << num_fifo_words << " words."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16ReadDataFromExternalFIFO(data.data(), num_fifo_words, mod_num),
|
||||
"Pixie16ReadDataFromExternalFIFO", false))
|
||||
return false;
|
||||
output_streams[mod_num]->write(reinterpret_cast<char*>(data.data()),
|
||||
num_fifo_words * sizeof(uint32_t));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
std::cout << LOG("INFO") << "Module " << mod_num << " has no active run!"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Check the run status of the Director module (module #0) to see if the run has been stopped.
|
||||
This is possible in a multi-chassis system where modules in one chassis can stop the run
|
||||
in all chassis.
|
||||
*/
|
||||
if (Pixie16CheckRunStatus(0) == 0) {
|
||||
std::cout << LOG("INFO")
|
||||
<< "Run was stopped by the director module. Stopping data collection."
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Stop run in the Director module (module #0) - a SYNC interrupt should be generated
|
||||
to stop run in all modules simultaneously
|
||||
*/
|
||||
std::cout << LOG("INFO") << "Stopping List Mode Run." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16EndRun(0), "Pixie16EndRun"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Checking that the run is finalized in all the modules."
|
||||
<< std::endl;
|
||||
bool all_modules_finished = false;
|
||||
const unsigned int max_finalize_attempts = 50;
|
||||
for (unsigned int counter = 0; counter < max_finalize_attempts; counter++) {
|
||||
for (unsigned short k = 0; k < cfg.num_modules(); k++) {
|
||||
if (Pixie16CheckRunStatus(k) == 1) {
|
||||
all_modules_finished = false;
|
||||
} else {
|
||||
all_modules_finished = true;
|
||||
}
|
||||
}
|
||||
if (all_modules_finished) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
if (!all_modules_finished) {
|
||||
std::cout << LOG("ERROR") << "All modules did not stop their runs properly!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << LOG("INFO") << "List-mode run finished in "
|
||||
<< std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
std::chrono::steady_clock::now() - run_start_time)
|
||||
.count()
|
||||
<< " s" << std::endl;
|
||||
|
||||
std::cout << LOG("INFO")
|
||||
<< "Reading the final words from the External FIFO and the run statistics."
|
||||
<< std::endl;
|
||||
for (unsigned short mod_num = 0; mod_num < cfg.num_modules(); mod_num++) {
|
||||
if (!verify_api_return_value(Pixie16CheckExternalFIFOStatus(&num_fifo_words, mod_num),
|
||||
"Pixie16CheckExternalFIFOStatus", false))
|
||||
return false;
|
||||
|
||||
if (num_fifo_words > 0) {
|
||||
std::cout << LOG("INFO") << "External FIFO has " << num_fifo_words << " words."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16ReadDataFromExternalFIFO(data.data(), num_fifo_words, mod_num),
|
||||
"Pixie16ReadDataFromExternalFIFO", false))
|
||||
return false;
|
||||
output_streams[mod_num]->write(reinterpret_cast<char*>(data.data()),
|
||||
num_fifo_words * sizeof(uint32_t));
|
||||
}
|
||||
if (!output_statistics_data(mod_num, "list-mode-stats")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_mca_run(const unsigned int& mod, const double& runtime_in_seconds) {
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write HOST_RT_PRESET to "
|
||||
<< runtime_in_seconds << std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16WriteSglModPar("HOST_RT_PRESET", Decimal2IEEEFloating(runtime_in_seconds), mod),
|
||||
"Pixie16WriteSglModPar - HOST_RT_PRESET"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write SYNCH_WAIT = 1 in Module 0."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16WriteSglModPar("SYNCH_WAIT", 1, mod),
|
||||
"Pixie16WriteSglModPar - SYNC_WAIT"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write IN_SYNCH = 0 in Module 0."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16WriteSglModPar("IN_SYNCH", 0, mod),
|
||||
"Pixie16WriteSglModPar - IN_SYNC"))
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Starting MCA data run for " << runtime_in_seconds << " s."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16StartHistogramRun(mod, NEW_RUN),
|
||||
"Pixie16StartHistogramRun"))
|
||||
return false;
|
||||
|
||||
std::chrono::steady_clock::time_point run_start_time = std::chrono::steady_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
std::chrono::steady_clock::now() - run_start_time)
|
||||
.count() < runtime_in_seconds) {
|
||||
//do nothing
|
||||
}
|
||||
std::cout << LOG("INFO") << "Stopping MCA data run after "
|
||||
<< std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
std::chrono::steady_clock::now() - run_start_time)
|
||||
.count()
|
||||
<< " s." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16EndRun(mod), "Pixie16EndRun"))
|
||||
return false;
|
||||
|
||||
std::string name = generate_filename(mod, "mca", "csv");
|
||||
std::ofstream out(name);
|
||||
out << "bin,";
|
||||
|
||||
std::vector<std::vector<uint32_t>> hists;
|
||||
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||
std::vector<uint32_t> hist(MAX_HISTOGRAM_LENGTH, 0);
|
||||
Pixie16ReadHistogramFromModule(hist.data(), MAX_HISTOGRAM_LENGTH, mod, i);
|
||||
hists.push_back(hist);
|
||||
if (i < NUMBER_OF_CHANNELS - 1)
|
||||
out << "Chan" << i << ",";
|
||||
else
|
||||
out << "Chan" << i;
|
||||
}
|
||||
out << std::endl;
|
||||
|
||||
for (unsigned int bin = 0; bin < MAX_HISTOGRAM_LENGTH; bin++) {
|
||||
out << bin << ",";
|
||||
for (auto& hist : hists) {
|
||||
if (&hist != &hists.back())
|
||||
out << hist[bin] << ",";
|
||||
else
|
||||
out << hist[bin];
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
if (!output_statistics_data(mod, "mca-stats")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_parameter_read(args::ValueFlag<std::string>& parameter,
|
||||
args::ValueFlag<unsigned int>& crate,
|
||||
args::ValueFlag<unsigned int>& module,
|
||||
args::ValueFlag<unsigned int>& channel) {
|
||||
if (channel) {
|
||||
double result;
|
||||
std::cout << LOG("INFO") << "Pixie16ReadSglChanPar"
|
||||
<< " reading " << parameter.Get() << " from Crate " << crate.Get() << " Module "
|
||||
<< module.Get() << " Channel " << channel.Get() << "." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16ReadSglChanPar(parameter.Get().c_str(), &result,
|
||||
module.Get(), channel.Get()),
|
||||
"Pixie16ReadSglChanPar", false))
|
||||
return false;
|
||||
std::cout << LOG("INFO") << result << std::endl;
|
||||
} else {
|
||||
unsigned int result;
|
||||
std::cout << LOG("INFO") << "Pixie16ReadSglModPar reading " << parameter.Get()
|
||||
<< " from Crate " << crate.Get() << " Module " << module.Get() << "."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16ReadSglModPar(parameter.Get().c_str(), &result, module.Get()),
|
||||
"Pixie16ReadSglModPar", false))
|
||||
return false;
|
||||
std::cout << LOG("INFO") << result << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_parameter_write(args::ValueFlag<std::string>& parameter,
|
||||
args::ValueFlag<double>& value, args::ValueFlag<unsigned int>& crate,
|
||||
const module_config& module, args::ValueFlag<unsigned int>& channel) {
|
||||
if (channel) {
|
||||
std::cout << LOG("INFO") << "Pixie16WriteSglChanPar setting " << parameter.Get() << " to "
|
||||
<< value.Get() << " for Crate " << crate.Get() << " Module " << module.number
|
||||
<< " Channel " << channel.Get() << "." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16WriteSglChanPar(parameter.Get().c_str(), value.Get(),
|
||||
module.number, channel.Get()),
|
||||
"Pixie16WriteSglChanPar"))
|
||||
return false;
|
||||
} else {
|
||||
std::cout << LOG("INFO") << "Pixie16WriteSglModPar"
|
||||
<< " setting " << parameter.Get() << " to " << value.Get() << " for Crate "
|
||||
<< crate.Get() << " Module " << module.number << "." << std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16WriteSglModPar(parameter.Get().c_str(), value, module.number),
|
||||
"Pixie16WriteSglModPar"))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!save_dsp_pars(module.dsp_par))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_trace_capture(const unsigned short& module_number) {
|
||||
std::cout << LOG("INFO") << "Pixie16AcquireADCTrace acquiring traces for Module "
|
||||
<< module_number << "." << std::endl;
|
||||
if (!verify_api_return_value(Pixie16AcquireADCTrace(module_number), "Pixie16AcquireADCTrace"))
|
||||
return false;
|
||||
|
||||
|
||||
unsigned short trace[NUMBER_OF_CHANNELS][MAX_ADC_TRACE_LEN];
|
||||
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||
if (!verify_api_return_value(
|
||||
Pixie16ReadSglChanADCTrace(trace[i], MAX_ADC_TRACE_LEN, module_number, i),
|
||||
"Pixie16AcquireADCTrace", false))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream ofstream1(generate_filename(module_number, "adc", "csv"));
|
||||
ofstream1 << "bin,";
|
||||
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||
if (i != NUMBER_OF_CHANNELS - 1)
|
||||
ofstream1 << "Chan" << i << ",";
|
||||
else
|
||||
ofstream1 << "Chan" << i;
|
||||
}
|
||||
ofstream1 << std::endl;
|
||||
for (unsigned int i = 0; i < MAX_ADC_TRACE_LEN; i++) {
|
||||
ofstream1 << i << ",";
|
||||
for (unsigned int k = 0; k < NUMBER_OF_CHANNELS; k++) {
|
||||
if (k != NUMBER_OF_CHANNELS - 1)
|
||||
ofstream1 << trace[k][i] << ",";
|
||||
else
|
||||
ofstream1 << trace[k][i];
|
||||
}
|
||||
ofstream1 << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_blcut(args::ValueFlag<unsigned int>& module, args::ValueFlag<unsigned int>& channel) {
|
||||
if (!module)
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Executing Pixie16BLcutFinder for Module" << module.Get() << "."
|
||||
<< std::endl;
|
||||
unsigned int blcut = 0;
|
||||
if (!verify_api_return_value(Pixie16BLcutFinder(module.Get(), channel.Get(), &blcut),
|
||||
"Pixie16BLcutFinder", false))
|
||||
return false;
|
||||
std::cout << LOG("INFO") << "BLCut for Module " << module.Get() << " Channel " << channel.Get()
|
||||
<< " is " << blcut << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_set_dacs(args::ValueFlag<unsigned int>& module) {
|
||||
if (!module)
|
||||
return false;
|
||||
|
||||
std::cout << LOG("INFO") << "Executing Pixie16SetDACs for Module" << module.Get() << "."
|
||||
<< std::endl;
|
||||
if (!verify_api_return_value(Pixie16SetDACs(module.Get()), "Pixie16SetDACs", false))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool execute_close_module_connection(const int& numModules) {
|
||||
std::cout << LOG("INFO") << "Closing out connection to Modules." << std::endl;
|
||||
verify_api_return_value(Pixie16ExitSystem(numModules),"Pixie16ExitSystem");
|
||||
return true;
|
||||
}
|
||||
|
||||
double calculate_duration_in_seconds(const std::chrono::system_clock::time_point& start,
|
||||
const std::chrono::system_clock::time_point& end) {
|
||||
return std::chrono::duration<double>(end - start).count();
|
||||
}
|
||||
|
||||
void output_module_info(const configuration& cfg) {
|
||||
unsigned short rev;
|
||||
unsigned int serial_number;
|
||||
unsigned short adc_bits;
|
||||
unsigned short adc_msps;
|
||||
for (const auto& mod : cfg.modules) {
|
||||
if (!verify_api_return_value(
|
||||
Pixie16ReadModuleInfo(mod.number, &rev, &serial_number, &adc_bits, &adc_msps),
|
||||
"Pixie16ReadModuleInfo", false))
|
||||
throw std::runtime_error("Could not get module information for Module " +
|
||||
std::to_string(mod.number));
|
||||
std::cout << LOG("INFO") << "Begin module information for Module " << mod.number
|
||||
<< std::endl;
|
||||
std::cout << LOG("INFO") << "Serial Number: " << serial_number << std::endl;
|
||||
std::cout << LOG("INFO") << "Revision: " << rev << std::endl;
|
||||
std::cout << LOG("INFO") << "ADC Bits: " << adc_bits << std::endl;
|
||||
std::cout << LOG("INFO") << "ADC MSPS: " << adc_msps << std::endl;
|
||||
std::cout << LOG("INFO") << "End module information for Module " << mod.number << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
auto start = std::chrono::system_clock::now();
|
||||
args::ArgumentParser parser(
|
||||
"Sample code that interfaces with a Pixie system through the User API.");
|
||||
parser.LongSeparator("=");
|
||||
|
||||
args::Group commands(parser, "commands");
|
||||
args::Command boot(commands, "boot", "Boots the crate of modules.");
|
||||
args::Command copy(commands, "copy", "Copies DSP parameters from source to destination.");
|
||||
args::Command export_settings(
|
||||
commands, "export-settings",
|
||||
"Boots the system and dumps the settings to the file defined in the config.");
|
||||
args::Command histogram(commands, "histogram", "Save histograms from the module.");
|
||||
args::Command init(commands, "init", "Initializes the system without going any farther.");
|
||||
args::Command list_mode(commands, "list-mode", "Starts a list mode data run");
|
||||
args::Command read(commands, "read", "Read a parameter from the module.");
|
||||
args::Command write(commands, "write", "Write a parameter to the module.");
|
||||
args::Command trace(commands, "trace", "Captures traces from the modules.");
|
||||
args::Command adjust_offsets(commands, "adjust_offsets",
|
||||
"Adjusts the DC offsets for all modules in the config file.");
|
||||
args::Command baseline(commands, "baseline", "Acquire and print baselines from the module");
|
||||
args::Command mca(commands, "mca", "Starts an MCA data run.");
|
||||
args::Command blcut(commands, "blcut",
|
||||
"Starts a control task to find the BLCut for a channel.");
|
||||
args::Command dacs(commands, "dacs", "Starts a control task to set the module's DACs");
|
||||
args::Command tau_finder(commands, "tau_finder",
|
||||
"Executes the Tau Finder control task and returns the values.");
|
||||
|
||||
args::Group arguments(parser, "arguments", args::Group::Validators::AtLeastOne,
|
||||
args::Options::Global);
|
||||
args::ValueFlag<std::string> conf_flag(arguments, "cfg", "The configuration file to load.",
|
||||
{'c', "config"}, args::Options::Required);
|
||||
args::ValueFlag<std::string> additional_cfg_flag(
|
||||
arguments, "cfg", "The configuration file to load.", {"additional-config"});
|
||||
args::HelpFlag help_flag(arguments, "help", "Displays this message", {'h', "help"});
|
||||
args::Flag is_fast_boot(boot, "fast-boot", "Performs a partial boot of the system.",
|
||||
{'f', "fast-boot"});
|
||||
args::Flag is_offline(arguments, "Offline Mode",
|
||||
"Tells the API to use Offline mode when running.", {'o', "offline"});
|
||||
args::ValueFlag<std::string> boot_pattern_flag(arguments, "boot_pattern",
|
||||
"The boot pattern used for booting.",
|
||||
{'b', "boot_pattern"}, "0x7F");
|
||||
args::ValueFlag<double> run_time(
|
||||
list_mode, "time", "The amount of time that a list mode run will take in seconds.",
|
||||
{'t', "run-time"}, 10.);
|
||||
args::ValueFlag<std::string> parameter(
|
||||
arguments, "parameter", "The parameter we want to read from the system.", {'n', "name"});
|
||||
args::ValueFlag<unsigned int> channel(arguments, "channel", "The channel to operate on.",
|
||||
{"chan"});
|
||||
args::ValueFlag<unsigned int> crate(arguments, "crate", "The crate", {"crate"}, 0);
|
||||
args::ValueFlag<unsigned int> copy_mask(
|
||||
copy, "copy_mask", "An integer representing the set of parameters to copy", {"copy-mask"});
|
||||
args::ValueFlag<unsigned int> dest_mask(
|
||||
copy, "dest_mask", "An integer representing the destination channels", {"dest-mask"});
|
||||
args::ValueFlag<unsigned int> dest_channel(copy, "dest_channel",
|
||||
"The channel that we'll copy to", {"dest-chan"});
|
||||
args::ValueFlag<unsigned int> dest_module(copy, "dest_module", "The module that we'll copy to.",
|
||||
{"dest-mod"});
|
||||
args::ValueFlag<unsigned int> module(arguments, "module", "The module to operate on.", {"mod"});
|
||||
args::ValueFlag<double> parameter_value(
|
||||
write, "parameter_value", "The value of the parameter we want to write.", {'v', "value"});
|
||||
|
||||
adjust_offsets.Add(conf_flag);
|
||||
adjust_offsets.Add(boot_pattern_flag);
|
||||
adjust_offsets.Add(module);
|
||||
baseline.Add(is_fast_boot);
|
||||
baseline.Add(boot_pattern_flag);
|
||||
baseline.Add(module);
|
||||
blcut.Add(module);
|
||||
blcut.Add(channel);
|
||||
boot.Add(conf_flag);
|
||||
boot.Add(boot_pattern_flag);
|
||||
copy.Add(boot_pattern_flag);
|
||||
copy.Add(module);
|
||||
copy.Add(channel);
|
||||
dacs.Add(module);
|
||||
mca.Add(module);
|
||||
mca.Add(boot_pattern_flag);
|
||||
read.Add(conf_flag);
|
||||
read.Add(crate);
|
||||
read.Add(module);
|
||||
read.Add(channel);
|
||||
read.Add(parameter);
|
||||
tau_finder.Add(module);
|
||||
trace.Add(conf_flag);
|
||||
trace.Add(module);
|
||||
trace.Add(boot_pattern_flag);
|
||||
write.Add(conf_flag);
|
||||
write.Add(parameter);
|
||||
write.Add(crate);
|
||||
write.Add(module);
|
||||
write.Add(channel);
|
||||
|
||||
try {
|
||||
parser.ParseCLI(argc, argv);
|
||||
} catch (args::Help& help) {
|
||||
std::cout << LOG("INFO") << help.what() << std::endl;
|
||||
std::cout << parser;
|
||||
return EXIT_SUCCESS;
|
||||
} catch (args::Error& e) {
|
||||
std::cout << LOG("ERROR") << e.what() << std::endl;
|
||||
std::cout << parser;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
configuration cfg;
|
||||
try {
|
||||
read_config(conf_flag.Get(), cfg);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << LOG("ERROR") << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout << LOG("INFO") << "Finished reading config in "
|
||||
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
|
||||
<< std::endl;
|
||||
|
||||
int offline_mode = 0;
|
||||
if (is_offline)
|
||||
offline_mode = 1;
|
||||
|
||||
start = std::chrono::system_clock::now();
|
||||
std::cout << LOG("INFO") << "Calling Pixie16InitSystem." << std::endl;
|
||||
if (!verify_api_return_value(
|
||||
Pixie16InitSystem(cfg.num_modules(), cfg.slot_def.data(), offline_mode),
|
||||
"Pixie16InitSystem", false))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
std::cout << LOG("INFO") << "Finished Pixie16InitSystem in "
|
||||
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
|
||||
<< std::endl;
|
||||
|
||||
try {
|
||||
output_module_info(cfg);
|
||||
} catch (std::runtime_error& error) {
|
||||
std::cout << LOG("ERROR") << error.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (init) {
|
||||
execute_close_module_connection(cfg.num_modules());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
unsigned int boot_pattern = stoul(args::get(boot_pattern_flag), nullptr, 0);
|
||||
if (is_fast_boot || additional_cfg_flag)
|
||||
boot_pattern = 0x70;
|
||||
|
||||
for (const auto& mod : cfg.modules) {
|
||||
start = std::chrono::system_clock::now();
|
||||
std::cout << LOG("INFO") << "Calling Pixie16BootModule for Module " << mod.number
|
||||
<< " with boot pattern: " << std::showbase << std::hex << boot_pattern << std::dec
|
||||
<< std::endl;
|
||||
|
||||
if (!verify_api_return_value(
|
||||
Pixie16BootModule(mod.com_fpga_config.c_str(), mod.sp_fpga_config.c_str(), nullptr,
|
||||
mod.dsp_code.c_str(), mod.dsp_par.c_str(), mod.dsp_var.c_str(),
|
||||
mod.number, boot_pattern),
|
||||
"Pixie16BootModule", "Finished booting!"))
|
||||
return EXIT_FAILURE;
|
||||
std::cout << LOG("INFO") << "Finished Pixie16BootModule for Module " << mod.number << " in "
|
||||
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (boot) {
|
||||
execute_close_module_connection(cfg.num_modules());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (additional_cfg_flag) {
|
||||
if (!verify_api_return_value(
|
||||
Pixie16LoadDSPParametersFromFile(additional_cfg_flag.Get().c_str()),
|
||||
"Pixie16LoadDSPParametersFromFile", true))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (copy) {
|
||||
if (!module || !channel || !copy_mask || !dest_channel || !dest_module) {
|
||||
std::cout
|
||||
<< LOG("ERROR")
|
||||
<< "Pixie16CopyDSPParameters requires the source/destination module and channel "
|
||||
"and the destination mask to execute!"
|
||||
<< std::endl;
|
||||
}
|
||||
std::vector<unsigned short> dest_mask;
|
||||
for(size_t mod = 0; mod < cfg.num_modules(); mod++) {
|
||||
for(size_t chan = 0; chan < NUMBER_OF_CHANNELS; chan++) {
|
||||
if (mod == dest_module.Get() && chan == dest_channel.Get())
|
||||
dest_mask.push_back(1);
|
||||
else
|
||||
dest_mask.push_back(0);
|
||||
}
|
||||
}
|
||||
if (!verify_api_return_value(
|
||||
Pixie16CopyDSPParameters(copy_mask.Get(), module.Get(), channel.Get(), dest_mask.data()),
|
||||
"Pixie16CopyDSPParameters", true)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (tau_finder) {
|
||||
if (!module) {
|
||||
std::cout << LOG("ERROR") << "Pixie16TauFinder requires the module flag to execute!"
|
||||
<< std::endl;
|
||||
}
|
||||
std::vector<double> taus(NUMBER_OF_CHANNELS);
|
||||
if (!verify_api_return_value(Pixie16TauFinder(module.Get(), taus.data()),
|
||||
"Pixie16TauFinder", true)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (unsigned int i = 0; i < taus.size(); i++) {
|
||||
std::cout << "Channel " << i << ": " << taus.at(i) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (read) {
|
||||
if (!execute_parameter_read(parameter, crate, module, channel))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (write) {
|
||||
if (!execute_parameter_write(parameter, parameter_value, crate, cfg.modules[module.Get()],
|
||||
channel))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (adjust_offsets) {
|
||||
if (!execute_adjust_offsets(cfg.modules[module.Get()]))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (trace) {
|
||||
if (!execute_trace_capture(module.Get()))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (list_mode) {
|
||||
if (!execute_list_mode_run(cfg, run_time.Get()))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (export_settings) {
|
||||
if (!save_dsp_pars(cfg.modules.front().dsp_par))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (baseline) {
|
||||
if (!execute_baseline_capture(module.Get()))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (mca) {
|
||||
if (!execute_mca_run(module.Get(), run_time.Get()))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (blcut) {
|
||||
if (!execute_blcut(module, channel))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (dacs) {
|
||||
if (!execute_set_dacs(module))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
execute_close_module_connection(cfg.num_modules());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
59
pixieDAQ.cpp
59
pixieDAQ.cpp
|
@ -5,21 +5,30 @@
|
|||
#include <TRandom.h>
|
||||
#include <TGButton.h>
|
||||
#include <TRootEmbeddedCanvas.h>
|
||||
#include <TGraph.h>
|
||||
#include <TAxis.h>
|
||||
#include "pixieDAQ.h"
|
||||
|
||||
#include "Pixie16Class.h"
|
||||
|
||||
Pixie16 * pixie;
|
||||
|
||||
MainWindow::MainWindow(const TGWindow *p,UInt_t w,UInt_t h) {
|
||||
|
||||
openPixie();
|
||||
|
||||
/// Create a main frame
|
||||
fMain = new TGMainFrame(p,w,h);
|
||||
///fMain->SetWMPosition(500, 500); //does not work
|
||||
|
||||
/// Create canvas widget
|
||||
fEcanvas = new TRootEmbeddedCanvas("Ecanvas",fMain,800,400);
|
||||
fMain->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,1));
|
||||
/// Create a horizontal frame widget with buttons
|
||||
TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain,200,40);
|
||||
|
||||
TGTextButton *draw = new TGTextButton(hframe,"&Draw");
|
||||
draw->Connect("Clicked()","MainWindow",this,"DoDraw()");
|
||||
draw->Connect("Clicked()","MainWindow",this,"getADCTrace()");
|
||||
hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
|
||||
TGTextButton *exit = new TGTextButton(hframe,"&Exit");
|
||||
exit->Connect("Clicked()", "MainWindow", this, "GoodBye()");
|
||||
|
@ -28,7 +37,7 @@ MainWindow::MainWindow(const TGWindow *p,UInt_t w,UInt_t h) {
|
|||
fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2));
|
||||
|
||||
/// Set a name to the main frame
|
||||
fMain->SetWindowName("Simple Example");
|
||||
fMain->SetWindowName("Pixie16 DAQ");
|
||||
|
||||
/// Map all subwindows of main frame
|
||||
fMain->MapSubwindows();
|
||||
|
@ -56,11 +65,41 @@ MainWindow::~MainWindow() {
|
|||
delete fMain;
|
||||
}
|
||||
|
||||
void MainWindow::DoDraw() {
|
||||
void MainWindow::openPixie(){
|
||||
|
||||
printf("Removing Pixie16Msg.log \n");
|
||||
remove( "Pixie16Msg.log");
|
||||
|
||||
pixie = new Pixie16();
|
||||
if ( pixie->GetStatus() < 0 ) {
|
||||
printf("Exiting program... \n");
|
||||
GoodBye();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::getADCTrace() {
|
||||
/// Draws function graphics in randomly chosen interval
|
||||
TF1 *f1 = new TF1("f1","sin(x)/x",0,gRandom->Rndm()*10);
|
||||
f1->SetLineWidth(3);
|
||||
f1->Draw();
|
||||
///TF1 *f1 = new TF1("f1","sin(x)/x",0,gRandom->Rndm()*10);
|
||||
///f1->SetLineWidth(3);
|
||||
///f1->Draw();
|
||||
|
||||
printf("--------- get ADCTrace \n");
|
||||
|
||||
int ch = 6;
|
||||
pixie->CaptureADCTrace(0, ch);
|
||||
|
||||
unsigned short * haha = pixie->GetADCTrace();
|
||||
double dt = pixie->GetChannelSetting("XDT", 0, ch);
|
||||
|
||||
TGraph * gTrace = new TGraph();
|
||||
|
||||
for( int i = 0 ; i < pixie->GetADCTraceLength(); i++){
|
||||
gTrace->SetPoint(i, i*dt, haha[i]);
|
||||
}
|
||||
gTrace->GetXaxis()->SetTitle("time [us]");
|
||||
gTrace->Draw("AP");
|
||||
|
||||
TCanvas *fCanvas = fEcanvas->GetCanvas();
|
||||
fCanvas->cd();
|
||||
fCanvas->Update();
|
||||
|
@ -69,15 +108,21 @@ void MainWindow::DoDraw() {
|
|||
|
||||
|
||||
void MainWindow::GoodBye(){
|
||||
|
||||
pixie->CloseDigitizers();
|
||||
|
||||
printf("----- bye bye ---- \n");
|
||||
|
||||
gApplication->Terminate(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
printf(" Welcome to pixie16 DQ \n");
|
||||
|
||||
TApplication theApp("App",&argc,argv);
|
||||
new MainWindow(gClient->GetRoot(),200,200);
|
||||
new MainWindow(gClient->GetRoot(),800,600);
|
||||
theApp.Run();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class TGWindow;
|
||||
class TGMainFrame;
|
||||
class TRootEmbeddedCanvas;
|
||||
class Pixie16;
|
||||
//class Pixie16;
|
||||
|
||||
class MainWindow {
|
||||
RQ_OBJECT("MainWindow")
|
||||
|
@ -12,12 +12,15 @@ private:
|
|||
TGMainFrame *fMain;
|
||||
TRootEmbeddedCanvas *fEcanvas;
|
||||
|
||||
Pixie16 * pixie;
|
||||
|
||||
public:
|
||||
MainWindow(const TGWindow *p, UInt_t w, UInt_t h);
|
||||
virtual ~MainWindow();
|
||||
|
||||
void openPixie();
|
||||
|
||||
void getADCTrace();
|
||||
|
||||
void GoodBye();
|
||||
|
||||
void DoDraw();
|
||||
};
|
||||
|
|
29
test.cpp
29
test.cpp
|
@ -79,7 +79,9 @@ int main(int argc, char *argv[]){
|
|||
TH1F * hch = new TH1F("hch", "channel", 16, 0, 16);
|
||||
TH1F * hE = new TH1F("hE", "energy", 400, 0, 30000);
|
||||
TGraph * gTrace = new TGraph();
|
||||
gTrace->GetXaxis()->SetTitle("time [ch = 4 ns]");
|
||||
|
||||
int ch2ns = pixie->GetCh2ns(0);
|
||||
gTrace->GetXaxis()->SetTitle("time [ns]");
|
||||
|
||||
|
||||
//pixie->SetDigitizerPresetRunTime(100000, 0);
|
||||
|
@ -111,33 +113,34 @@ int main(int argc, char *argv[]){
|
|||
|
||||
|
||||
//pixie->SetChannelEnergyRiseTime(2, 0, ch);
|
||||
pixie->SetChannelTriggerThreshold(300, 0, ch);
|
||||
//pixie->SetChannelTriggerThreshold(300, 0, ch);
|
||||
//pixie->SetChannelEnergyTau(50, 0, ch);
|
||||
//pixie->SetChannelOnOff(true, 0, ch);
|
||||
//pixie->SetChannelPositivePolarity(true, 0, ch);
|
||||
//pixie->SetChannelTraceOnOff(true, 0, ch);
|
||||
pixie->SetChannelBaseLinePrecent(90, 0, ch);
|
||||
//pixie->SetChannelVOffset(0.0, 0, ch);
|
||||
//pixie->SetChannelBaseLinePrecent(10, 0, ch);
|
||||
//pixie->SetChannelVOffset(-0.5, 0, ch);
|
||||
//pixie->SetChannelTraceLenght(10, 0, ch);
|
||||
//pixie->SetChannelTraceDelay(2, 0, ch);
|
||||
pixie->SetChannelGain(1, 0, ch);
|
||||
pixie->SaveSettings("test_ryan.set");
|
||||
//pixie->SetChannelGain(1, 0, ch);
|
||||
//pixie->SaveSettings("test_ryan.set");
|
||||
|
||||
|
||||
pixie->PrintChannelAllSettings(0, ch);
|
||||
|
||||
pixie->PrintChannelsMainSettings(0);
|
||||
|
||||
/*
|
||||
|
||||
pixie->CaptureADCTrace(0, ch);
|
||||
unsigned short * haha = pixie->GetADCTrace();
|
||||
double dt = GetChannelSetting("XDT", 0, ch);
|
||||
double dt = pixie->GetChannelSetting("XDT", 0, ch);
|
||||
for( int i = 0 ; i < pixie->GetADCTraceLength(); i++){
|
||||
gTrace->SetPoint(i, i*dt, haha[i]);
|
||||
}
|
||||
gTrace->GetXaxis()->SetTitle("time [us]");
|
||||
canvas->cd(3); gTrace->Draw("APL");
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//pixie->CaptureBaseLine(0, ch);
|
||||
//double * baseline = pixie->GetBasline();
|
||||
|
@ -146,10 +149,10 @@ int main(int argc, char *argv[]){
|
|||
// gTrace->SetPoint(i, baselineTime[i]*1000, baseline[i]);
|
||||
// //printf("%5d | %f, %f \n", i, baselineTime[i]*1000, baseline[i]);
|
||||
//}
|
||||
//canvas->cd(3); gTrace->Draw("APL");
|
||||
|
||||
//canvas->cd(2); gTrace->Draw("APL");
|
||||
|
||||
|
||||
/*
|
||||
printf("start run for %f sec\n", time);
|
||||
|
||||
uint32_t StartTime = get_time(), CurrentTime = get_time();
|
||||
|
@ -175,9 +178,9 @@ int main(int argc, char *argv[]){
|
|||
if( data->eventID %10 == 0 ){
|
||||
if( data->trace_length > 0 ) {
|
||||
for( int i = 0 ; i < data->trace_length; i++){
|
||||
gTrace->SetPoint(i, i, data->trace[i]);
|
||||
gTrace->SetPoint(i, i*ch2ns, data->trace[i]);
|
||||
}
|
||||
gTrace->GetYaxis()->SetRangeUser(0, 5000);
|
||||
//gTrace->GetYaxis()->SetRangeUser(0, 5000);
|
||||
canvas->cd(3); gTrace->Draw("APL");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
10,
|
||||
10,
|
||||
10,
|
||||
90,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
|
@ -423,7 +423,7 @@
|
|||
32768,
|
||||
32768,
|
||||
32768,
|
||||
32768,
|
||||
21845,
|
||||
32768,
|
||||
32768,
|
||||
32768,
|
||||
|
@ -970,7 +970,7 @@
|
|||
"dsp": {
|
||||
"adc_bits": 16,
|
||||
"adc_msps": 250,
|
||||
"file": "Pixie16DSP_revfgeneral_12b250m_r41847.ldr",
|
||||
"file": "Pixie16DSP_revfgeneral_16b250m_r35921.ldr",
|
||||
"rev": 15,
|
||||
"tag": "15-250-16",
|
||||
"version": "n/a"
|
||||
|
@ -984,7 +984,7 @@
|
|||
"fippi": {
|
||||
"adc_bits": 16,
|
||||
"adc_msps": 250,
|
||||
"file": "fippixie16_revfgeneral_12b250m_r42081.bin",
|
||||
"file": "fippixie16_revfgeneral_16b250m_r36563.bin",
|
||||
"rev": 15,
|
||||
"tag": "15-250-16",
|
||||
"version": "n/a"
|
||||
|
@ -1005,7 +1005,7 @@
|
|||
"var": {
|
||||
"adc_bits": 16,
|
||||
"adc_msps": 250,
|
||||
"file": "Pixie16DSP_revfgeneral_12b250m_r41847.var",
|
||||
"file": "Pixie16DSP_revfgeneral_16b250m_r35921.var",
|
||||
"rev": 15,
|
||||
"tag": "15-250-16",
|
||||
"version": "n/a"
|
||||
|
@ -1016,7 +1016,7 @@
|
|||
"ChanNum": 0,
|
||||
"CoincPattern": 0,
|
||||
"CoincWait": 0,
|
||||
"ControlTask": 6,
|
||||
"ControlTask": 0,
|
||||
"CrateID": 0,
|
||||
"FIFOLength": 8188,
|
||||
"FastFilterRange": 0,
|
||||
|
|
Loading…
Reference in New Issue
Block a user