commit 9a302c631b330454773558bd8714408f0af1cf6f Author: Ryan@Debain10 Date: Wed Mar 2 18:28:38 2022 -0500 use libPixie16Api.so, can change setting, try to understand the collected data diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2108662 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.o +*.log +*.bin +*.csv +*.gch + +test +example diff --git a/DataBlock.h b/DataBlock.h new file mode 100644 index 0000000..0d7645e --- /dev/null +++ b/DataBlock.h @@ -0,0 +1,95 @@ + +#ifndef DATABLOCK_H +#define DATABLOCK_H + +#include +#include +#include +#include +#include + +class DataBlock{ + +public: + unsigned short ch; + unsigned short slot; + unsigned short crate; + unsigned short headerLength; /// headerLength > 4, more data except tarce. + unsigned short eventLength; /// eventLength = headerLength + trace + bool pileup; + unsigned long long time; + unsigned short cfd; + unsigned short energy; + unsigned short trace_length; + bool trace_out_of_range; + + int trailing; + int leading; + int gap; + int baseline; + int QDCsum[8]; + + unsigned long long eventID; + unsigned short trace[1024]; + + DataBlock(){ + Clear(); + }; + + ~DataBlock(){}; + + void Clear(){ + ch = 0; + slot = 0; + crate = 0; + headerLength = 0; + eventLength = 0; + pileup = false; + time = 0; + cfd = 0; + energy = 0; + trace_length = 0; + trace_out_of_range = 0; + + eventID = 0; + ClearQDC(); + ClearTrace(); + } + + void ClearQDC(){ + trailing = 0; + leading = 0; + gap = 0; + baseline = 0; + for( int i = 0; i < 8; i++) QDCsum[i] = -1; + } + + void ClearTrace(){ + for( int i = 0; i < 1024; i++) trace[i] = 0; + } + + + void Print(bool printTrace = false){ + printf("============== eventID : %llu\n", eventID); + printf("Crate: %d, Slot: %d, Ch: %d \n", crate, slot, ch); + printf("HeaderLength: %d, Event Length: %d, energy: %d, timeStamp: %llu\n", headerLength, eventLength, energy, time); + printf("trace_length: %d, pile-up:%d\n", trace_length, pileup); + if( headerLength > 4 ){ + if( headerLength > 12 ){ + printf(" trailing : %d\n", trailing); + printf(" leading : %d\n", leading); + printf(" gap : %d\n", gap); + printf(" baseLine : %d\n", baseline); + } + printf(" QDCsum : \n"); + for( int i = 0; i < 8; i++) printf(" %-10d\n", QDCsum[i]); + } + if( printTrace && eventLength > headerLength ){ + printf(" trace:\n"); + for( int i = 0 ; i < trace_length ; i++)printf("%3d| %-10d\n",i, trace[i]); + } + } + +}; + +#endif diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6f189ca --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +PLXBASE = /usr/opt/PlxSdk/PlxApi/Library/ +CC = g++ +CFLAGS = -c -Wall +LDFLAGS = -ldl -lm +ROOT_FLAG = `root-config --cflags --glibs` + +#==== old pixie library +#APIBASE = /usr/opt/Pixie16/lib/ +#INCFLAGS = -I$(APIBASE)app/ -I$(APIBASE)sys/ +#INCFLAGS2 = -I$(APIBASE)inc/ +#LIBS = $(APIBASE)libPixie16App.a $(APIBASE)libPixie16Sys.a $(PLXBASE)PlxApi.a +# +#all: test +# +#test : test.o Pixie16Class.o +# $(CC) test.o Pixie16Class.o $(LIBS) -o test +# +#test.o : test.cpp +# $(CC) $(CFLAGS) $(INCFLAGS) $(INCFLAGS2) test.cpp $(ROOT_FLAG) +# +#Pixie16Class.o : Pixie16Class.h Pixie16Class.cpp DataBlock.h +# $(CC) $(CFLAGS) $(INCFLAGS) $(INCFLAGS2) Pixie16Class.cpp DataBlock.h $(ROOT_FLAG) +# + +#==== new pixie library +INCFLAGS = -I/usr/opt/xia/PixieSDK/ -I/usr/opt/xia/PixieSDK/include/ -I/usr/opt/xia/PixieSDK/include/pixie16/ +APIBASE = /usr/opt/xia/PixieSDK/lib/ +LIBS = $(APIBASE)libPixie16Api.so $(APIBASE)libPixieSDK.a $(PLXBASE)PlxApi.a + +all: test example + +example : example.o Pixie16Class.o + $(CC) $(INCFLAGS) example.o Pixie16Class.o $(LIBS) -o example + +example.o : example.cpp + $(CC) $(CFLAGS) $(INCFLAGS) example.cpp + +test : test.o Pixie16Class.o + $(CC) $(INCFLAGS) test.o Pixie16Class.o $(LIBS) -o test + +test.o : test.cpp + $(CC) $(CFLAGS) $(INCFLAGS) test.cpp $(ROOT_FLAG) + +Pixie16Class.o : Pixie16Class.h Pixie16Class.cpp DataBlock.h + $(CC) $(CFLAGS) $(INCFLAGS) Pixie16Class.cpp DataBlock.h $(ROOT_FLAG) + +#need to export LD_LIBRARY_PATH +#the pixie.ini is not needed + +clean: + rm -f *.o test + + diff --git a/Pixie16Class.cpp b/Pixie16Class.cpp new file mode 100644 index 0000000..71a4ce2 --- /dev/null +++ b/Pixie16Class.cpp @@ -0,0 +1,605 @@ +#ifndef PIXIE16_CPP +#define PIXIE16_CPP + +#include "pixie16/pixie16.h" +//#include "pixie16app_export.h" +//#include "pixie16sys_export.h" +//#include "def21160.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Pixie16Class.h" + +std::string exec(const char* cmd) { + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(cmd, "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + return result; +} + +Pixie16::Pixie16(){ + + isRunning = false; + retval = 0; + + CheckDriver(); + if( retval > 0 ) CheckHardware(); + + if( retval > 0 ){ + LoadConfigFile(""); + + BootDigitizers(); + + nFIFOWords = 0; + ExtFIFO_Data = NULL; + Statistics = NULL; + + data = new DataBlock(); + } +} + +Pixie16::~Pixie16(){ + + retval = Pixie16ExitSystem(NumModules); + CheckError("Pixie16ExitSystem"); + + delete PXISlotMap; + + delete ComFPGAConfigFile; + delete SPFPGAConfigFile; + delete TrigFPGAConfigFile; + delete DSPCodeFile; + delete DSPParFile; + delete DSPVarFile; + + delete ExtFIFO_Data; + delete Statistics; + delete data; + +} + + +bool Pixie16::LoadConfigFile(std::string fileName){ + + printf("\033[32m======= Loading Configuration file : \033[m\n"); + + NumModules = 1; + OfflineMode = 0; + PXISlotMap = new unsigned short[NumModules]; + + ComFPGAConfigFile = new char* [NumModules]; + SPFPGAConfigFile = new char* [NumModules]; + TrigFPGAConfigFile = new char* [NumModules]; + DSPCodeFile = new char* [NumModules]; + DSPParFile = new char* [NumModules]; + DSPVarFile = new char* [NumModules]; + + PXISlotMap[0] = 2; + + ComFPGAConfigFile [0] = (char *)"/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/syspixie16_revfgeneral_adc250mhz_r33339.bin"; + SPFPGAConfigFile [0] = (char *)"/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/fippixie16_revfgeneral_12b250m_r42081.bin"; + TrigFPGAConfigFile [0] = (char *)"FPGATrig"; ///only Revision A + DSPCodeFile [0] = (char *)"/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.ldr"; + DSPVarFile [0] = (char *)"/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.var"; + + //DSPParFile [0] = (char *)"/usr/opt/Pixie16/Pixie-16_FSU_Custom_Firmware_06022020/Configuration/Pixie16_FSU_Sample_Setup.set"; + DSPParFile [0] = (char *)"/home/ryan/Pixie16/ryan/test_ryan.set"; + //DSPParFile [0] = (char *)"/home/ryan/Pixie16/ryan/Pixie16_FSU_Sample_Setup.set"; + + BootPattern = 0x7F; + + printf("Number of Module : %d \n", NumModules); + printf("Slot Map : "); for( int i = 0; i < NumModules ; i++) printf("%d\t", PXISlotMap[i]); + printf("\n"); + for( int i = 0; i < NumModules; i++){ + printf("--- configuration files for module-%d\n", i); + printf(" ComFPGA : %s \n", ComFPGAConfigFile[i]); + printf(" SPFPGA : %s \n", SPFPGAConfigFile[i]); + printf(" DSP Code : %s \n", DSPCodeFile[i]); + printf(" DSP Var : %s \n", DSPVarFile[i]); + printf(" DSP Par : %s \n", DSPParFile[i]); + } + + return true; +} + +int Pixie16::CheckError(std::string operation){ + + if( retval < 0 ){ + printf("\033[1;31m*ERROR* \033[1;33m%s\033[m failed, retval = %d\n", operation.c_str(), retval); + return -1; + } + + return 1; +} + + +void Pixie16::CheckDriver(){ + printf("\033[32m======= check PLX PCI 9054 ...\033[m\n"); + //check driver is loaded + std::string ans = exec("lsmod | grep 9054 | wc -l"); + if( ans == "0\n" ){ + printf("cannot find PLX PCI 9054 driver.\n"); + retval = -1; + return; + } + printf("Found PLX PCI 9054 driver.\n"); + retval = 1; +} + + +void Pixie16::CheckHardware(){ + //check pci is there + std::string ans = exec("lspci | grep 9054 | wc -l"); + if( ans == "0\n" ){ + printf("cannot find PLX PCI 9054.\n"); + retval = -2; + return; + } + printf("Found PLX PCI 9054 card.\n"); + + //check pci is OK + ans = exec("lspci -vv| grep \"Unknown header type\" | wc -l"); + if( atoi(ans.c_str()) > 0 ){ + printf("found PLX PCI 9054, but not working. Unknown header Type.\n"); + retval = -3; + return; + } + printf("PLX PCI 9054 card does not detected problem.\n"); + retval = 1; +} + + +void Pixie16::GetDigitizerInfo(unsigned short modID){ + + unsigned short ModRev; + unsigned int ModSerNum; + unsigned short ModADCBits; + unsigned short ModADCMSPS; + retval = Pixie16ReadModuleInfo(modID, &ModRev, &ModSerNum, &ModADCBits, &ModADCMSPS); + + if( CheckError("Pixie16ReadModuleInfo") < 0 ) return ; + + printf("------------ Module-%d \n", modID); + printf(" Revision : %d \n", ModRev); + printf(" Serial Num : %d \n", ModSerNum); + printf(" ADC Bits : %d \n", ModADCBits); + printf("ADC sampling rate : %d \n", ModADCMSPS); + +} + + +void Pixie16::BootDigitizers(){ + + // Boot Modules + printf("\033[32m======= Booting Pixie16 System ...\033[0m\n"); + + retval = Pixie16InitSystem (NumModules, PXISlotMap, OfflineMode); + + printf("\033[32mInit Ok\033[0m\n"); + + + // Boot Module + printf("\033[32mBooting module ...\033[0m\n"); + for( int i = 0 ; i < NumModules; i++){ + + GetDigitizerInfo(i); + + retval = Pixie16BootModule ( + ComFPGAConfigFile[i], + SPFPGAConfigFile[i], + TrigFPGAConfigFile[i], + DSPCodeFile[i], + DSPParFile[i], + DSPVarFile[i], + i, + BootPattern + ); + + if( CheckError("Pixie16BootModule") < 0 ) return ; + printf("\033[32mBoot Ok\033[0m\n"); + + } + +} + +void Pixie16::StartRun(bool listMode){ + + unsigned short mode = NEW_RUN; //RESUME_RUN + + for( int i = 0 ; i < NumModules; i++){ + retval = Pixie16StartListModeRun(i, 0x100, mode); + if( CheckError("Pixie16StartListModeRun") < 0 ) return; + printf("\033[32mModule-%d run\033[0m\n", i); + + isRunning = true; + } + +} + + +void Pixie16::StopRun(){ + + retval = Pixie16EndRun( NumModules ); + if( CheckError("Pixie16EndRun") < 0 ) return; + printf("\033[32mRun Stopped\033[0m\n"); + + isRunning = false; + +} + + +void Pixie16::ReadData(unsigned short modID){ + + retval = Pixie16CheckExternalFIFOStatus (&nFIFOWords, modID); + + printf("number of word in module-%d FIFO : %d \n", modID, nFIFOWords); + + if(nFIFOWords > 0) { + if( ExtFIFO_Data != NULL ) delete ExtFIFO_Data; + ExtFIFO_Data = new unsigned int [nFIFOWords]; + retval = Pixie16ReadDataFromExternalFIFO(ExtFIFO_Data, nFIFOWords, modID); + if( CheckError("Pixie16ReadDataFromExternalFIFO") < 0 ) return; + } + +} + +void Pixie16::PrintData(){ + + printf("----------------------------\n"); + printf("number of words read : %d \n", nFIFOWords); + + unsigned int word = 0; + + for( unsigned int i = 0; i < nFIFOWords; i++) printf("%5d|%X|\n", i, ExtFIFO_Data[word]); + + while( word < nFIFOWords ){ + data->ch = ExtFIFO_Data[word] & 0xF ; + data->slot = (ExtFIFO_Data[word] >> 4) & 0xF; + data->crate = (ExtFIFO_Data[word] >> 8) & 0xF; + data->headerLength = (ExtFIFO_Data[word] >> 12) & 0x1F; + data->eventLength = (ExtFIFO_Data[word] >> 17) & 0x3FFF; + data->pileup = ExtFIFO_Data[word] >> 31 ; + data->time = ((unsigned long long)(ExtFIFO_Data[word+2] & 0xFFFF) << 32) + ExtFIFO_Data[word+1]; + data->cfd = ExtFIFO_Data[word + 2] >> 16 ; + data->energy = (ExtFIFO_Data[word + 3] & 0xFFFF ); + data->trace_length = (ExtFIFO_Data[word + 3] >> 16) & 0x7FFF; + data->trace_out_of_range = ExtFIFO_Data[word + 3] >> 31; + + data->Print(0); + data->eventID ++; + + word += data->eventLength + 1; + } + +} + +void Pixie16::GetTrace(unsigned short modID, unsigned short ch){ + + unsigned short ADCTrace[8192]; + retval = Pixie16AcquireADCTrace (modID); + if( CheckError("Pixie16AcquireADCTrace") < 0 ) return; + + retval = Pixie16ReadSglChanADCTrace (ADCTrace, 8192, modID, ch); + if( CheckError("Pixie16ReadSglChanADCTrace") < 0 ) return; + + for( int i = 0; i < 8192 ; i++){ + printf("%4d, %d \n", i, ADCTrace[i]); + } +} + + +void Pixie16::GetBaseLines(unsigned short modID, unsigned short ch){ + + retval = Pixie16AcquireBaselines(modID); + if( CheckError("Pixie16AcquireBaselines") < 0 ) return; + + + double Baselines[3640], TimeStamps[3640]; + + retval = Pixie16ReadSglChanBaselines(Baselines, TimeStamps, 3640, modID, ch); + if( CheckError("Pixie16ReadSglChanBaselines") < 0 ) return; + + for( int i = 0; i < 3640; i++){ + printf("%4d, %.4f, %.4f \n", i, Baselines[i], TimeStamps[i]); + } + +} + +void Pixie16::GetDigitizerSettings(unsigned short modID){ + + printf("=========== Digitizer setting for module-%d\n", modID); + + unsigned int ParData; + retval = Pixie16ReadSglModPar ((char *)"MODULE_NUMBER", &ParData, modID); printf(" module number: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"CrateID", &ParData, modID); printf(" Crate modID: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"SlotID", &ParData, modID); printf(" Slot modID: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"ModID", &ParData, modID); printf(" Mod modID: %d \n", ParData); + ///retval = Pixie16ReadSglModPar ((char *)"MODULE_CSRA", &ParData, modID); printf("channel control registor A: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"MODULE_CSRB", &ParData, modID); printf("channel control registor B: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"MODULE_FORMAT", &ParData, modID); printf(" format: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"MAX_EVENTS", &ParData, modID); printf(" max events: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"SYNCH_WAIT", &ParData, modID); printf(" syn ch wait: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"IN_SYNCH", &ParData, modID); printf(" in syn ch: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"SLOW_FILTER_RANGE", &ParData, modID); printf(" slow filter range: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"FAST_FILTER_RANGE", &ParData, modID); printf(" fast filter range: %d \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"FastTrigBackplaneEna", &ParData, modID); printf("fast trig Backplane enable: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"TrigConfig0", &ParData, modID); printf(" Trig config 0: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"TrigConfig1", &ParData, modID); printf(" Trig config 1: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"TrigConfig2", &ParData, modID); printf(" Trig config 2: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"TrigConfig3", &ParData, modID); printf(" Trig config 3: %X \n", ParData); + retval = Pixie16ReadSglModPar ((char *)"HOST_RT_PRESET", &ParData, modID); printf(" Host run time preset: %d \n", ParData); + + if( CheckError("GetDigitizerSettings") < 0 ) return; +} + + +double Pixie16::GetChannelSetting(std::string parName, unsigned short modID, unsigned short ch, bool verbose){ + + double ParData; + retval = Pixie16ReadSglChanPar( const_cast (parName.c_str()), &ParData, modID, ch); + if( CheckError("Pixie16ReadSglChanPar::"+parName) < 0 ) return -404; + + if( verbose ) { + if( parName == "TRIGGER_THRESHOLD" ) { + printf("READ | Mod : %2d, CH: %2d, %18s = %5d ADC\n", modID, ch, parName.c_str(), (int) ParData); + }else if( parName == "BASELINE_PERCENT" ) { + printf("READ | Mod : %2d, CH: %2d, %18s = %9.3f %%\n", modID, ch, parName.c_str(), ParData); + }else if( parName == "BLCUT" ) { + printf("READ | Mod : %2d, CH: %2d, %18s = %5d \n", modID, ch, parName.c_str(), (int) ParData); + }else if ( parName == "CHANNEL_CSRA" || parName == "CHANNEL_CSRB" || parName == "MultiplicityMaskL" || parName == "MultiplicityMaskH"){ + printf("READ | Mod : %2d, CH: %2d, %18s = %X\n", modID, ch, parName.c_str(), (int) ParData); + printf( " 32 28 24 20 16 12 8 4 0\n"); + printf( " | | | | | | | | |\n"); + std::cout <<" Module Configuration : 0xb" << std::bitset<32>(ParData) << std::endl; + + if( parName == "CHANNEL_CSRA" ){ + int CSRA = (int) ParData; + printf("---------------------------------------------------------------------------\n"); + printf(" fast trigger selection (bit: 0) : %s \n", CSRA & CSRA_BIT::FAST_TRIGGER ? "external" : "internal"); + printf(" module validation signal selection (bit: 1) : %s \n", CSRA & CSRA_BIT::M_VALIDATION ? "module gate" : "global gate"); + printf(" channel enable (bit: 2) : %s \n", CSRA & CSRA_BIT::ENABLE_CHANNEL ? "\033[1;33mYes\033[m" : "\033[1;31mNo\033[m"); + printf(" channal validation signal selection (bit: 3) : %s \n", CSRA & CSRA_BIT::C_VALIFATION ? "module gate" : "global gate"); + printf("Block data acquisition if trace or header DPMs are full (bit: 4) : %s \n", CSRA & CSRA_BIT::BLOCK_DAQ_DPM_FULL ? "Yes" : "No"); + printf(" signal polarity (bit: 5) : %s \n", CSRA & CSRA_BIT::POLARITY ? "Positive" : "Negative"); + printf(" veto channel trigger (bit: 6) : %s \n", CSRA & CSRA_BIT::VETO_TRIGGER ? "enable" : "disable"); + printf(" Enable trace capture (bit: 8) : %s \n", CSRA & CSRA_BIT::ENABLE_TRACE ? "enable" : "disable"); + printf(" Enable QDC sum capture (bit: 9) : %s \n", CSRA & CSRA_BIT::ENABLE_QDC ? "enable" : "disable"); + printf(" Enable CFD trigger mode (bit: 10) : %s \n", CSRA & CSRA_BIT::ENABLE_CFD ? "enable" : "disable"); + printf(" required module validation trigger (bit: 11) : %s \n", CSRA & CSRA_BIT::REQ_M_VALIDATION ? "required" : "not required"); + printf(" Enable capture raw energy sums and baselines (bit: 12) : %s \n", CSRA & CSRA_BIT::CAPTURE_ESUMS_BASELINE ? "enable" : "disable"); + printf(" required cahnnel validation trigger (bit: 13) : %s \n", CSRA & CSRA_BIT::REQ_C_VALIDATION ? "required" : "not required"); + printf(" Enable input relay (bit: 14) : %s \n", CSRA & CSRA_BIT::INPUT_RELAY ? "enable" : "disable"); + printf(" Pile-up control (bit: 15-16) : "); + int pileUpVaule = (CSRA & CSRA_BIT::PILEUP); + if( pileUpVaule == 0 ) printf("no energy for pile-up\n"); + if( pileUpVaule == 1 ) printf("reject pile-up\n"); + if( pileUpVaule == 2 ) printf("no trace for non-pile-up\n"); + if( pileUpVaule == 3 ) printf("only pile-up\n"); + printf(" Enable no-trace-for-large-pulse (bit: 17) : %s \n", CSRA & CSRA_BIT::NO_TRACE_LARGE_PULSE ? "enable" : "disable"); + printf(" Group trigger selection (bit: 18) : %s \n", CSRA & CSRA_BIT::GROUP_TRIGGER ? "group trigger" : "local fast trigger"); + printf(" Channel veto selection (bit: 19) : %s \n", CSRA & CSRA_BIT::CH_VETO ? "channel validation trigger" : "front pannel channel veto"); + printf(" Module veto selection (bit: 20) : %s \n", CSRA & CSRA_BIT::MO_VETO ? "module validation trigger" : "front pannel module veto"); + printf(" external timestamp in event header (bit: 21) : %s \n", CSRA & CSRA_BIT::EXT_TIMESTAMP ? "enable" : "disable"); + printf("---------------------------------------------------------------------------\n"); + } + + }else{ + printf("READ | Mod : %2d, CH: %2d, %18s = %9.3f us\n", modID, ch, parName.c_str(), ParData); + } + } + + return ParData; +} + +unsigned short Pixie16::GetCSRA(int bitwise, unsigned short modID, unsigned short ch, bool verbose){ + double ParData; + retval = Pixie16ReadSglChanPar( (char *)"CHANNEL_CSRA", &ParData, modID, ch); + if( CheckError("Pixie16ReadSglChanPar::CHANNEL_CSRA") < 0 ) return false; + if( verbose ) printf("Mod-%d CH-%02d %X: %s\n", modID, ch, bitwise, (((int)ParData) & bitwise ) ? "Positive" : "Negative" ); + return (((int)ParData) & bitwise ); +} + +void Pixie16::PrintChannelAllSettings(unsigned short modID, unsigned short ch){ + + printf("===================== Channel setting. Mod-%d CH-%02d\n", modID, ch); + GetChannelSetting("TRIGGER_RISETIME", modID, ch, true); + GetChannelSetting("TRIGGER_FLATTOP", modID, ch, true); + GetChannelSetting("TRIGGER_THRESHOLD", modID, ch, true); + GetChannelSetting("ENERGY_RISETIME", modID, ch, true); + GetChannelSetting("ENERGY_FLATTOP", modID, ch, true); + GetChannelSetting("TAU", modID, ch, true); + GetChannelSetting("TRACE_LENGTH", modID, ch, true); + GetChannelSetting("TRACE_DELAY", modID, ch, true); + GetChannelSetting("VOFFSET", modID, ch, true); + GetChannelSetting("XDT", modID, ch, true); + GetChannelSetting("BASELINE_PERCENT", modID, ch, true); + GetChannelSetting("BASELINE_AVERAGE", modID, ch, true); + GetChannelSetting("BLCUT", modID, ch, true); + GetChannelSetting("EMIN", modID, ch, true); + GetChannelSetting("CHANNEL_CSRA", modID, ch, true); + ///GetChannelSetting("CHANNEL_CSRB", modID, ch, true); //CSRB is reserved to be zero + GetChannelSetting("QDCLen0", modID, ch, true); + GetChannelSetting("QDCLen1", modID, ch, true); + GetChannelSetting("QDCLen2", modID, ch, true); + GetChannelSetting("QDCLen3", modID, ch, true); + GetChannelSetting("QDCLen4", modID, ch, true); + GetChannelSetting("QDCLen5", modID, ch, true); + GetChannelSetting("QDCLen6", modID, ch, true); + GetChannelSetting("QDCLen7", modID, ch, true); + GetChannelSetting("MultiplicityMaskL", modID, ch, true); + GetChannelSetting("MultiplicityMaskH", modID, ch, true); + printf("=====================================\n"); + } + +void Pixie16::PrintChannelsMainSettings(unsigned short modID){ + + printf(" ch | En | Trig_L | Trig_G | Threshold | Energy_L | Energy_G | Tau | Trace | Trace_d | Voff | BL \n"); + printf("----+-----+--------+--------+-----------+----------+----------+-------+------ -+---------+------+------ \n"); + for( int ch = 0; ch < 16; ch ++){ + printf(" %2d |", ch); + printf(" %3s |", GetChannleOnOff(modID, ch) ? "On" : "Off" ); + printf(" %6.2f |", GetChannelTriggerRiseTime(modID, ch)); + printf(" %6.2f |", GetChannelTriggerFlatTop(modID, ch)); + printf(" %9.2f |", GetChannelTriggerThreshold(modID, ch)); + printf(" %8.2f |", GetChannelEnergyRiseTime(modID, ch)); + printf(" %8.2f |", GetChannelEnergyFlatTop(modID, ch)); + printf(" %5.2f |", GetChannelEnergyTau(modID, ch)); + if( GetChannelTraceOnOff(modID, ch) ){ + printf(" %7.2f |", GetChannelTraceLength(modID, ch)); + printf(" %7.2f |", GetChannelTraceDelay(modID, ch)); + }else{ + printf(" %7s |", "Off"); + printf(" %7s |", "Off"); + } + printf(" %4.2f |", GetChannelVOffset(modID, ch)); + printf(" %4.2f \n", GetChannelBaseLinePrecent(modID, ch)); + } +} + + +void Pixie16::WriteChannelSetting(std::string parName, double val, unsigned short modID, unsigned short ch, bool verbose ){ + + retval = Pixie16WriteSglChanPar( const_cast (parName.c_str()), val, modID, ch); + if( CheckError("Pixie16WriteSglChanPar::"+parName) < 0 ) return; + if( verbose ) GetChannelSetting(parName, modID, ch, verbose); + +} + +void Pixie16::SwitchCSRA(int bitwise, unsigned short modID, unsigned short ch){ + + double ParData; + retval = Pixie16ReadSglChanPar( (char *)"CHANNEL_CSRA", &ParData, modID, ch); + if( CheckError("Pixie16ReadSglChanPar::CHANNEL_CSRA") < 0 ) return; + + ParData = ((int)ParData) ^ bitwise; + WriteChannelSetting("CHANNEL_CSRA", ParData, modID, ch); + +} + +void Pixie16::SetCSRABit(int bitwise, unsigned short val, unsigned short modID, unsigned short ch){ + + double ParData; + retval = Pixie16ReadSglChanPar( (char *)"CHANNEL_CSRA", &ParData, modID, ch); + if( CheckError("Pixie16ReadSglChanPar::CHANNEL_CSRA") < 0 ) return; + + int temp = ((int)ParData) & ~bitwise ; + int haha = 0; + if( bitwise == CSRA_BIT::FAST_TRIGGER ) haha = val << 0; + if( bitwise == CSRA_BIT::M_VALIDATION ) haha = val << 1; + if( bitwise == CSRA_BIT::ENABLE_CHANNEL ) haha = val << 2; + if( bitwise == CSRA_BIT::C_VALIFATION ) haha = val << 3; + if( bitwise == CSRA_BIT::BLOCK_DAQ_DPM_FULL ) haha = val << 4; + if( bitwise == CSRA_BIT::POLARITY ) haha = val << 5; + if( bitwise == CSRA_BIT::VETO_TRIGGER ) haha = val << 6; + if( bitwise == CSRA_BIT::HIST_ENERGY ) haha = val << 7; + if( bitwise == CSRA_BIT::ENABLE_TRACE ) haha = val << 8; + if( bitwise == CSRA_BIT::ENABLE_QDC ) haha = val << 9; + if( bitwise == CSRA_BIT::ENABLE_CFD ) haha = val << 10; + if( bitwise == CSRA_BIT::REQ_M_VALIDATION ) haha = val << 11; + if( bitwise == CSRA_BIT::CAPTURE_ESUMS_BASELINE ) haha = val << 12; + if( bitwise == CSRA_BIT::REQ_C_VALIDATION ) haha = val << 13; + if( bitwise == CSRA_BIT::INPUT_RELAY ) haha = val << 14; + if( bitwise == CSRA_BIT::PILEUP ) haha = val << 15; + if( bitwise == CSRA_BIT::NO_TRACE_LARGE_PULSE ) haha = val << 17; + if( bitwise == CSRA_BIT::GROUP_TRIGGER ) haha = val << 18; + if( bitwise == CSRA_BIT::CH_VETO ) haha = val << 19; + if( bitwise == CSRA_BIT::MO_VETO ) haha = val << 20; + if( bitwise == CSRA_BIT::EXT_TIMESTAMP ) haha = val << 21; + + WriteChannelSetting("CHANNEL_CSRA", (temp | haha), modID, ch); + +} + +unsigned int * Pixie16::GetStatitics(unsigned short modID){ + int ss = Pixie16GetStatisticsSize(); + if( Statistics != NULL ) delete Statistics; + Statistics = new unsigned int [ss]; + retval = Pixie16ReadStatisticsFromModule (Statistics, modID); + if( CheckError("Pixie16ReadStatisticsFromModule") < 0 ) return NULL; + return Statistics; +} + +void Pixie16::PrintStatistics(unsigned short modID){ + + GetStatitics(modID); + if( retval >= 0 ){ + printf(" Real (or RUN) Time : %9.3f sec \n", Pixie16ComputeRealTime (Statistics, modID)); + printf(" ch | live time (sec) | input count rate | output count rate \n"); + printf("-----+-----------------+------------------+-------------------\n"); + for( int ch = 0; ch < 16; ch ++){ + printf(" %2d |", ch); + printf(" %15.4f |", Pixie16ComputeLiveTime(Statistics, modID, ch)); + printf(" %16.4f |", Pixie16ComputeInputCountRate(Statistics, modID, ch)); + printf(" %17.4f \n", Pixie16ComputeOutputCountRate(Statistics, modID, ch)); + } + } +} + +double Pixie16::GetInputCountRate(unsigned short modID, unsigned short ch){ + int ss = Pixie16GetStatisticsSize(); + unsigned int statistics[ss]; + retval = Pixie16ReadStatisticsFromModule (statistics, modID); + if( CheckError("Pixie16ReadStatisticsFromModule") < 0 ) return -404; + return Pixie16ComputeInputCountRate (Statistics, modID, ch); +} +double Pixie16::GetLiveTime(unsigned short modID, unsigned short ch){ + int ss = Pixie16GetStatisticsSize(); + unsigned int statistics[ss]; + retval = Pixie16ReadStatisticsFromModule (statistics, modID); + if( CheckError("Pixie16ReadStatisticsFromModule") < 0 ) return -404; + return Pixie16ComputeLiveTime (statistics, modID, ch); +} + +double Pixie16::GetOutputCountRate(unsigned short modID, unsigned short ch){ + int ss = Pixie16GetStatisticsSize(); + unsigned int statistics[ss]; + retval = Pixie16ReadStatisticsFromModule (statistics, modID); + if( CheckError("Pixie16ReadStatisticsFromModule") < 0 ) return -404; + return Pixie16ComputeOutputCountRate (statistics, modID, ch); +} +double Pixie16::GetRealTime(unsigned short modID){ + int ss = Pixie16GetStatisticsSize(); + unsigned int statistics[ss]; + retval = Pixie16ReadStatisticsFromModule (statistics, modID); + if( CheckError("Pixie16ReadStatisticsFromModule") < 0 ) return -404; + return Pixie16ComputeRealTime (statistics, modID); +} + +void Pixie16::SaveSettings(std::string fileName){ + + retval = Pixie16SaveDSPParametersToFile((char *)fileName.c_str()); + if( CheckError("Pixie16SaveDSPParametersToFile") < 0 ) { + return; + }else{ + printf("saved setting to %s\n", fileName.c_str()); + } +} + +/* +void Pixie16::SaveData(char * fileName, unsigned short isEndOfRun){ + + retval = Pixie16SaveExternalFIFODataToFile(fileName, &nFIFOWords, 0, isEndOfRun); + if( CheckError("Pixie16SaveExternalFIFODataToFile") < 0 ) return; + +}*/ + + +#endif + diff --git a/Pixie16Class.h b/Pixie16Class.h new file mode 100644 index 0000000..bad376f --- /dev/null +++ b/Pixie16Class.h @@ -0,0 +1,162 @@ +#ifndef PIXIE16_H +#define PIXIE16_H + +#include + +#include "DataBlock.h" + +enum CSRA_BIT{ + FAST_TRIGGER = 0x00000001, + M_VALIDATION = 0x00000002, + ENABLE_CHANNEL = 0x00000004, + C_VALIFATION = 0x00000008, + BLOCK_DAQ_DPM_FULL = 0x00000010, + POLARITY = 0x00000020, + VETO_TRIGGER = 0x00000040, + HIST_ENERGY = 0x00000080, + ENABLE_TRACE = 0x00000100, + ENABLE_QDC = 0x00000200, + ENABLE_CFD = 0x00000400, + REQ_M_VALIDATION = 0x00000800, + CAPTURE_ESUMS_BASELINE = 0x00001000, + REQ_C_VALIDATION = 0x00002000, + INPUT_RELAY = 0x00004000, + PILEUP = 0x00018000, + NO_TRACE_LARGE_PULSE = 0x00020000, + GROUP_TRIGGER = 0x00040000, + CH_VETO = 0x00080000, + MO_VETO = 0x00100000, + EXT_TIMESTAMP = 0x00200000, +}; + +class Pixie16 { + +private: + unsigned short NumModules; + unsigned short * PXISlotMap; + unsigned short OfflineMode; + + char ** ComFPGAConfigFile; + char ** SPFPGAConfigFile; + char ** TrigFPGAConfigFile; + char ** DSPCodeFile; + char ** DSPParFile; + char ** DSPVarFile; + + unsigned short BootPattern ; + + int retval; + + bool isRunning; + + int CheckError(std::string operation); + + unsigned int nFIFOWords; + unsigned int * ExtFIFO_Data; + unsigned int * Statistics; + + DataBlock * data; + + /*** + struct channelSetting{ + double trigger_risetime; + double trigger_flattop; + double trigger_threshold; + double energy_risetime; + double energy_flattop; + double tau; + double trace_length; + double trace_delay; + double V_offset; + double XDT; + double baseline_percent; + double energy_minumum; //EMIN + double baseline_cut; //BLCUT + };**/ + +public: + + Pixie16(); + ~Pixie16(); + + int GetStatus() {return retval;} + bool IsRunning() {return isRunning;} + + ///======================== startup + bool LoadConfigFile(std::string fileName); + + void CheckDriver(); + void CheckHardware(); + + void GetDigitizerInfo(unsigned short modID); + void BootDigitizers(); + + + ///========================= Setting + + void GetDigitizerSettings(unsigned short modID); + + double GetChannelSetting(std::string parName, unsigned short modID, unsigned short ch, bool verbose = false); + double GetChannelTriggerRiseTime (unsigned modID, unsigned short ch){ return GetChannelSetting("TRIGGER_RISETIME", modID, ch); } + double GetChannelTriggerFlatTop (unsigned modID, unsigned short ch){ return GetChannelSetting("TRIGGER_FLATTOP", modID, ch); } + double GetChannelTriggerThreshold(unsigned modID, unsigned short ch){ return GetChannelSetting("TRIGGER_THRESHOLD", modID, ch); } + double GetChannelEnergyRiseTime (unsigned modID, unsigned short ch){ return GetChannelSetting("ENERGY_RISETIME", modID, ch); } + double GetChannelEnergyFlatTop (unsigned modID, unsigned short ch){ return GetChannelSetting("ENERGY_FLATTOP", modID, ch); } + double GetChannelEnergyTau (unsigned modID, unsigned short ch){ return GetChannelSetting("TAU", modID, ch); } + double GetChannelTraceLength (unsigned modID, unsigned short ch){ return GetChannelSetting("TRACE_LENGTH", modID, ch); } + double GetChannelTraceDelay (unsigned modID, unsigned short ch){ return GetChannelSetting("TRACE_DELAY", modID, ch); } + double GetChannelVOffset (unsigned modID, unsigned short ch){ return GetChannelSetting("VOFFSET", modID, ch); } + double GetChannelBaseLinePrecent (unsigned modID, unsigned short ch){ return GetChannelSetting("BASELINE_PERCENT", modID, ch); } + + void PrintChannelAllSettings(unsigned short modID, unsigned short ch); + void PrintChannelsMainSettings(unsigned short modID); + + unsigned short GetCSRA(int bitwise, unsigned short modID, unsigned short ch, bool verbose = false); + bool GetChannleOnOff(unsigned short modID, unsigned short ch, bool verbose = false) {return GetCSRA(CSRA_BIT::ENABLE_CHANNEL, modID, ch, verbose);} + bool GetChannelPolarity(unsigned short modID, unsigned short ch, bool verbose = false) {return GetCSRA(CSRA_BIT::POLARITY, modID, ch, verbose);} + bool GetChannelTraceOnOff(unsigned short modID, unsigned short ch, bool verbose = false) {return GetCSRA(CSRA_BIT::ENABLE_TRACE, modID, ch, verbose);} + + void WriteChannelSetting(std::string parName, double val, unsigned short modID, unsigned short ch, bool verbose = false); + void WriteChannelTriggerRiseTime (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TRIGGER_RISETIME", val, modID, ch, 1);} + void WriteChannelTriggerFlatTop (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TRIGGER_FLATTOP", val, modID, ch, 1);} + void WriteChannelTriggerThreshold(double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TRIGGER_THRESHOLD", val, modID, ch, 1);} + void WriteChannelEnergyRiseTime (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("ENERGY_RISETIME", val, modID, ch, 1);} + void WriteChannelEnergyFlatTop (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("ENERGY_FLATTOP", val, modID, ch, 1);} + void WriteChannelEnergyTau (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TAU", val, modID, ch, 1);} + void WriteChannelTraceLenght (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TRACE_LENGTH", val, modID, ch, 1);} + void WriteChannelTraceDelay (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("TRACE_DELAY", val, modID, ch, 1);} + void WriteChannelBaseLinePrecent (double val, unsigned short modID, unsigned short ch){ WriteChannelSetting("BASELINE_PERCENT", val, modID, ch, 1);} + + void SwitchCSRA(int bitwise, unsigned short modID, unsigned short ch); + void SetCSRABit(int bitwise, unsigned short val, unsigned short modID, unsigned short ch); + + void SetChannleOnOff(bool enable, unsigned short modID, unsigned short ch) { SetCSRABit(CSRA_BIT::ENABLE_CHANNEL, enable, modID, ch); } + void SetPositivePolarity(bool positive, unsigned short modID, unsigned short ch) { SetCSRABit(CSRA_BIT::POLARITY, positive, modID, ch); } + void SetTraceOnOff(bool enable, unsigned short modID, unsigned short ch) { SetCSRABit(CSRA_BIT::ENABLE_TRACE, enable, modID, ch); } + + void SaveSettings(std::string fileName); + + ///========================== RUN + + void StartRun(bool listMode); + void StopRun(); + + unsigned int * GetStatitics(unsigned short modID); + double GetInputCountRate(unsigned short modID, unsigned short ch); + double GetLiveTime(unsigned short modID, unsigned short ch); + double GetOutputCountRate(unsigned short modID, unsigned short ch); + double GetRealTime(unsigned short modID); + void PrintStatistics(unsigned short modID); + + void GetTrace(unsigned short modID, unsigned short ch); + void GetBaseLines(unsigned short modID, unsigned short ch); + + void ReadData(unsigned short modID); + void PrintData(); + + //void SaveData(char * fileName, unsigned short isEndOfRun); + + +}; + +#endif diff --git a/Pixie16_FSU_Sample_Setup.set b/Pixie16_FSU_Sample_Setup.set new file mode 100644 index 0000000..6a8d098 --- /dev/null +++ b/Pixie16_FSU_Sample_Setup.set @@ -0,0 +1,1091 @@ +[ + { + "channel": { + "input": { + "BLcut": [ + 32, + 1, + 1, + 31, + 31, + 1, + 1, + 32, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2 + ], + "BaselinePercent": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "CFDDelay": [ + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8 + ], + "CFDScale": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "CFDThresh": [ + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120 + ], + "ChanCSRa": [ + 18852, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804, + 16804 + ], + "ChanCSRb": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "ChanTrigStretch": [ + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100 + ], + "DigGain": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "EnergyLow": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "ExtTrigStretch": [ + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150 + ], + "ExternDelayLen": [ + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20 + ], + "FastGap": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FastLength": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FastThresh": [ + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000, + 2000 + ], + "FastTrigBackLen": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FtrigoutDelay": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "GainDAC": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Integrator": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Log2Bweight": [ + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294 + ], + "Log2Ebin": [ + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295 + ], + "MultiplicityMaskH": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "MultiplicityMaskL": [ + 96, + 96, + 96, + 96, + 104, + 104, + 104, + 104, + 112, + 112, + 112, + 112, + 2, + 2, + 2, + 2 + ], + "OffsetDAC": [ + 38048, + 38304, + 37664, + 38048, + 38240, + 38304, + 37984, + 37856, + 38816, + 38112, + 38688, + 38368, + 38496, + 38624, + 38240, + 38048 + ], + "PAFlength": [ + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768 + ], + "PSAlength": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PSAoffset": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PeakSample": [ + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95 + ], + "PeakSep": [ + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97 + ], + "PreampTau": [ + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650 + ], + "QDCLen0": [ + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30 + ], + "QDCLen1": [ + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63 + ], + "QDCLen2": [ + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88 + ], + "QDCLen3": [ + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113 + ], + "QDCLen4": [ + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138 + ], + "QDCLen5": [ + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163 + ], + "QDCLen6": [ + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188 + ], + "QDCLen7": [ + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213 + ], + "ResetDelay": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "SlowGap": [ + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19 + ], + "SlowLength": [ + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78 + ], + "ThreshWidth": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "TraceLength": [ + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000 + ], + "TrigOutLen": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "TriggerDelay": [ + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768 + ], + "VetoStretch": [ + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30 + ], + "Xavg": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Xwait": [ + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96 + ] + } + }, + "metadata": { + "config": [ + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + } + ], + "dsp": { + "adc_bits": 16, + "adc_msps": 250, + "file": "Pixie16DSP_revfgeneral_12b250m_r41847.ldr", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "fifo": { + "buffers": 100, + "hold": 50000, + "idle-wait": 150000, + "run-wait": 2000 + }, + "fippi": { + "adc_bits": 16, + "adc_msps": 250, + "file": "fippixie16_revfgeneral_12b250m_r42081.bin", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "hardware_revision": "F", + "num-channels": 16, + "number": 0, + "serial-num": 1314, + "slot": 2, + "sys": { + "adc_bits": 16, + "adc_msps": 250, + "file": "syspixie16_revfgeneral_adc250mhz_r33339.bin", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "var": { + "adc_bits": 16, + "adc_msps": 250, + "file": "Pixie16DSP_revfgeneral_12b250m_r41847.var", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + } + }, + "module": { + "input": { + "ChanNum": 0, + "CoincPattern": 0, + "CoincWait": 0, + "ControlTask": 23, + "CrateID": 0, + "FIFOLength": 8188, + "FastFilterRange": 0, + "FastTrigBackplaneEna": 0, + "HostIO": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "HostRunTimePreset": 1092616192, + "InSynch": 1, + "MaxEvents": 0, + "ModCSRA": 0, + "ModCSRB": 1, + "ModFormat": 0, + "ModID": 0, + "ModNum": 0, + "Resume": 1, + "RunTask": 0, + "SlotID": 2, + "SlowFilterRange": 3, + "SynchWait": 1, + "TrigConfig": [ + 6212, + 0, + 0, + 0 + ], + "U00": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "UserIn": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + } + } +] diff --git a/Pixie16_example_legacy.set b/Pixie16_example_legacy.set new file mode 100644 index 0000000..1eba988 Binary files /dev/null and b/Pixie16_example_legacy.set differ diff --git a/evtReader.h b/evtReader.h new file mode 100644 index 0000000..ee859db --- /dev/null +++ b/evtReader.h @@ -0,0 +1,276 @@ +#ifndef EVTREADER_H +#define EVTREADER_H + +#include +#include +#include +#include +#include + +#include "TSystem.h" +#include "TObject.h" +#include "TFile.h" +#include "TTree.h" +#include "TString.h" +#include "TBenchmark.h" + +#include "../mapping.h" +#include "../armory/DataBlock.h" + +#define MAX_CRATES 2 +#define MAX_BOARDS_PER_CRATE 13 +#define MAX_CHANNELS_PER_BOARD 16 +#define BOARD_START 2 + +class evtReader{ + + public: + DataBlock * data; + + private: + FILE * inFile; + + long int inFileSize; + long int inFilePos; + bool endOfFile; + bool isOpened; + Long64_t blockID; + long int nBlock; + + unsigned int extraHeader[14]; + unsigned int traceBlock[4000]; + + TBenchmark gClock; + + ///============================================ Methods + public: + + evtReader(); + evtReader(TString inFileName); + ~evtReader(); + + void OpenFile(TString inFileName); + + void UpdateFileSize(); + bool IsEndOfFile(); + + bool IsOpen() {return isOpened;} + long int GetFilePos() {return inFilePos;} + long int GetFileSize() {return inFileSize;} + Long64_t GetBlockID() {return blockID;} + Long64_t GetNumberOfBlock() {return nBlock;} + + int ReadBlock(int opt = 0); /// 0 = default, fill data + /// 1 = no fill data + + void ScanNumberOfBlock(); + void PrintStatus(int mod); + +}; + + +//========================== implementation + +evtReader::evtReader(){ + inFile = 0; + data = new DataBlock(); + + inFileSize = 0; + inFilePos = 0; + + nBlock = 0; + blockID = -1; + endOfFile = false; + isOpened = false; +} + + +evtReader::~evtReader(){ + fclose(inFile); + delete inFile; + delete data; +} + + +evtReader::evtReader(TString inFileName){ + inFile = 0; + data = new DataBlock(); + + inFileSize = 0; + inFilePos = 0; + + nBlock = 0; + blockID = -1; + endOfFile = false; + isOpened = false; + + OpenFile(inFileName); +} + +void evtReader::OpenFile(TString inFileName){ + inFile = fopen(inFileName, "r"); + if( inFile == NULL ){ + printf("Cannot read file : %s \n", inFileName.Data()); + }else{ + fseek(inFile, 0L, SEEK_END); + inFileSize = ftell(inFile); + rewind(inFile); ///back to the File begining + + data->Clear(); + + gClock.Reset(); + gClock.Start("timer"); + } +}; + +void evtReader::UpdateFileSize(){ + if( inFile == NULL ) return; + fseek(inFile, 0L, SEEK_END); + inFileSize = ftell(inFile); + fseek(inFile, inFilePos, SEEK_SET); +} + +bool evtReader::IsEndOfFile() { + int haha = feof(inFile); + return haha > 0 ? true: false; +} + + +int evtReader::ReadBlock(int opt = 0){ + + if( feof(inFile) ) return -1; + if( endOfFile ) return -1; + + unsigned int header[4]; ///read 4 header, unsigned int = 4 byte = 32 bits. + + if ( fread(header, sizeof(header), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + blockID ++; + + + if( opt == 0 ){ + /// see the Pixie-16 user manual, Table4-2 + data->eventID = blockID; + data->ch = header[0] & 0xF ; + data->slot = (header[0] >> 4) & 0xF; + data->crate = (header[0] >> 8) & 0xF; + data->headerLength = (header[0] >> 12) & 0x1F; + data->eventLength = (header[0] >> 17) & 0x3FFF; + data->pileup = header[0] >> 31 ; + data->time = ((ULong64_t)(header[2] & 0xFFFF) << 32) + header[1]; + data->cfd = header[2] >> 16 ; + data->energy = (header[3] & 0xFFFF ); + data->trace_length = (header[3] >> 16) & 0x7FFF; + data->trace_out_of_range = header[3] >> 31; + + data->id = data->crate*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD + (data->slot-BOARD_START)*MAX_CHANNELS_PER_BOARD + data->ch; + data->detID = mapping[data->id]; + + data->ClearQDC(); + + ///======== read QDCsum + if( data->headerLength >= 4 ){ + fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); + if( data->headerLength == 8 || data->headerLength == 16){ + data->trailing = extraHeader[0]; + data->leading = extraHeader[1]; + data->gap = extraHeader[2]; + data->baseline = extraHeader[3]; + } + if( data->headerLength == 12 || data->headerLength == 16){ + for( int i = 0; i < 8; i++){ + int startID = 0; + if( data->headerLength > 12) startID = 4; ///the 1st 4 words + data->QDCsum[i] = extraHeader[i+startID]; + } + } + }else{ + for( int i = 0 ; i < 8; i++){ data->QDCsum[i] = 0;} + data->trailing = 0; + data->leading = 0; + data->gap = 0; + data->baseline = 0; + } + ///====== read trace + if( data->eventLength > data->headerLength ){ + fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); + + for( int i = 0; i < data->trace_length/2 ; i++){ + data->trace[2*i+0] = traceBlock[i] & 0xFFFF ; + data->trace[2*i+1] = (traceBlock[i] >> 16 ) & 0xFFFF ; + } + + ///make QDC by trace + if( data->headerLength == 4 || data->headerLength == 8 ) { + for( int i = 0; i < 8; i++){ data->QDCsum[i] = 0;} + for( int i = 0; i < data->trace_length; i++){ + if( 0 <= i && i < 31 ) data->QDCsum[0] += data->trace[i]; + if( 31 <= i && i < 60 ) data->QDCsum[1] += data->trace[i]; + if( 60 <= i && i < 75 ) data->QDCsum[2] += data->trace[i]; + if( 75 <= i && i < 95 ) data->QDCsum[3] += data->trace[i]; + if( 95 <= i && i < 105 ) data->QDCsum[4] += data->trace[i]; + if( 105 <= i && i < 160 ) data->QDCsum[5] += data->trace[i]; + if( 160 <= i && i < 175 ) data->QDCsum[6] += data->trace[i]; + if( 175 <= i && i < 200 ) data->QDCsum[7] += data->trace[i]; + } + } + } + } + + if( opt == 1 ){ + + data->headerLength = (header[0] >> 12) & 0x1F; + data->eventLength = (header[0] >> 17) & 0x3FFF; + data->trace_length = (header[3] >> 16) & 0x7FFF; + + if( data->headerLength >= 4 ){ + fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); + } + if( data->eventLength > data->headerLength ){ + fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); + } + } + + inFilePos = ftell(inFile); + + return 1; +} + + +void evtReader::ScanNumberOfBlock(){ + + nBlock = 0; + while( ReadBlock(1) != -1 ){ + nBlock ++; + PrintStatus(10000); + } + + printf("\n\n\n"); + printf("scan complete: number of data Block : %ld\n", nBlock); + + inFilePos = 0; + blockID = -1; + + rewind(inFile); ///back to the File begining + endOfFile = false; + +} + + +void evtReader::PrintStatus(int mod){ + + ///==== event stats, print status every 10000 events + if ( blockID % mod == 0 ) { + UpdateFileSize(); + gClock.Stop("timer"); + double time = gClock.GetRealTime("timer"); + gClock.Start("timer"); + printf("Total measurements: \x1B[32m%llu \x1B[0m\nReading Pos: \x1B[32m %.3f/%.3f GB\x1B[0m\nTime used:%3.0f min %5.2f sec\033[A\033[A\r", + blockID, inFilePos/(1024.*1024.*1024.), inFileSize/1024./1024./1024, TMath::Floor(time/60.), time - TMath::Floor(time/60.)*60.); + } + +} + +#endif diff --git a/example.cpp b/example.cpp new file mode 100644 index 0000000..0f2bf86 --- /dev/null +++ b/example.cpp @@ -0,0 +1,899 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include + +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(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_configs; + +struct configuration { + module_configs modules; + std::vector slot_def; + unsigned short num_modules() const { + return static_cast(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(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 stats(Pixie16GetStatisticsSize(), 0); +#else + std::vector 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(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 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 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", "bin"), + std::ios::out | std::ios::binary); + } + + std::vector 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::steady_clock::now() - run_start_time) + .count() < runtime_in_seconds) { + for (unsigned short mod_num = 0; mod_num < cfg.num_modules(); 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(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::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(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 = 0 in Module 0." + << std::endl; + if (!verify_api_return_value(Pixie16WriteSglModPar("SYNCH_WAIT", 0, mod), + "Pixie16WriteSglModPar - SYNC_WAIT")) + return false; + + std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write IN_SYNCH = 1 in Module 0." + << std::endl; + if (!verify_api_return_value(Pixie16WriteSglModPar("IN_SYNCH", 1, 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::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::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> hists; + for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) { + std::vector 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& parameter, + args::ValueFlag& crate, + args::ValueFlag& module, + args::ValueFlag& 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& parameter, + args::ValueFlag& value, args::ValueFlag& crate, + const module_config& module, args::ValueFlag& 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& module, args::ValueFlag& 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& 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(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 conf_flag(arguments, "cfg", "The configuration file to load.", + {'c', "config"}, args::Options::Required); + args::ValueFlag 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 boot_pattern_flag(arguments, "boot_pattern", + "The boot pattern used for booting.", + {'b', "boot_pattern"}, "0x7F"); + args::ValueFlag run_time( + list_mode, "time", "The amount of time that a list mode run will take in seconds.", + {'t', "run-time"}, 10.); + args::ValueFlag parameter( + arguments, "parameter", "The parameter we want to read from the system.", {'n', "name"}); + args::ValueFlag channel(arguments, "channel", "The channel to operate on.", + {"chan"}); + args::ValueFlag crate(arguments, "crate", "The crate", {"crate"}, 0); + args::ValueFlag copy_mask( + copy, "copy_mask", "An integer representing the set of parameters to copy", {"copy-mask"}); + args::ValueFlag dest_mask( + copy, "dest_mask", "An integer representing the destination channels", {"dest-mask"}); + args::ValueFlag dest_channel(copy, "dest_channel", + "The channel that we'll copy to", {"dest-chan"}); + args::ValueFlag dest_module(copy, "dest_module", "The module that we'll copy to.", + {"dest-mod"}); + args::ValueFlag module(arguments, "module", "The module to operate on.", {"mod"}); + args::ValueFlag 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 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 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; +} diff --git a/example_config.json b/example_config.json new file mode 100644 index 0000000..6e1e61f --- /dev/null +++ b/example_config.json @@ -0,0 +1,15 @@ +[ + { + "slot": 2, + "dsp": { + "ldr": "/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.ldr", + "par": "/home/ryan/Pixie16/ryan/test_ryan.set", + "var": "/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/dsp/Pixie16DSP_revfgeneral_12b250m_r41847.var" + }, + "fpga": { + "fippi": "/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/fippixie16_revfgeneral_12b250m_r42081.bin", + "sys": "/usr/opt/Pixie16/pixie16_revf_general_12b250m_41847_2019-05-18/firmware/syspixie16_revfgeneral_adc250mhz_r33339.bin", + "trig": "FPGATrig" + } + } +] diff --git a/pxisys.ini b/pxisys.ini new file mode 100644 index 0000000..cd47502 --- /dev/null +++ b/pxisys.ini @@ -0,0 +1,105 @@ +# This is the PXISYS.INI file for a PXI system using +# a Wiener 14-slot Pixie-16 Chassis. +# + +[Slot1] +IDSEL = None +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = None +PCIDeviceNumber = None + +[Slot2] +IDSEL = 31 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 15 + +[Slot3] +IDSEL = 30 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 14 + +[Slot4] +IDSEL = 29 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 13 + +[Slot5] +IDSEL = 28 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 12 + +[Slot6] +IDSEL = 27 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 11 + +[Slot7] +IDSEL = 26 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 1 +PCIDeviceNumber = 10 + + + +[Slot8] +IDSEL = 31 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 15 + +[Slot9] +IDSEL = 30 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 14 + +[Slot10] +IDSEL = 29 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 13 + +[Slot11] +IDSEL = 28 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 12 + +[Slot12] +IDSEL = 27 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 11 + +[Slot13] +IDSEL = 26 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 10 + +[Slot14] +IDSEL = 25 +SecondaryBusNumber = 0 +ExternalBackplaneInterface = None +PCIBusNumber = 2 +PCIDeviceNumber = 9 + + diff --git a/read-set b/read-set new file mode 100755 index 0000000..37e8003 Binary files /dev/null and b/read-set differ diff --git a/read-set.c b/read-set.c new file mode 100644 index 0000000..88272c9 --- /dev/null +++ b/read-set.c @@ -0,0 +1,50 @@ +/**********************************************************/ +/* Read PXI Set File -- J.M. Allmond (ORNL) -- July 2016 */ +/**********************************************************/ + + +#include +#include +#include +#include +#include + + +#define MOD_NUM 1 +#define MOD_SLOT_START 2 +#define MOD_LENGTH 1280 //Number of DSP Parameters per Module +#define MOD_TYPE uint32_t //unsigned/signed 2-btye/4-byte; i.e., int16_t, uint16_t, int32_t, uint32_t + +int main(int argc, char **argv) { + + FILE *fpr; + MOD_TYPE mod[MOD_LENGTH]; + memset(mod, 0, sizeof(mod)); + + int i=0; + int module=MOD_SLOT_START; + + if ((fpr = fopen(argv[1], "r")) == NULL) { + fprintf(stderr, "Error, cannot open input file %s\n", argv[1]); + return 1; + } + + + while (fread(mod, MOD_LENGTH*sizeof(MOD_TYPE), 1, fpr) == 1) { // read next module settings + + //Settings + for (i = 0; i < MOD_LENGTH; i++) { + + printf("%d\t%d\t%u\n", module, i, mod[i]); + + } + + module++; + } + + + fclose(fpr); + + return 0; +} + diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..b64573d --- /dev/null +++ b/test.cpp @@ -0,0 +1,273 @@ +//*.h are C header +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct timeval, select() */ +#include /* tcgetattr(), tcsetattr() */ + +#include "Pixie16Class.h" + + +long get_time(); +static struct termios g_old_kbd_mode; +static void cooked(void); ///set keyboard behaviour as wait-for-enter +static void uncooked(void); ///set keyboard behaviour as immediate repsond +static void raw(void); +int getch(void); +int keyboardhit(); + +bool QuitFlag = false; + +void PrintCommands(){ + + if (QuitFlag) return; + printf("\n"); + printf("\e[96m============= Command List ===================\e[0m\n"); + printf("s ) Start acquisition \n"); + printf("a ) Stop acquisition \n"); + printf("q ) Quit \n"); + printf("\n"); + printf("r ) RiseTime \n"); + printf("t ) Trigger \n"); + + + +} + +///################################################## +int main(int argc, char *argv[]){ + + Pixie16 * pixie = new Pixie16(); + if ( pixie->GetStatus() < 0 ) { + QuitFlag = true; + printf("Exiting program... \n"); + return 0; + } + + pixie->GetDigitizerSettings(0); + + ///pixie->GetHostCSR(0); + + ///pixie->SaveSettings("haha.set"); + + /* + pixie->GetPolarity(0, 6, 1); + pixie->SetPolarity(false, 0, 6); + pixie->GetPolarity(0, 6, 1); + pixie->SetPolarity(true, 0, 6); + pixie->GetPolarity(0, 6, 1); + */ + + + int ch = 6; + double time = 0.5; ///sec + + /* + for( int i = 0; i < 16; i++){ + if( i == ch ){ + pixie->WriteChannelTriggerThreshold(10, 0, i); + pixie->WriteChannelEnergyRiseTime(4, 0, i); + pixie->WriteChannelEnergyTau(50, 0, i); + pixie->WriteChannelTraceLenght(1, 0, i); + pixie->WriteChannelTraceDelay(0.5, 0, i); + pixie->SetPositivePolarity(true, 0, i); + pixie->SetTraceOnOff(false, 0, i); + + }else{ + pixie->WriteChannelTriggerThreshold(500, 0, i); + pixie->SetChannleOnOff(false, 0, i); + } + } + */ + pixie->WriteChannelTriggerThreshold(500, 0, 6); + pixie->SaveSettings("test_ryan.set"); + + pixie->PrintChannelsMainSettings(0); + + printf("start run for %f sec\n", time); + pixie->StartRun(1); + + ///pixie->GetHostCSR(0); + + usleep(time*1e6); + pixie->StopRun(); + + pixie->ReadData(0); + + //pixie->PrintData(); + + + printf("===================================\n"); + pixie->PrintStatistics(0); + + + //pixie->SaveSettings("/home/ryan/Pixie16/ryan/test_ryan.set"); + + //pixie->GetTrace(0,0); + + /* + uint32_t StartTime = get_time(), CurrentTime, ElapsedTime; + uint32_t PreviousTime = get_time(); + + uint32_t updatePeriod = 1000; + + PrintCommands(); + + //start event loop + while(!QuitFlag){ + + if( keyboardhit()){ + char c = getch(); + + if( c =='s' ){ + pixie->StartRun(1); + StartTime = get_time(); + + } + + if( c == 'a'){ + pixie->StopRun(); + + } + + if( c == 'q'){ + pixie->StopRun(); + QuitFlag = true; + } + + if( c == 'r'){ + float haha; + cooked(); + printf("Rise time [us] ? "); + int temp = scanf("%f", &haha); + pixie->WriteChannelEnergyRiseTime((double)haha, 0, 0); + + printf("Rise time for channle 0 is now : %f us\n", pixie->GetChannelEnergyRiseTime(0,0)); + uncooked(); + + } + + if( c == 't'){ + float haha; + cooked(); + printf("Trigger [ADC] ? "); + int temp = scanf("%f", &haha); + pixie->WriteChannelTriggerThreshold(haha, 0, 0); + + printf("Tigger for channle 0 is now : %f ADC\n", pixie->GetChannelTriggerThreshold(0,0)); + uncooked(); + + } + + } + + + CurrentTime = get_time(); + ElapsedTime = CurrentTime - PreviousTime; /// milliseconds + + if (ElapsedTime > updatePeriod){ + system("clear"); + printf("\n======== Tree, Histograms, and Table update every ~%.2f sec\n", updatePeriod/1000.); + if( pixie->IsRunning() ) { + printf("\033[1;33m DAQ is running \033[m\n"); + printf(" Rise time for channle 0: %f us\n", pixie->GetChannelEnergyRiseTime(0,0)); + printf(" Flat top for channle 0: %f us\n", pixie->GetChannelEnergyFlatTop(0,0)); + printf(" Decay time for channle 0: %f us\n", pixie->GetChannelEnergyTau(0,0)); + printf("Trigger threshold for channle 0: %.0f ADC\n", pixie->GetChannelTriggerThreshold(0,0)); + } + printf("Time Elapsed = %.3f sec = %.1f min\n", (CurrentTime - StartTime)/1e3, (CurrentTime - StartTime)/1e3/60.); + pixie->ReadData(0); + + pixie->PrintData(); + + PreviousTime = CurrentTime; + + PrintCommands(); + + } + + } + /**/ + + + //delete pixie; + + printf("================ end of program. \n"); + return 0; +} + +///################################################## +long get_time(){ + long time_ms; + struct timeval t1; + struct timezone tz; + gettimeofday(&t1, &tz); + time_ms = (t1.tv_sec) * 1000 + t1.tv_usec / 1000; + return time_ms; +} + + +static void cooked(void){ + tcsetattr(0, TCSANOW, &g_old_kbd_mode); +} + +static void uncooked(void){ + struct termios new_kbd_mode; + /* put keyboard (stdin, actually) in raw, unbuffered mode */ + tcgetattr(0, &g_old_kbd_mode); + memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios)); + new_kbd_mode.c_lflag &= ~(ICANON | ECHO); + new_kbd_mode.c_cc[VTIME] = 0; + new_kbd_mode.c_cc[VMIN] = 1; + tcsetattr(0, TCSANOW, &new_kbd_mode); +} + +static void raw(void){ + + static char init; + if(init) return; + /* put keyboard (stdin, actually) in raw, unbuffered mode */ + uncooked(); + /* when we exit, go back to normal, "cooked" mode */ + atexit(cooked); + + init = 1; +} + + +int getch(void){ + unsigned char temp; + raw(); + /* stdin = fd 0 */ + if(read(0, &temp, 1) != 1) return 0; + //printf("%s", &temp); + return temp; +} + + + + +int keyboardhit(){ + + struct timeval timeout; + fd_set read_handles; + int status; + + raw(); + /* check stdin (fd 0) for activity */ + FD_ZERO(&read_handles); + FD_SET(0, &read_handles); + timeout.tv_sec = timeout.tv_usec = 0; + status = select(0 + 1, &read_handles, NULL, NULL, &timeout); + if(status < 0){ + printf("select() failed in keyboardhit()\n"); + exit(1); + } + return (status); +} diff --git a/test_ryan.set b/test_ryan.set new file mode 100644 index 0000000..a341d4b --- /dev/null +++ b/test_ryan.set @@ -0,0 +1,1091 @@ +[ + { + "channel": { + "input": { + "BLcut": [ + 32, + 1, + 1, + 31, + 31, + 1, + 36, + 32, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2 + ], + "BaselinePercent": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "CFDDelay": [ + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8 + ], + "CFDScale": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "CFDThresh": [ + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120, + 120 + ], + "ChanCSRa": [ + 18848, + 16800, + 16800, + 16800, + 16800, + 16800, + 16548, + 16800, + 16800, + 16800, + 16800, + 16800, + 16800, + 16800, + 16800, + 16800 + ], + "ChanCSRb": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "ChanTrigStretch": [ + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100 + ], + "DigGain": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "EnergyLow": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "ExtTrigStretch": [ + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150, + 150 + ], + "ExternDelayLen": [ + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20, + 20 + ], + "FastGap": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FastLength": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FastThresh": [ + 2000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000, + 10000 + ], + "FastTrigBackLen": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "FtrigoutDelay": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "GainDAC": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Integrator": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Log2Bweight": [ + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294, + 4294967294 + ], + "Log2Ebin": [ + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295, + 4294967295 + ], + "MultiplicityMaskH": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "MultiplicityMaskL": [ + 96, + 96, + 96, + 96, + 104, + 104, + 104, + 104, + 112, + 112, + 112, + 112, + 2, + 2, + 2, + 2 + ], + "OffsetDAC": [ + 38048, + 38304, + 37664, + 38048, + 38240, + 38304, + 37984, + 37856, + 38816, + 38112, + 38688, + 38368, + 38496, + 38624, + 38240, + 38048 + ], + "PAFlength": [ + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 710, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768, + 1768 + ], + "PSAlength": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PSAoffset": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "PeakSample": [ + 95, + 95, + 95, + 95, + 95, + 95, + 80, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95, + 95 + ], + "PeakSep": [ + 97, + 97, + 97, + 97, + 97, + 97, + 82, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97, + 97 + ], + "PreampTau": [ + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1112014848, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650, + 1100456650 + ], + "QDCLen0": [ + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30 + ], + "QDCLen1": [ + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63, + 63 + ], + "QDCLen2": [ + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88, + 88 + ], + "QDCLen3": [ + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113, + 113 + ], + "QDCLen4": [ + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138, + 138 + ], + "QDCLen5": [ + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163, + 163 + ], + "QDCLen6": [ + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188, + 188 + ], + "QDCLen7": [ + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213, + 213 + ], + "ResetDelay": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "SlowGap": [ + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19, + 19 + ], + "SlowLength": [ + 78, + 78, + 78, + 78, + 78, + 78, + 63, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78, + 78 + ], + "ThreshWidth": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "TraceLength": [ + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 250, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000, + 5000 + ], + "TrigOutLen": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "TriggerDelay": [ + 768, + 768, + 768, + 768, + 768, + 768, + 648, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768, + 768 + ], + "VetoStretch": [ + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30 + ], + "Xavg": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "Xwait": [ + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96 + ] + } + }, + "metadata": { + "config": [ + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + }, + { + "adc_bits": 16, + "adc_clk_div": 2, + "adc_msps": 250, + "fpga_clk_mhz": 125 + } + ], + "dsp": { + "adc_bits": 16, + "adc_msps": 250, + "file": "Pixie16DSP_revfgeneral_12b250m_r41847.ldr", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "fifo": { + "buffers": 100, + "hold": 50000, + "idle-wait": 150000, + "run-wait": 2000 + }, + "fippi": { + "adc_bits": 16, + "adc_msps": 250, + "file": "fippixie16_revfgeneral_12b250m_r42081.bin", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "hardware_revision": "F", + "num-channels": 16, + "number": 0, + "serial-num": 1314, + "slot": 2, + "sys": { + "adc_bits": 16, + "adc_msps": 250, + "file": "syspixie16_revfgeneral_adc250mhz_r33339.bin", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + }, + "var": { + "adc_bits": 16, + "adc_msps": 250, + "file": "Pixie16DSP_revfgeneral_12b250m_r41847.var", + "rev": 15, + "tag": "15-250-16", + "version": "n/a" + } + }, + "module": { + "input": { + "ChanNum": 0, + "CoincPattern": 0, + "CoincWait": 0, + "ControlTask": 5, + "CrateID": 0, + "FIFOLength": 8188, + "FastFilterRange": 0, + "FastTrigBackplaneEna": 0, + "HostIO": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "HostRunTimePreset": 1092616192, + "InSynch": 1, + "MaxEvents": 0, + "ModCSRA": 0, + "ModCSRB": 1, + "ModFormat": 0, + "ModID": 0, + "ModNum": 0, + "Resume": 1, + "RunTask": 0, + "SlotID": 2, + "SlowFilterRange": 3, + "SynchWait": 1, + "TrigConfig": [ + 6212, + 0, + 0, + 0 + ], + "U00": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "UserIn": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + } + } +]