2021-01-25 12:39:07 +01:00
//This is an object interface for reading HIT data files
//See HIT documentation for details and examples.
/*
2021-02-08 17:58:07 +01:00
THIS DOESN ' T WORK !
2021-01-25 12:39:07 +01:00
. 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] << " ";
2021-02-08 17:58:07 +01:00
// std::cout << std::endl;
2021-01-25 12:39:07 +01:00
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 ;
} ;