|
|
//This is an object interface for reading HIT data files
//See HIT documentation for details and examples.
/*
.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; };
|