use libPixie16Api.so, can change setting, try to understand the collected data
This commit is contained in:
commit
9a302c631b
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
*.o
|
||||||
|
*.log
|
||||||
|
*.bin
|
||||||
|
*.csv
|
||||||
|
*.gch
|
||||||
|
|
||||||
|
test
|
||||||
|
example
|
95
DataBlock.h
Normal file
95
DataBlock.h
Normal 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
53
Makefile
Normal 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
605
Pixie16Class.cpp
Normal 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
162
Pixie16Class.h
Normal 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
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
BIN
Pixie16_example_legacy.set
Normal file
Binary file not shown.
276
evtReader.h
Normal file
276
evtReader.h
Normal 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
899
example.cpp
Normal 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(¤tTime));
|
||||||
|
|
||||||
|
std::stringstream tmp;
|
||||||
|
tmp << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << "Z";
|
||||||
|
|
||||||
|
datetime_ = tmp.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const LOG& log) {
|
||||||
|
os << log.datetime_ << " - " << log.type_ << " - ";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string type_;
|
||||||
|
std::string datetime_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct module_config {
|
||||||
|
unsigned short slot;
|
||||||
|
unsigned short number;
|
||||||
|
std::string com_fpga_config;
|
||||||
|
std::string sp_fpga_config;
|
||||||
|
std::string dsp_code;
|
||||||
|
std::string dsp_par;
|
||||||
|
std::string dsp_var;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<module_config> module_configs;
|
||||||
|
|
||||||
|
struct configuration {
|
||||||
|
module_configs modules;
|
||||||
|
std::vector<unsigned short> slot_def;
|
||||||
|
unsigned short num_modules() const {
|
||||||
|
return static_cast<unsigned short>(modules.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string generate_filename(const unsigned int& module_number, const std::string& type,
|
||||||
|
const std::string& ext) {
|
||||||
|
#ifndef LEGACY_EXAMPLE
|
||||||
|
static const std::string file_prefix = "pixie16api-module";
|
||||||
|
#else
|
||||||
|
static const std::string file_prefix = "pixie16app-module";
|
||||||
|
#endif
|
||||||
|
return file_prefix + std::to_string(module_number) + "-" + type + "." + ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void verify_json_module(const nlohmann::json& mod) {
|
||||||
|
if (!mod.contains("slot")) {
|
||||||
|
throw std::invalid_argument("Missing slot definition in configuration element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mod.contains("dsp")) {
|
||||||
|
throw std::invalid_argument("Missing dsp object in configuration element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mod["dsp"].contains("ldr") || !mod["dsp"].contains("var") || !mod["dsp"].contains("par")) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"Missing dsp object in configuration element: ldr, dsp, or par.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mod.contains("fpga")) {
|
||||||
|
throw std::invalid_argument("Missing fpga object in configuration element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mod["fpga"].contains("fippi") || !mod["fpga"].contains("sys")) {
|
||||||
|
throw std::invalid_argument("Missing fpga firmware definition (fippi or sys).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_config(const std::string& config_file_name, configuration& cfg) {
|
||||||
|
std::ifstream input(config_file_name, std::ios::in);
|
||||||
|
if (input.fail()) {
|
||||||
|
throw std::ios_base::failure("open: " + config_file_name + ": " + std::strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json jf = nlohmann::json::parse(input);
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
if (jf.empty() || jf.size() > SYS_MAX_NUM_MODULES) {
|
||||||
|
throw std::invalid_argument("invalid number of modules");
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.slot_def.clear();
|
||||||
|
for (const auto& module : jf) {
|
||||||
|
verify_json_module(module);
|
||||||
|
|
||||||
|
cfg.slot_def.push_back(module["slot"]);
|
||||||
|
|
||||||
|
module_config mod_cfg;
|
||||||
|
mod_cfg.slot = module["slot"];
|
||||||
|
mod_cfg.number = static_cast<unsigned short>(cfg.slot_def.size() - 1);
|
||||||
|
mod_cfg.com_fpga_config = module["fpga"]["sys"];
|
||||||
|
mod_cfg.sp_fpga_config = module["fpga"]["fippi"];
|
||||||
|
mod_cfg.dsp_code = module["dsp"]["ldr"];
|
||||||
|
mod_cfg.dsp_par = module["dsp"]["par"];
|
||||||
|
mod_cfg.dsp_var = module["dsp"]["var"];
|
||||||
|
cfg.modules.push_back(mod_cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool verify_api_return_value(const int& val, const std::string& func_name,
|
||||||
|
const bool& print_success = true) {
|
||||||
|
if (val < 0) {
|
||||||
|
std::cout << LOG("ERROR") << func_name << " failed with Error Code " << val << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (print_success)
|
||||||
|
std::cout << LOG("INFO") << func_name << " finished successfully." << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool output_statistics_data(const unsigned short& mod_num, const std::string& type) {
|
||||||
|
#ifndef LEGACY_EXAMPLE
|
||||||
|
std::vector<unsigned int> stats(Pixie16GetStatisticsSize(), 0);
|
||||||
|
#else
|
||||||
|
std::vector<unsigned int> stats(N_DSP_PAR - DSP_IO_BORDER, 0);
|
||||||
|
#endif
|
||||||
|
if (!verify_api_return_value(Pixie16ReadStatisticsFromModule(stats.data(), mod_num),
|
||||||
|
"Pixie16ReadStatisticsFromModule", false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::ofstream bin_output(generate_filename(mod_num, type, "bin"),
|
||||||
|
std::ios::binary | std::ios::out);
|
||||||
|
bin_output.write(reinterpret_cast<char*>(stats.data()), sizeof(unsigned int) * stats.size());
|
||||||
|
bin_output.close();
|
||||||
|
|
||||||
|
std::ofstream csv_output(generate_filename(mod_num, type, "csv"), std::ios::out);
|
||||||
|
csv_output << "channel,real_time,live_time,input_count_rate,output_count_rate" << std::endl;
|
||||||
|
|
||||||
|
auto real_time = Pixie16ComputeRealTime(stats.data(), mod_num);
|
||||||
|
|
||||||
|
std::cout << LOG("INFO") << "Begin Statistics for Module " << mod_num << std::endl;
|
||||||
|
std::cout << LOG("INFO") << "Real Time: " << real_time << std::endl;
|
||||||
|
for (unsigned int chan = 0; chan < NUMBER_OF_CHANNELS; chan++) {
|
||||||
|
auto live_time = Pixie16ComputeLiveTime(stats.data(), mod_num, chan);
|
||||||
|
auto icr = Pixie16ComputeInputCountRate(stats.data(), mod_num, chan);
|
||||||
|
auto ocr = Pixie16ComputeOutputCountRate(stats.data(), mod_num, chan);
|
||||||
|
|
||||||
|
std::cout << LOG("INFO") << "Channel " << chan << " LiveTime: " << live_time << std::endl;
|
||||||
|
std::cout << LOG("INFO") << "Channel " << chan << " Input Count Rate: " << icr << std::endl;
|
||||||
|
std::cout << LOG("INFO") << "Channel " << chan << " Output Count Rate: " << ocr
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
csv_output << chan << "," << real_time << "," << live_time << "," << icr << "," << ocr
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
std::cout << LOG("INFO") << "End Statistics for Module " << mod_num << std::endl;
|
||||||
|
csv_output.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool save_dsp_pars(const std::string& filename) {
|
||||||
|
std::cout << LOG("INFO") << "Saving DSP Parameters to " << filename << "." << std::endl;
|
||||||
|
if (!verify_api_return_value(Pixie16SaveDSPParametersToFile(filename.c_str()),
|
||||||
|
"Pixie16SaveDSPParametersToFile"))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute_adjust_offsets(const module_config& module) {
|
||||||
|
std::cout << LOG("INFO") << "Adjusting baseline offset for Module " << module.number << "."
|
||||||
|
<< std::endl;
|
||||||
|
if (!verify_api_return_value(Pixie16AdjustOffsets(module.number),
|
||||||
|
"Pixie16AdjustOffsets for Module " +
|
||||||
|
std::to_string(module.number)))
|
||||||
|
return false;
|
||||||
|
if (!save_dsp_pars(module.dsp_par))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute_baseline_capture(const unsigned short& module_number) {
|
||||||
|
std::cout << LOG("INFO") << "Starting baseline capture for Module " << module_number
|
||||||
|
<< std::endl;
|
||||||
|
if (!verify_api_return_value(Pixie16AcquireBaselines(module_number), "Pixie16AcquireBaselines"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double baselines[NUMBER_OF_CHANNELS][MAX_NUM_BASELINES];
|
||||||
|
double timestamps[MAX_NUM_BASELINES];
|
||||||
|
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||||
|
std::cout << LOG("INFO") << "Acquiring baselines for Channel " << i << std::endl;
|
||||||
|
if (!verify_api_return_value(Pixie16ReadSglChanBaselines(baselines[i], timestamps,
|
||||||
|
MAX_NUM_BASELINES, module_number,
|
||||||
|
i),
|
||||||
|
"Pixie16ReadsglChanBaselines"))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream ofstream1(generate_filename(module_number, "baselines", "csv"));
|
||||||
|
ofstream1 << "bin,timestamp,";
|
||||||
|
for (unsigned int i = 0; i < NUMBER_OF_CHANNELS; i++) {
|
||||||
|
if (i != NUMBER_OF_CHANNELS - 1)
|
||||||
|
ofstream1 << "Chan" << i << ",";
|
||||||
|
else
|
||||||
|
ofstream1 << "Chan" << i;
|
||||||
|
}
|
||||||
|
ofstream1 << std::endl;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < MAX_NUM_BASELINES; i++) {
|
||||||
|
ofstream1 << i << "," << timestamps[i] << ",";
|
||||||
|
for (unsigned int k = 0; k < NUMBER_OF_CHANNELS; k++) {
|
||||||
|
if (k != NUMBER_OF_CHANNELS - 1)
|
||||||
|
ofstream1 << baselines[k][i] << ",";
|
||||||
|
else
|
||||||
|
ofstream1 << baselines[k][i];
|
||||||
|
}
|
||||||
|
ofstream1 << std::endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool execute_list_mode_run(const configuration& cfg, const double& runtime_in_seconds) {
|
||||||
|
std::cout << LOG("INFO") << "Starting list mode data run for " << runtime_in_seconds << " s."
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::cout << LOG("INFO") << "Calling Pixie16WriteSglModPar to 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
15
example_config.json
Normal 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
105
pxisys.ini
Normal 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
|
||||||
|
|
||||||
|
|
50
read-set.c
Normal file
50
read-set.c
Normal 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
273
test.cpp
Normal 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
1091
test_ryan.set
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user