HITDAQ/hit2023v2/hitreader.h

442 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//This is an object interface for reading HIT data files
//See HIT documentation for details and examples.
/*
THIS DOESN'T WORK!
.L hitreader.c
Hitdata data;
data.read(“my_file.da2”); //to load whole file at once forget it! See below.
data.read(“my_file.da2”,1000,100,10) //to read 100 frames starting from frame 1000 and incrementing by 10 (i.e. frame 1000, 1010, 1020, ... 1990 will be read)
//Reading 10 000 frames is reasonable. Reading 100 000 frames made my VM beg for memory.
data.nrFrames //to see how many frames you have
data.frames[0].nrBoards //to see how many boards you had in the system
data.frames[0].boards[0].nrChannels //to see how many channels you have in board 0
data.frames[10].boards[0].data[100] //get signal value for frame 10, board 0, channel 100
data.frames[10].boards[0].syncframe.local_ctr //get the local synchro counter for frame 10, board 0
//same for .global_ctr, .sma_state, .dummy, .device_nr, .data_ok
*/
//*********************** Helper *************************
#include <fstream>
#include <iostream>
using namespace std;
//#define debug(str) std::cout << "HIT DEBUG: " << str << endl;
#define debug(str)
//*********************** Syncframe *************************
class Syncframe
{
public:
Syncframe()
{
debug("Syncframe()");
local_ctr = global_ctr = 0;
sma_state = dummy = 0;
device_nr = -1;
data_ok = 0;
};
~Syncframe()
{
debug("~Syncframe()");
};
int sizeInFile()
{
return 16;
};
int read(std::ifstream* file)
{
char buffer[16];
file->read(buffer,16);
if (file->fail())
return 0;
local_ctr = *(unsigned short*)(buffer+0);
global_ctr = *(unsigned short*)(buffer+2);
sma_state = *(unsigned short*)(buffer+4);
dummy = *(unsigned short*)(buffer+6);
device_nr = *(int*)(buffer+8);
data_ok = *(int*)(buffer+12);
// std::cout << "Syncframe:" << local_ctr << " " << global_ctr << " " << sma_state << " " << dummy << " " << device_nr << " " << data_ok << std::endl;
return 1;
};
unsigned short local_ctr;
unsigned short global_ctr;
unsigned short sma_state;
unsigned short dummy;
int device_nr;
unsigned int data_ok;
};
//*********************** Sensorframe *************************
class Boardframe
{
public:
Boardframe(int nr_channels = 0)
{
debug("Boardframe()");
data = NULL;
resize (nr_channels);
};
Boardframe(const Boardframe& in)
{
debug("Boardframe(Boardframe&)");
data = NULL;
resize(in.nrChannels);
for (int i = 0; i < nrChannels; i++)
data[i] = in.data[i];
syncframe = in.syncframe;
};
Boardframe& operator=(const Boardframe& in)
{
debug("Boardframe::operator==");
resize(in.nrChannels);//creates an array called data of length nrChannels
for (int i = 0; i < nrChannels; i++)
data[i] = in.data[i];
syncframe = in.syncframe;
return *this;
};
~Boardframe()
{
debug("~Boardframe()");
if (data)
delete[] data;
};
void resize(int nr_channels)
{
if (data)
delete[] data;
nrChannels = nr_channels;
if (nrChannels)
data = new unsigned short[nrChannels];
else
data = NULL;
};
int sizeInFile()
{
// std::cout << "boardframe.sizeInFile() = " << syncframe.sizeInFile() + nrChannels*2 << std::endl;
return syncframe.sizeInFile() + nrChannels*2;
};
int read(std::ifstream* file)
{
if (syncframe.read(file) == 0)//get the syncframe before the board data
return 0;
//I must be already resized at this point!
file->read((char*)data,2*nrChannels);
if (file->fail())
return 0;
// std::cout<< "data[" << nrChannels << "]: ";
// for (int i = 0;i<nrChannels;i++) std::cout << data[i] << " ";
// std::cout << std::endl;
return 1;
};
unsigned short& operator[] (int index)
{
return data[index];
};
Syncframe syncframe;
int nrChannels;
unsigned short* data;
};
//*********************** Fullframe *************************
class Fullframe
{
public:
Fullframe(int nr_boards = 0)
{
debug("Fullframe()");
boards = NULL;
resize(nr_boards);
};
Fullframe(const Fullframe& in)
{
debug("Fullframe(Fullframe&)");
boards = NULL;
resize(in.nrBoards);
for (int i = 0; i < nrBoards; i++)
boards[i] = in.boards[i];
};
Fullframe& operator=(const Fullframe& in)
{
debug("Fullframe::operator==");
resize(in.nrBoards);
for (int i = 0; i < nrBoards; i++)
boards[i] = in.boards[i];
return *this;
};
~Fullframe()
{
debug("~Fullframe()");
if (boards)
delete[] boards;
};
void resize (int nr_boards)
{
if (boards)
delete[] boards;
nrBoards = nr_boards;
if (nrBoards)
boards = new Boardframe[nrBoards];
else
boards = NULL;
}
int sizeInFile()
{
if (boards){
// std::cout << "Fullframe.sizeInFile() = " << 2 + nrBoards*2 + nrBoards * boards[0].sizeInFile() << std::endl;
// return 2 + nrBoards*2 + nrBoards * boards[0].sizeInFile();
//// boards[0].sizeInFile() returns 656 for every board...
return 2 + 4*2 + (16 + 320 * 2) + (16 + 128*2)*3; //1482
}
else
return 0; //no boards, makes no sense...
};
int read(std::ifstream* file)
{
//Read number of boards
unsigned short nr_boards;
file->read((char*)&nr_boards,2);
if(file->fail()){
std::cerr << "File read failed." << std::endl;
return 0;
}
if (nr_boards!=4){
std::cerr << "Unrealistic number(!=) of boards to be read:"<< nr_boards << std::endl;
std::cerr << "Will try to resync frame." << std::endl;
for (int j = 0;j<741;j++){
file->read((char*)&nr_boards,2);
if (nr_boards==4) break;
}
if ( nr_boards!=4){
std::cerr << "Resync failed." << std::endl;
return 0;
}
}
//std::cout << " nr_boards: " << nr_boards << std::endl;
//Read channel counts
unsigned short* channel_counts = new unsigned short[nr_boards];
file->read((char*)channel_counts,nr_boards*2);
if (file->fail())
{
delete[] channel_counts;
return 0;
}
//Read board frames
resize(nr_boards);
for (int board_nr = 0; board_nr < nr_boards; board_nr++)
{
// std::cout << " channel_counts[" << board_nr << "]: "<< channel_counts[board_nr] << std::endl;
boards[board_nr].resize(channel_counts[board_nr]);
if (boards[board_nr].read(file) == 0)//read the board
{
delete[] channel_counts;
return 0;
}
}
delete[] channel_counts;
return 1;
};
int nrChannels()
{
int result = 0;
for (int board_nr = 0; board_nr < nrBoards; board_nr++)
result += boards[board_nr].nrChannels;
return result;
};
unsigned short& operator[] (int index)
{
for (int board_nr = 0; board_nr < nrBoards; board_nr++)
{
if (index >= boards[board_nr].nrChannels)
index -= boards[board_nr].nrChannels;
else
return boards[board_nr][index];
}
std::cerr << " ### Fullframe::operator[]: index out of range!" << std::endl;
// return (*NULL); //this will cause crash (intended).
return boards[nrBoards][index];
};
int nrBoards;
Boardframe* boards;
};
//*********************** Hitdata *************************
class Hitdata
{
public:
Hitdata(int nr_frames = 0)
{
frames = NULL;
resize(nr_frames);
};
Hitdata(const Hitdata& in)
{
frames = NULL;
resize(in.nrFrames);
for (int i = 0; i < nrFrames; i++)
frames[i] = in.frames[i];
};
Hitdata& operator=(const Hitdata& in)
{
resize(in.nrFrames);
for (int i = 0; i < nrFrames; i++)
frames[i] = in.frames[i];
return *this;
};
~Hitdata()
{
if (nrFrames)
delete[] frames;
};
void resize (int nr_frames)
{
if (nrFrames)
delete[] frames;
nrFrames = nr_frames;
if (nrFrames)
frames = new Fullframe[nrFrames];
else
frames = NULL;
};
//Read data from a given file.
//first_frame is the number of first frame to be read
//nr_frames is the maximum number of frames to be read
//-1 to read all of them
//increment allows you reading once every nth sample
//Return number of frames read or 0 in case of failure
int readFile(char* filename, int first_frame = 1, int nr_frames = -1, int increment = 1)
{
std::ifstream file;
//Open the file
file.open(filename, ios_base::in | ios_base::binary);
if (!file.is_open())
{
std::cerr << " ### Hitdata: File could not be open!" << std::endl;
return 0; //file could not be opened
}
//Read first record to find board configuration
Fullframe sampleframe;
if (sampleframe.read(&file) == 0)
{
std::cerr << " ### Hitdata: First frame could not be read!" << std::endl;
file.close();
return 0;
}
else {
std::cout << "Sample frame size (bytes): " << sampleframe.sizeInFile() << std::endl;
}
//Check file size
file.seekg(0, std::ios::beg);
std::streamsize fsize = file.tellg();
file.seekg(0, std::ios::end);
fsize = file.tellg() - fsize;
//Determine real frames to read
unsigned int max_frames = fsize / sampleframe.sizeInFile();
if ((max_frames == -1) || (max_frames < nr_frames))
nr_frames = max_frames;
std::cout << " Hitdata: Nr frames to be read: " << nr_frames << std::endl;
//Read!
// resize(nr_frames); //make an array of Fullframes called frames of size nr_frames
file.seekg(first_frame * sampleframe.sizeInFile(), std::ios::beg);
for (int frame_nr = first_frame; frame_nr < nr_frames; frame_nr++)
{
if ((frame_nr%10000) == 0)
std::cout << " Frame " << frame_nr << std::endl;
file.seekg((frame_nr*increment) * sampleframe.sizeInFile() , std::ios::beg);
if (file.eof()) {
std::cerr<< "end of file reached." << std::endl;
return frame_nr;
}
if ( sampleframe.read(&file) == 0) //read the next frame
{
std::cerr << " ### Hitdata: Frame " << frame_nr << " could not be read!" << std::endl;
file.close(); //read error, finish!
// frames = frame_nr; //Kinky! We decrease nr_frames, but the actual array size remains unchanged!
///???? I don't know what the above line does.
return frame_nr;
}
// std::cout << frames[frame_nr].nrBoards << std::endl;
}
//Finished
file.close();
return nr_frames;
};
Fullframe& operator[] (int index)
{
if (index < nrFrames)
return frames[index];
else
{
std::cerr << " ### Hitdata::operator[]: index out of range!" << std::endl;
// return (*NULL); //this will cause crash (intended).
return frames[index];
}
};
int nrFrames;
Fullframe* frames;
};