use libPixie16Api.so, can change setting, try to understand the collected data

This commit is contained in:
Ryan Tang 2022-03-02 18:28:38 -05:00
commit 9a302c631b
15 changed files with 4723 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
*.o
*.log
*.bin
*.csv
*.gch
test
example

95
DataBlock.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef DATABLOCK_H
#define DATABLOCK_H
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
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

53
Makefile Normal file
View File

@ -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

605
Pixie16Class.cpp Normal file
View File

@ -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 <bitset>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <array>
#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<char*> (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<char*> (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

162
Pixie16Class.h Normal file
View File

@ -0,0 +1,162 @@
#ifndef PIXIE16_H
#define PIXIE16_H
#include <string>
#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

1091
Pixie16_FSU_Sample_Setup.set Normal file

File diff suppressed because it is too large Load Diff

BIN
Pixie16_example_legacy.set Normal file

Binary file not shown.

276
evtReader.h Normal file
View File

@ -0,0 +1,276 @@
#ifndef EVTREADER_H
#define EVTREADER_H
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
#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

899
example.cpp Normal file
View File

@ -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 <chrono>
#include <cmath>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <thread>
#include <vector>
#include <args/args.hxx>
#include <nolhmann/json.hpp>
#include <pixie16/pixie16.h>
#include <unistd.h>
struct LOG {
explicit LOG(const std::string& type) {
type_ = type;
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::chrono::milliseconds now2 =
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
char timeBuffer[80];
std::strftime(timeBuffer, 80, "%FT%T", gmtime(&currentTime));
std::stringstream tmp;
tmp << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << "Z";
datetime_ = tmp.str();
}
friend std::ostream& operator<<(std::ostream& os, const LOG& log) {
os << log.datetime_ << " - " << log.type_ << " - ";
return os;
}
std::string type_;
std::string datetime_;
};
struct module_config {
unsigned short slot;
unsigned short number;
std::string com_fpga_config;
std::string sp_fpga_config;
std::string dsp_code;
std::string dsp_par;
std::string dsp_var;
};
typedef std::vector<module_config> module_configs;
struct configuration {
module_configs modules;
std::vector<unsigned short> slot_def;
unsigned short num_modules() const {
return static_cast<unsigned short>(modules.size());
}
};
std::string generate_filename(const unsigned int& module_number, const std::string& type,
const std::string& ext) {
#ifndef LEGACY_EXAMPLE
static const std::string file_prefix = "pixie16api-module";
#else
static const std::string file_prefix = "pixie16app-module";
#endif
return file_prefix + std::to_string(module_number) + "-" + type + "." + ext;
}
void verify_json_module(const nlohmann::json& mod) {
if (!mod.contains("slot")) {
throw std::invalid_argument("Missing slot definition in configuration element.");
}
if (!mod.contains("dsp")) {
throw std::invalid_argument("Missing dsp object in configuration element.");
}
if (!mod["dsp"].contains("ldr") || !mod["dsp"].contains("var") || !mod["dsp"].contains("par")) {
throw std::invalid_argument(
"Missing dsp object in configuration element: ldr, dsp, or par.");
}
if (!mod.contains("fpga")) {
throw std::invalid_argument("Missing fpga object in configuration element.");
}
if (!mod["fpga"].contains("fippi") || !mod["fpga"].contains("sys")) {
throw std::invalid_argument("Missing fpga firmware definition (fippi or sys).");
}
}
void read_config(const std::string& config_file_name, configuration& cfg) {
std::ifstream input(config_file_name, std::ios::in);
if (input.fail()) {
throw std::ios_base::failure("open: " + config_file_name + ": " + std::strerror(errno));
}
nlohmann::json jf = nlohmann::json::parse(input);
input.close();
if (jf.empty() || jf.size() > SYS_MAX_NUM_MODULES) {
throw std::invalid_argument("invalid number of modules");
}
cfg.slot_def.clear();
for (const auto& module : jf) {
verify_json_module(module);
cfg.slot_def.push_back(module["slot"]);
module_config mod_cfg;
mod_cfg.slot = module["slot"];
mod_cfg.number = static_cast<unsigned short>(cfg.slot_def.size() - 1);
mod_cfg.com_fpga_config = module["fpga"]["sys"];
mod_cfg.sp_fpga_config = module["fpga"]["fippi"];
mod_cfg.dsp_code = module["dsp"]["ldr"];
mod_cfg.dsp_par = module["dsp"]["par"];
mod_cfg.dsp_var = module["dsp"]["var"];
cfg.modules.push_back(mod_cfg);
}
}
bool verify_api_return_value(const int& val, const std::string& func_name,
const bool& print_success = true) {
if (val < 0) {
std::cout << LOG("ERROR") << func_name << " failed with Error Code " << val << std::endl;
return false;
}
if (print_success)
std::cout << LOG("INFO") << func_name << " finished successfully." << std::endl;
return true;
}
bool output_statistics_data(const unsigned short& mod_num, const std::string& type) {
#ifndef LEGACY_EXAMPLE
std::vector<unsigned int> stats(Pixie16GetStatisticsSize(), 0);
#else
std::vector<unsigned int> stats(N_DSP_PAR - DSP_IO_BORDER, 0);
#endif
if (!verify_api_return_value(Pixie16ReadStatisticsFromModule(stats.data(), mod_num),
"Pixie16ReadStatisticsFromModule", false))
return false;
std::ofstream bin_output(generate_filename(mod_num, type, "bin"),
std::ios::binary | std::ios::out);
bin_output.write(reinterpret_cast<char*>(stats.data()), sizeof(unsigned int) * stats.size());
bin_output.close();
std::ofstream csv_output(generate_filename(mod_num, type, "csv"), std::ios::out);
csv_output << "channel,real_time,live_time,input_count_rate,output_count_rate" << std::endl;
auto real_time = Pixie16ComputeRealTime(stats.data(), mod_num);
std::cout << LOG("INFO") << "Begin Statistics for Module " << mod_num << std::endl;
std::cout << LOG("INFO") << "Real Time: " << real_time << std::endl;
for (unsigned int chan = 0; chan < NUMBER_OF_CHANNELS; chan++) {
auto live_time = Pixie16ComputeLiveTime(stats.data(), mod_num, chan);
auto icr = Pixie16ComputeInputCountRate(stats.data(), mod_num, chan);
auto ocr = Pixie16ComputeOutputCountRate(stats.data(), mod_num, chan);
std::cout << LOG("INFO") << "Channel " << chan << " LiveTime: " << live_time << std::endl;
std::cout << LOG("INFO") << "Channel " << chan << " Input Count Rate: " << icr << std::endl;
std::cout << LOG("INFO") << "Channel " << chan << " Output Count Rate: " << ocr
<< std::endl;
csv_output << chan << "," << real_time << "," << live_time << "," << icr << "," << ocr
<< std::endl;
}
std::cout << LOG("INFO") << "End Statistics for Module " << mod_num << std::endl;
csv_output.close();
return true;
}
bool save_dsp_pars(const std::string& filename) {
std::cout << LOG("INFO") << "Saving DSP Parameters to " << filename << "." << std::endl;
if (!verify_api_return_value(Pixie16SaveDSPParametersToFile(filename.c_str()),
"Pixie16SaveDSPParametersToFile"))
return false;
return true;
}
bool execute_adjust_offsets(const module_config& module) {
std::cout << LOG("INFO") << "Adjusting baseline offset for Module " << module.number << "."
<< std::endl;
if (!verify_api_return_value(Pixie16AdjustOffsets(module.number),
"Pixie16AdjustOffsets for Module " +
std::to_string(module.number)))
return false;
if (!save_dsp_pars(module.dsp_par))
return false;
return true;
}
bool execute_baseline_capture(const unsigned short& module_number) {
std::cout << LOG("INFO") << "Starting baseline capture for Module " << module_number
<< std::endl;
if (!verify_api_return_value(Pixie16AcquireBaselines(module_number), "Pixie16AcquireBaselines"))
return false;
double baselines[NUMBER_OF_CHANNELS][MAX_NUM_BASELINES];
double timestamps[MAX_NUM_BASELINES];
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
std::cout << LOG("INFO") << "Acquiring baselines for Channel " << i << std::endl;
if (!verify_api_return_value(Pixie16ReadSglChanBaselines(baselines[i], timestamps,
MAX_NUM_BASELINES, module_number,
i),
"Pixie16ReadsglChanBaselines"))
return false;
}
std::ofstream ofstream1(generate_filename(module_number, "baselines", "csv"));
ofstream1 << "bin,timestamp,";
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
if (i != NUMBER_OF_CHANNELS - 1)
ofstream1 << "Chan" << i << ",";
else
ofstream1 << "Chan" << i;
}
ofstream1 << std::endl;
for (unsigned int i = 0; i < MAX_NUM_BASELINES; i++) {
ofstream1 << i << "," << timestamps[i] << ",";
for (unsigned int k = 0; k < NUMBER_OF_CHANNELS; k++) {
if (k != NUMBER_OF_CHANNELS - 1)
ofstream1 << baselines[k][i] << ",";
else
ofstream1 << baselines[k][i];
}
ofstream1 << std::endl;
}
return true;
}
bool execute_list_mode_run(const configuration& cfg, const double& runtime_in_seconds) {
std::cout << LOG("INFO") << "Starting list mode data run for " << runtime_in_seconds << " s."
<< std::endl;
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write SYNCH_WAIT = 1 in Module 0."
<< std::endl;
if (!verify_api_return_value(Pixie16WriteSglModPar("SYNCH_WAIT", 1, 0),
"Pixie16WriteSglModPar - SYNC_WAIT"))
return false;
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write IN_SYNCH = 0 in Module 0."
<< std::endl;
if (!verify_api_return_value(Pixie16WriteSglModPar("IN_SYNCH", 0, 0),
"Pixie16WriteSglModPar - IN_SYNC"))
return false;
std::cout << LOG("INFO") << "Calling Pixie16StartListModeRun." << std::endl;
if (!verify_api_return_value(Pixie16StartListModeRun(cfg.num_modules(), LIST_MODE_RUN, NEW_RUN),
"Pixie16StartListModeRun"))
return false;
std::vector<std::ofstream*> output_streams(cfg.num_modules());
for (unsigned short i = 0; i < cfg.num_modules(); i++) {
output_streams[i] = new std::ofstream(generate_filename(i, "list-mode", "bin"),
std::ios::out | std::ios::binary);
}
std::vector<uint32_t> data(EXTERNAL_FIFO_LENGTH, 0);
unsigned int num_fifo_words = 0;
std::cout << LOG("INFO") << "Collecting data for " << runtime_in_seconds << " s." << std::endl;
std::chrono::steady_clock::time_point run_start_time = std::chrono::steady_clock::now();
while (std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::steady_clock::now() - run_start_time)
.count() < runtime_in_seconds) {
for (unsigned short mod_num = 0; mod_num < cfg.num_modules(); mod_num++) {
if (Pixie16CheckRunStatus(mod_num) == 1) {
if (!verify_api_return_value(
Pixie16CheckExternalFIFOStatus(&num_fifo_words, mod_num),
"Pixie16CheckExternalFIFOStatus", false))
return false;
if (double(num_fifo_words) / EXTERNAL_FIFO_LENGTH > 0.2) {
std::cout << LOG("INFO") << "External FIFO has " << num_fifo_words << " words."
<< std::endl;
if (!verify_api_return_value(
Pixie16ReadDataFromExternalFIFO(data.data(), num_fifo_words, mod_num),
"Pixie16ReadDataFromExternalFIFO", false))
return false;
output_streams[mod_num]->write(reinterpret_cast<char*>(data.data()),
num_fifo_words * sizeof(uint32_t));
} else {
continue;
}
} else {
std::cout << LOG("INFO") << "Module " << mod_num << " has no active run!"
<< std::endl;
}
}
/*
Check the run status of the Director module (module #0) to see if the run has been stopped.
This is possible in a multi-chassis system where modules in one chassis can stop the run
in all chassis.
*/
if (Pixie16CheckRunStatus(0) == 0) {
std::cout << LOG("INFO")
<< "Run was stopped by the director module. Stopping data collection."
<< std::endl;
break;
}
}
/*
Stop run in the Director module (module #0) - a SYNC interrupt should be generated
to stop run in all modules simultaneously
*/
std::cout << LOG("INFO") << "Stopping List Mode Run." << std::endl;
if (!verify_api_return_value(Pixie16EndRun(0), "Pixie16EndRun"))
return false;
std::cout << LOG("INFO") << "Checking that the run is finalized in all the modules."
<< std::endl;
bool all_modules_finished = false;
const unsigned int max_finalize_attempts = 50;
for (unsigned int counter = 0; counter < max_finalize_attempts; counter++) {
for (unsigned short k = 0; k < cfg.num_modules(); k++) {
if (Pixie16CheckRunStatus(k) == 1) {
all_modules_finished = false;
} else {
all_modules_finished = true;
}
}
if (all_modules_finished) {
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if (!all_modules_finished) {
std::cout << LOG("ERROR") << "All modules did not stop their runs properly!" << std::endl;
return false;
}
std::cout << LOG("INFO") << "List-mode run finished in "
<< std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::steady_clock::now() - run_start_time)
.count()
<< " s" << std::endl;
std::cout << LOG("INFO")
<< "Reading the final words from the External FIFO and the run statistics."
<< std::endl;
for (unsigned short mod_num = 0; mod_num < cfg.num_modules(); mod_num++) {
if (!verify_api_return_value(Pixie16CheckExternalFIFOStatus(&num_fifo_words, mod_num),
"Pixie16CheckExternalFIFOStatus", false))
return false;
if (num_fifo_words > 0) {
std::cout << LOG("INFO") << "External FIFO has " << num_fifo_words << " words."
<< std::endl;
if (!verify_api_return_value(
Pixie16ReadDataFromExternalFIFO(data.data(), num_fifo_words, mod_num),
"Pixie16ReadDataFromExternalFIFO", false))
return false;
output_streams[mod_num]->write(reinterpret_cast<char*>(data.data()),
num_fifo_words * sizeof(uint32_t));
}
if (!output_statistics_data(mod_num, "list-mode-stats")) {
return false;
}
}
return true;
}
bool execute_mca_run(const unsigned int& mod, const double& runtime_in_seconds) {
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write HOST_RT_PRESET to "
<< runtime_in_seconds << std::endl;
if (!verify_api_return_value(
Pixie16WriteSglModPar("HOST_RT_PRESET", Decimal2IEEEFloating(runtime_in_seconds), mod),
"Pixie16WriteSglModPar - HOST_RT_PRESET"))
return false;
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to write SYNCH_WAIT = 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::duration<double>>(
std::chrono::steady_clock::now() - run_start_time)
.count() < runtime_in_seconds) {
//do nothing
}
std::cout << LOG("INFO") << "Stopping MCA data run after "
<< std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::steady_clock::now() - run_start_time)
.count()
<< " s." << std::endl;
if (!verify_api_return_value(Pixie16EndRun(mod), "Pixie16EndRun"))
return false;
std::string name = generate_filename(mod, "mca", "csv");
std::ofstream out(name);
out << "bin,";
std::vector<std::vector<uint32_t>> hists;
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
std::vector<uint32_t> hist(MAX_HISTOGRAM_LENGTH, 0);
Pixie16ReadHistogramFromModule(hist.data(), MAX_HISTOGRAM_LENGTH, mod, i);
hists.push_back(hist);
if (i < NUMBER_OF_CHANNELS - 1)
out << "Chan" << i << ",";
else
out << "Chan" << i;
}
out << std::endl;
for (unsigned int bin = 0; bin < MAX_HISTOGRAM_LENGTH; bin++) {
out << bin << ",";
for (auto& hist : hists) {
if (&hist != &hists.back())
out << hist[bin] << ",";
else
out << hist[bin];
}
out << std::endl;
}
if (!output_statistics_data(mod, "mca-stats")) {
return false;
}
return true;
}
bool execute_parameter_read(args::ValueFlag<std::string>& parameter,
args::ValueFlag<unsigned int>& crate,
args::ValueFlag<unsigned int>& module,
args::ValueFlag<unsigned int>& channel) {
if (channel) {
double result;
std::cout << LOG("INFO") << "Pixie16ReadSglChanPar"
<< " reading " << parameter.Get() << " from Crate " << crate.Get() << " Module "
<< module.Get() << " Channel " << channel.Get() << "." << std::endl;
if (!verify_api_return_value(Pixie16ReadSglChanPar(parameter.Get().c_str(), &result,
module.Get(), channel.Get()),
"Pixie16ReadSglChanPar", false))
return false;
std::cout << LOG("INFO") << result << std::endl;
} else {
unsigned int result;
std::cout << LOG("INFO") << "Pixie16ReadSglModPar reading " << parameter.Get()
<< " from Crate " << crate.Get() << " Module " << module.Get() << "."
<< std::endl;
if (!verify_api_return_value(
Pixie16ReadSglModPar(parameter.Get().c_str(), &result, module.Get()),
"Pixie16ReadSglModPar", false))
return false;
std::cout << LOG("INFO") << result << std::endl;
}
return true;
}
bool execute_parameter_write(args::ValueFlag<std::string>& parameter,
args::ValueFlag<double>& value, args::ValueFlag<unsigned int>& crate,
const module_config& module, args::ValueFlag<unsigned int>& channel) {
if (channel) {
std::cout << LOG("INFO") << "Pixie16WriteSglChanPar setting " << parameter.Get() << " to "
<< value.Get() << " for Crate " << crate.Get() << " Module " << module.number
<< " Channel " << channel.Get() << "." << std::endl;
if (!verify_api_return_value(Pixie16WriteSglChanPar(parameter.Get().c_str(), value.Get(),
module.number, channel.Get()),
"Pixie16WriteSglChanPar"))
return false;
} else {
std::cout << LOG("INFO") << "Pixie16WriteSglModPar"
<< " setting " << parameter.Get() << " to " << value.Get() << " for Crate "
<< crate.Get() << " Module " << module.number << "." << std::endl;
if (!verify_api_return_value(
Pixie16WriteSglModPar(parameter.Get().c_str(), value, module.number),
"Pixie16WriteSglModPar"))
return false;
}
if (!save_dsp_pars(module.dsp_par))
return false;
return true;
}
bool execute_trace_capture(const unsigned short& module_number) {
std::cout << LOG("INFO") << "Pixie16AcquireADCTrace acquiring traces for Module "
<< module_number << "." << std::endl;
if (!verify_api_return_value(Pixie16AcquireADCTrace(module_number), "Pixie16AcquireADCTrace"))
return false;
unsigned short trace[NUMBER_OF_CHANNELS][MAX_ADC_TRACE_LEN];
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
if (!verify_api_return_value(
Pixie16ReadSglChanADCTrace(trace[i], MAX_ADC_TRACE_LEN, module_number, i),
"Pixie16AcquireADCTrace", false))
return false;
}
std::ofstream ofstream1(generate_filename(module_number, "adc", "csv"));
ofstream1 << "bin,";
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
if (i != NUMBER_OF_CHANNELS - 1)
ofstream1 << "Chan" << i << ",";
else
ofstream1 << "Chan" << i;
}
ofstream1 << std::endl;
for (unsigned int i = 0; i < MAX_ADC_TRACE_LEN; i++) {
ofstream1 << i << ",";
for (unsigned int k = 0; k < NUMBER_OF_CHANNELS; k++) {
if (k != NUMBER_OF_CHANNELS - 1)
ofstream1 << trace[k][i] << ",";
else
ofstream1 << trace[k][i];
}
ofstream1 << std::endl;
}
return true;
}
bool execute_blcut(args::ValueFlag<unsigned int>& module, args::ValueFlag<unsigned int>& channel) {
if (!module)
return false;
std::cout << LOG("INFO") << "Executing Pixie16BLcutFinder for Module" << module.Get() << "."
<< std::endl;
unsigned int blcut = 0;
if (!verify_api_return_value(Pixie16BLcutFinder(module.Get(), channel.Get(), &blcut),
"Pixie16BLcutFinder", false))
return false;
std::cout << LOG("INFO") << "BLCut for Module " << module.Get() << " Channel " << channel.Get()
<< " is " << blcut << std::endl;
return true;
}
bool execute_set_dacs(args::ValueFlag<unsigned int>& module) {
if (!module)
return false;
std::cout << LOG("INFO") << "Executing Pixie16SetDACs for Module" << module.Get() << "."
<< std::endl;
if (!verify_api_return_value(Pixie16SetDACs(module.Get()), "Pixie16SetDACs", false))
return false;
return true;
}
bool execute_close_module_connection(const int& numModules) {
std::cout << LOG("INFO") << "Closing out connection to Modules." << std::endl;
verify_api_return_value(Pixie16ExitSystem(numModules),"Pixie16ExitSystem");
return true;
}
double calculate_duration_in_seconds(const std::chrono::system_clock::time_point& start,
const std::chrono::system_clock::time_point& end) {
return std::chrono::duration<double>(end - start).count();
}
void output_module_info(const configuration& cfg) {
unsigned short rev;
unsigned int serial_number;
unsigned short adc_bits;
unsigned short adc_msps;
for (const auto& mod : cfg.modules) {
if (!verify_api_return_value(
Pixie16ReadModuleInfo(mod.number, &rev, &serial_number, &adc_bits, &adc_msps),
"Pixie16ReadModuleInfo", false))
throw std::runtime_error("Could not get module information for Module " +
std::to_string(mod.number));
std::cout << LOG("INFO") << "Begin module information for Module " << mod.number
<< std::endl;
std::cout << LOG("INFO") << "Serial Number: " << serial_number << std::endl;
std::cout << LOG("INFO") << "Revision: " << rev << std::endl;
std::cout << LOG("INFO") << "ADC Bits: " << adc_bits << std::endl;
std::cout << LOG("INFO") << "ADC MSPS: " << adc_msps << std::endl;
std::cout << LOG("INFO") << "End module information for Module " << mod.number << std::endl;
}
}
int main(int argc, char** argv) {
auto start = std::chrono::system_clock::now();
args::ArgumentParser parser(
"Sample code that interfaces with a Pixie system through the User API.");
parser.LongSeparator("=");
args::Group commands(parser, "commands");
args::Command boot(commands, "boot", "Boots the crate of modules.");
args::Command copy(commands, "copy", "Copies DSP parameters from source to destination.");
args::Command export_settings(
commands, "export-settings",
"Boots the system and dumps the settings to the file defined in the config.");
args::Command histogram(commands, "histogram", "Save histograms from the module.");
args::Command init(commands, "init", "Initializes the system without going any farther.");
args::Command list_mode(commands, "list-mode", "Starts a list mode data run");
args::Command read(commands, "read", "Read a parameter from the module.");
args::Command write(commands, "write", "Write a parameter to the module.");
args::Command trace(commands, "trace", "Captures traces from the modules.");
args::Command adjust_offsets(commands, "adjust_offsets",
"Adjusts the DC offsets for all modules in the config file.");
args::Command baseline(commands, "baseline", "Acquire and print baselines from the module");
args::Command mca(commands, "mca", "Starts an MCA data run.");
args::Command blcut(commands, "blcut",
"Starts a control task to find the BLCut for a channel.");
args::Command dacs(commands, "dacs", "Starts a control task to set the module's DACs");
args::Command tau_finder(commands, "tau_finder",
"Executes the Tau Finder control task and returns the values.");
args::Group arguments(parser, "arguments", args::Group::Validators::AtLeastOne,
args::Options::Global);
args::ValueFlag<std::string> conf_flag(arguments, "cfg", "The configuration file to load.",
{'c', "config"}, args::Options::Required);
args::ValueFlag<std::string> additional_cfg_flag(
arguments, "cfg", "The configuration file to load.", {"additional-config"});
args::HelpFlag help_flag(arguments, "help", "Displays this message", {'h', "help"});
args::Flag is_fast_boot(boot, "fast-boot", "Performs a partial boot of the system.",
{'f', "fast-boot"});
args::Flag is_offline(arguments, "Offline Mode",
"Tells the API to use Offline mode when running.", {'o', "offline"});
args::ValueFlag<std::string> boot_pattern_flag(arguments, "boot_pattern",
"The boot pattern used for booting.",
{'b', "boot_pattern"}, "0x7F");
args::ValueFlag<double> run_time(
list_mode, "time", "The amount of time that a list mode run will take in seconds.",
{'t', "run-time"}, 10.);
args::ValueFlag<std::string> parameter(
arguments, "parameter", "The parameter we want to read from the system.", {'n', "name"});
args::ValueFlag<unsigned int> channel(arguments, "channel", "The channel to operate on.",
{"chan"});
args::ValueFlag<unsigned int> crate(arguments, "crate", "The crate", {"crate"}, 0);
args::ValueFlag<unsigned int> copy_mask(
copy, "copy_mask", "An integer representing the set of parameters to copy", {"copy-mask"});
args::ValueFlag<unsigned int> dest_mask(
copy, "dest_mask", "An integer representing the destination channels", {"dest-mask"});
args::ValueFlag<unsigned int> dest_channel(copy, "dest_channel",
"The channel that we'll copy to", {"dest-chan"});
args::ValueFlag<unsigned int> dest_module(copy, "dest_module", "The module that we'll copy to.",
{"dest-mod"});
args::ValueFlag<unsigned int> module(arguments, "module", "The module to operate on.", {"mod"});
args::ValueFlag<double> parameter_value(
write, "parameter_value", "The value of the parameter we want to write.", {'v', "value"});
adjust_offsets.Add(conf_flag);
adjust_offsets.Add(boot_pattern_flag);
adjust_offsets.Add(module);
baseline.Add(is_fast_boot);
baseline.Add(boot_pattern_flag);
baseline.Add(module);
blcut.Add(module);
blcut.Add(channel);
boot.Add(conf_flag);
boot.Add(boot_pattern_flag);
copy.Add(boot_pattern_flag);
copy.Add(module);
copy.Add(channel);
dacs.Add(module);
mca.Add(module);
mca.Add(boot_pattern_flag);
read.Add(conf_flag);
read.Add(crate);
read.Add(module);
read.Add(channel);
read.Add(parameter);
tau_finder.Add(module);
trace.Add(conf_flag);
trace.Add(module);
trace.Add(boot_pattern_flag);
write.Add(conf_flag);
write.Add(parameter);
write.Add(crate);
write.Add(module);
write.Add(channel);
try {
parser.ParseCLI(argc, argv);
} catch (args::Help& help) {
std::cout << LOG("INFO") << help.what() << std::endl;
std::cout << parser;
return EXIT_SUCCESS;
} catch (args::Error& e) {
std::cout << LOG("ERROR") << e.what() << std::endl;
std::cout << parser;
return EXIT_FAILURE;
}
configuration cfg;
try {
read_config(conf_flag.Get(), cfg);
} catch (std::exception& e) {
std::cout << LOG("ERROR") << e.what() << std::endl;
return EXIT_FAILURE;
}
std::cout << LOG("INFO") << "Finished reading config in "
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
<< std::endl;
int offline_mode = 0;
if (is_offline)
offline_mode = 1;
start = std::chrono::system_clock::now();
std::cout << LOG("INFO") << "Calling Pixie16InitSystem." << std::endl;
if (!verify_api_return_value(
Pixie16InitSystem(cfg.num_modules(), cfg.slot_def.data(), offline_mode),
"Pixie16InitSystem", false))
return EXIT_FAILURE;
std::cout << LOG("INFO") << "Finished Pixie16InitSystem in "
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
<< std::endl;
try {
output_module_info(cfg);
} catch (std::runtime_error& error) {
std::cout << LOG("ERROR") << error.what() << std::endl;
return EXIT_FAILURE;
}
if (init) {
execute_close_module_connection(cfg.num_modules());
return EXIT_SUCCESS;
}
unsigned int boot_pattern = stoul(args::get(boot_pattern_flag), nullptr, 0);
if (is_fast_boot || additional_cfg_flag)
boot_pattern = 0x70;
for (const auto& mod : cfg.modules) {
start = std::chrono::system_clock::now();
std::cout << LOG("INFO") << "Calling Pixie16BootModule for Module " << mod.number
<< " with boot pattern: " << std::showbase << std::hex << boot_pattern << std::dec
<< std::endl;
if (!verify_api_return_value(
Pixie16BootModule(mod.com_fpga_config.c_str(), mod.sp_fpga_config.c_str(), nullptr,
mod.dsp_code.c_str(), mod.dsp_par.c_str(), mod.dsp_var.c_str(),
mod.number, boot_pattern),
"Pixie16BootModule", "Finished booting!"))
return EXIT_FAILURE;
std::cout << LOG("INFO") << "Finished Pixie16BootModule for Module " << mod.number << " in "
<< calculate_duration_in_seconds(start, std::chrono::system_clock::now()) << " s."
<< std::endl;
}
if (boot) {
execute_close_module_connection(cfg.num_modules());
return EXIT_SUCCESS;
}
if (additional_cfg_flag) {
if (!verify_api_return_value(
Pixie16LoadDSPParametersFromFile(additional_cfg_flag.Get().c_str()),
"Pixie16LoadDSPParametersFromFile", true))
return EXIT_FAILURE;
}
if (copy) {
if (!module || !channel || !copy_mask || !dest_channel || !dest_module) {
std::cout
<< LOG("ERROR")
<< "Pixie16CopyDSPParameters requires the source/destination module and channel "
"and the destination mask to execute!"
<< std::endl;
}
std::vector<unsigned short> dest_mask;
for(size_t mod = 0; mod < cfg.num_modules(); mod++) {
for(size_t chan = 0; chan < NUMBER_OF_CHANNELS; chan++) {
if (mod == dest_module.Get() && chan == dest_channel.Get())
dest_mask.push_back(1);
else
dest_mask.push_back(0);
}
}
if (!verify_api_return_value(
Pixie16CopyDSPParameters(copy_mask.Get(), module.Get(), channel.Get(), dest_mask.data()),
"Pixie16CopyDSPParameters", true)) {
return EXIT_FAILURE;
}
}
if (tau_finder) {
if (!module) {
std::cout << LOG("ERROR") << "Pixie16TauFinder requires the module flag to execute!"
<< std::endl;
}
std::vector<double> taus(NUMBER_OF_CHANNELS);
if (!verify_api_return_value(Pixie16TauFinder(module.Get(), taus.data()),
"Pixie16TauFinder", true)) {
return EXIT_FAILURE;
}
for (unsigned int i = 0; i < taus.size(); i++) {
std::cout << "Channel " << i << ": " << taus.at(i) << std::endl;
}
}
if (read) {
if (!execute_parameter_read(parameter, crate, module, channel))
return EXIT_FAILURE;
}
if (write) {
if (!execute_parameter_write(parameter, parameter_value, crate, cfg.modules[module.Get()],
channel))
return EXIT_FAILURE;
}
if (adjust_offsets) {
if (!execute_adjust_offsets(cfg.modules[module.Get()]))
return EXIT_FAILURE;
}
if (trace) {
if (!execute_trace_capture(module.Get()))
return EXIT_FAILURE;
}
if (list_mode) {
if (!execute_list_mode_run(cfg, run_time.Get()))
return EXIT_FAILURE;
}
if (export_settings) {
if (!save_dsp_pars(cfg.modules.front().dsp_par))
return EXIT_FAILURE;
}
if (baseline) {
if (!execute_baseline_capture(module.Get()))
return EXIT_FAILURE;
}
if (mca) {
if (!execute_mca_run(module.Get(), run_time.Get()))
return EXIT_FAILURE;
}
if (blcut) {
if (!execute_blcut(module, channel))
return EXIT_FAILURE;
}
if (dacs) {
if (!execute_set_dacs(module))
return EXIT_FAILURE;
}
execute_close_module_connection(cfg.num_modules());
return EXIT_SUCCESS;
}

15
example_config.json Normal file
View File

@ -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"
}
}
]

105
pxisys.ini Normal file
View File

@ -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

BIN
read-set Executable file

Binary file not shown.

50
read-set.c Normal file
View File

@ -0,0 +1,50 @@
/**********************************************************/
/* Read PXI Set File -- J.M. Allmond (ORNL) -- July 2016 */
/**********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#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;
}

273
test.cpp Normal file
View File

@ -0,0 +1,273 @@
//*.h are C header
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <bitset>
#include <unistd.h>
#include <limits.h>
#include <ctime>
#include <sys/time.h> /* struct timeval, select() */
#include <termios.h> /* 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);
}

1091
test_ryan.set Normal file

File diff suppressed because it is too large Load Diff