data analysis scripts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
11 KiB

  1. //This is an object interface for reading HIT data files
  2. //See HIT documentation for details and examples.
  3. /*
  4. .L hitreader.c
  5. Hitdata data;
  6. data.read(my_file.da2); //to load whole file at once – forget it! See below.
  7. 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)
  8. //Reading 10 000 frames is reasonable. Reading 100 000 frames made my VM beg for memory.
  9. data.nrFrames //to see how many frames you have
  10. data.frames[0].nrBoards //to see how many boards you had in the system
  11. data.frames[0].boards[0].nrChannels //to see how many channels you have in board 0
  12. data.frames[10].boards[0].data[100] //get signal value for frame 10, board 0, channel 100
  13. data.frames[10].boards[0].syncframe.local_ctr //get the local synchro counter for frame 10, board 0
  14. //same for .global_ctr, .sma_state, .dummy, .device_nr, .data_ok
  15. */
  16. //*********************** Helper *************************
  17. #include <fstream>
  18. #include <iostream>
  19. using namespace std;
  20. //#define debug(str) std::cout << "HIT DEBUG: " << str << endl;
  21. #define debug(str)
  22. //*********************** Syncframe *************************
  23. class Syncframe
  24. {
  25. public:
  26. Syncframe()
  27. {
  28. debug("Syncframe()");
  29. local_ctr = global_ctr = 0;
  30. sma_state = dummy = 0;
  31. device_nr = -1;
  32. data_ok = 0;
  33. };
  34. ~Syncframe()
  35. {
  36. debug("~Syncframe()");
  37. };
  38. int sizeInFile()
  39. {
  40. return 16;
  41. };
  42. int read(std::ifstream* file)
  43. {
  44. char buffer[16];
  45. file->read(buffer,16);
  46. if (file->fail())
  47. return 0;
  48. local_ctr = *(unsigned short*)(buffer+0);
  49. global_ctr = *(unsigned short*)(buffer+2);
  50. sma_state = *(unsigned short*)(buffer+4);
  51. dummy = *(unsigned short*)(buffer+6);
  52. device_nr = *(int*)(buffer+8);
  53. data_ok = *(int*)(buffer+12);
  54. // std::cout << "Syncframe:" << local_ctr << " " << global_ctr << " " << sma_state << " " << dummy << " " << device_nr << " " << data_ok << std::endl;
  55. return 1;
  56. };
  57. unsigned short local_ctr;
  58. unsigned short global_ctr;
  59. unsigned short sma_state;
  60. unsigned short dummy;
  61. int device_nr;
  62. unsigned int data_ok;
  63. };
  64. //*********************** Sensorframe *************************
  65. class Boardframe
  66. {
  67. public:
  68. Boardframe(int nr_channels = 0)
  69. {
  70. debug("Boardframe()");
  71. data = NULL;
  72. resize (nr_channels);
  73. };
  74. Boardframe(const Boardframe& in)
  75. {
  76. debug("Boardframe(Boardframe&)");
  77. data = NULL;
  78. resize(in.nrChannels);
  79. for (int i = 0; i < nrChannels; i++)
  80. data[i] = in.data[i];
  81. syncframe = in.syncframe;
  82. };
  83. Boardframe& operator=(const Boardframe& in)
  84. {
  85. debug("Boardframe::operator==");
  86. resize(in.nrChannels);//creates an array called data of length nrChannels
  87. for (int i = 0; i < nrChannels; i++)
  88. data[i] = in.data[i];
  89. syncframe = in.syncframe;
  90. return *this;
  91. };
  92. ~Boardframe()
  93. {
  94. debug("~Boardframe()");
  95. if (data)
  96. delete[] data;
  97. };
  98. void resize(int nr_channels)
  99. {
  100. if (data)
  101. delete[] data;
  102. nrChannels = nr_channels;
  103. if (nrChannels)
  104. data = new unsigned short[nrChannels];
  105. else
  106. data = NULL;
  107. };
  108. int sizeInFile()
  109. {
  110. // std::cout << "boardframe.sizeInFile() = " << syncframe.sizeInFile() + nrChannels*2 << std::endl;
  111. return syncframe.sizeInFile() + nrChannels*2;
  112. };
  113. int read(std::ifstream* file)
  114. {
  115. if (syncframe.read(file) == 0)//get the syncframe before the board data
  116. return 0;
  117. //I must be already resized at this point!
  118. file->read((char*)data,2*nrChannels);
  119. if (file->fail())
  120. return 0;
  121. // std::cout<< "data[" << nrChannels << "]: ";
  122. // for (int i = 0;i<nrChannels;i++) std::cout << data[i] << " ";
  123. // std::cout << std::endl;
  124. return 1;
  125. };
  126. unsigned short& operator[] (int index)
  127. {
  128. return data[index];
  129. };
  130. Syncframe syncframe;
  131. int nrChannels;
  132. unsigned short* data;
  133. };
  134. //*********************** Fullframe *************************
  135. class Fullframe
  136. {
  137. public:
  138. Fullframe(int nr_boards = 0)
  139. {
  140. debug("Fullframe()");
  141. boards = NULL;
  142. resize(nr_boards);
  143. };
  144. Fullframe(const Fullframe& in)
  145. {
  146. debug("Fullframe(Fullframe&)");
  147. boards = NULL;
  148. resize(in.nrBoards);
  149. for (int i = 0; i < nrBoards; i++)
  150. boards[i] = in.boards[i];
  151. };
  152. Fullframe& operator=(const Fullframe& in)
  153. {
  154. debug("Fullframe::operator==");
  155. resize(in.nrBoards);
  156. for (int i = 0; i < nrBoards; i++)
  157. boards[i] = in.boards[i];
  158. return *this;
  159. };
  160. ~Fullframe()
  161. {
  162. debug("~Fullframe()");
  163. if (boards)
  164. delete[] boards;
  165. };
  166. void resize (int nr_boards)
  167. {
  168. if (boards)
  169. delete[] boards;
  170. nrBoards = nr_boards;
  171. if (nrBoards)
  172. boards = new Boardframe[nrBoards];
  173. else
  174. boards = NULL;
  175. }
  176. int sizeInFile()
  177. {
  178. if (boards){
  179. // std::cout << "Fullframe.sizeInFile() = " << 2 + nrBoards*2 + nrBoards * boards[0].sizeInFile() << std::endl;
  180. // return 2 + nrBoards*2 + nrBoards * boards[0].sizeInFile();
  181. //// boards[0].sizeInFile() returns 656 for every board...
  182. return 2 + 4*2 + (16 + 320 * 2) + (16 + 128*2)*3; //1482
  183. }
  184. else
  185. return 0; //no boards, makes no sense...
  186. };
  187. int read(std::ifstream* file)
  188. {
  189. //Read number of boards
  190. unsigned short nr_boards;
  191. file->read((char*)&nr_boards,2);
  192. if(file->fail()){
  193. std::cerr << "File read failed." << std::endl;
  194. return 0;
  195. }
  196. if (nr_boards!=4){
  197. std::cerr << "Unrealistic number(!=) of boards to be read:"<< nr_boards << std::endl;
  198. std::cerr << "Will try to resync frame." << std::endl;
  199. for (int j = 0;j<741;j++){
  200. file->read((char*)&nr_boards,2);
  201. if (nr_boards==4) break;
  202. }
  203. if ( nr_boards!=4){
  204. std::cerr << "Resync failed." << std::endl;
  205. return 0;
  206. }
  207. }
  208. //std::cout << " nr_boards: " << nr_boards << std::endl;
  209. //Read channel counts
  210. unsigned short* channel_counts = new unsigned short[nr_boards];
  211. file->read((char*)channel_counts,nr_boards*2);
  212. if (file->fail())
  213. {
  214. delete[] channel_counts;
  215. return 0;
  216. }
  217. //Read board frames
  218. resize(nr_boards);
  219. for (int board_nr = 0; board_nr < nr_boards; board_nr++)
  220. {
  221. // std::cout << " channel_counts[" << board_nr << "]: "<< channel_counts[board_nr] << std::endl;
  222. boards[board_nr].resize(channel_counts[board_nr]);
  223. if (boards[board_nr].read(file) == 0)//read the board
  224. {
  225. delete[] channel_counts;
  226. return 0;
  227. }
  228. }
  229. delete[] channel_counts;
  230. return 1;
  231. };
  232. int nrChannels()
  233. {
  234. int result = 0;
  235. for (int board_nr = 0; board_nr < nrBoards; board_nr++)
  236. result += boards[board_nr].nrChannels;
  237. return result;
  238. };
  239. unsigned short& operator[] (int index)
  240. {
  241. for (int board_nr = 0; board_nr < nrBoards; board_nr++)
  242. {
  243. if (index >= boards[board_nr].nrChannels)
  244. index -= boards[board_nr].nrChannels;
  245. else
  246. return boards[board_nr][index];
  247. }
  248. std::cerr << " ### Fullframe::operator[]: index out of range!" << std::endl;
  249. // return (*NULL); //this will cause crash (intended).
  250. return boards[nrBoards][index];
  251. };
  252. int nrBoards;
  253. Boardframe* boards;
  254. };
  255. //*********************** Hitdata *************************
  256. class Hitdata
  257. {
  258. public:
  259. Hitdata(int nr_frames = 0)
  260. {
  261. frames = NULL;
  262. resize(nr_frames);
  263. };
  264. Hitdata(const Hitdata& in)
  265. {
  266. frames = NULL;
  267. resize(in.nrFrames);
  268. for (int i = 0; i < nrFrames; i++)
  269. frames[i] = in.frames[i];
  270. };
  271. Hitdata& operator=(const Hitdata& in)
  272. {
  273. resize(in.nrFrames);
  274. for (int i = 0; i < nrFrames; i++)
  275. frames[i] = in.frames[i];
  276. return *this;
  277. };
  278. ~Hitdata()
  279. {
  280. if (nrFrames)
  281. delete[] frames;
  282. };
  283. void resize (int nr_frames)
  284. {
  285. if (nrFrames)
  286. delete[] frames;
  287. nrFrames = nr_frames;
  288. if (nrFrames)
  289. frames = new Fullframe[nrFrames];
  290. else
  291. frames = NULL;
  292. };
  293. //Read data from a given file.
  294. //first_frame is the number of first frame to be read
  295. //nr_frames is the maximum number of frames to be read
  296. //-1 to read all of them
  297. //increment allows you reading once every nth sample
  298. //Return number of frames read or 0 in case of failure
  299. int readFile(char* filename, int first_frame = 1, int nr_frames = -1, int increment = 1)
  300. {
  301. std::ifstream file;
  302. //Open the file
  303. file.open(filename, ios_base::in | ios_base::binary);
  304. if (!file.is_open())
  305. {
  306. std::cerr << " ### Hitdata: File could not be open!" << std::endl;
  307. return 0; //file could not be opened
  308. }
  309. //Read first record to find board configuration
  310. Fullframe sampleframe;
  311. if (sampleframe.read(&file) == 0)
  312. {
  313. std::cerr << " ### Hitdata: First frame could not be read!" << std::endl;
  314. file.close();
  315. return 0;
  316. }
  317. else {
  318. std::cout << "Sample frame size (bytes): " << sampleframe.sizeInFile() << std::endl;
  319. }
  320. //Check file size
  321. file.seekg(0, std::ios::beg);
  322. std::streamsize fsize = file.tellg();
  323. file.seekg(0, std::ios::end);
  324. fsize = file.tellg() - fsize;
  325. //Determine real frames to read
  326. unsigned int max_frames = fsize / sampleframe.sizeInFile();
  327. if ((max_frames == -1) || (max_frames < nr_frames))
  328. nr_frames = max_frames;
  329. std::cout << " Hitdata: Nr frames to be read: " << nr_frames << std::endl;
  330. //Read!
  331. // resize(nr_frames); //make an array of Fullframes called frames of size nr_frames
  332. file.seekg(first_frame * sampleframe.sizeInFile(), std::ios::beg);
  333. for (int frame_nr = first_frame; frame_nr < nr_frames; frame_nr++)
  334. {
  335. if ((frame_nr%10000) == 0)
  336. std::cout << " Frame " << frame_nr << std::endl;
  337. file.seekg((frame_nr*increment) * sampleframe.sizeInFile() , std::ios::beg);
  338. if (file.eof()) {
  339. std::cerr<< "end of file reached." << std::endl;
  340. return frame_nr;
  341. }
  342. if ( sampleframe.read(&file) == 0) //read the next frame
  343. {
  344. std::cerr << " ### Hitdata: Frame " << frame_nr << " could not be read!" << std::endl;
  345. file.close(); //read error, finish!
  346. // frames = frame_nr; //Kinky! We decrease nr_frames, but the actual array size remains unchanged!
  347. ///???? I don't know what the above line does.
  348. return frame_nr;
  349. }
  350. // std::cout << frames[frame_nr].nrBoards << std::endl;
  351. }
  352. //Finished
  353. file.close();
  354. return nr_frames;
  355. };
  356. Fullframe& operator[] (int index)
  357. {
  358. if (index < nrFrames)
  359. return frames[index];
  360. else
  361. {
  362. std::cerr << " ### Hitdata::operator[]: index out of range!" << std::endl;
  363. // return (*NULL); //this will cause crash (intended).
  364. return frames[index];
  365. }
  366. };
  367. int nrFrames;
  368. Fullframe* frames;
  369. };