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.

468 lines
16 KiB

  1. #define hit_analyse_v2_cxx
  2. #include "hit_analyse_v2.h"
  3. int main(int argc, char **argv){
  4. opendatafiles(argc, argv);
  5. histograms(argc, argv);
  6. analyse(argc, argv);
  7. closedatafiles();
  8. return 0;
  9. }
  10. int opendatafiles(int argc, char ** argv){
  11. if (argc>2){
  12. //open bpm data file
  13. filename = Form("%s%s.da2",argv[1],argv[2]);
  14. file.open(filename, ifstream::in | ifstream::binary);
  15. if (!file.is_open())
  16. {
  17. std::cerr << " ### Hitdata: File could not be opened!" << filename << std::endl;
  18. return 0; //file could not be opened
  19. }
  20. else {std::cout << filename << " opened successfully." << std::endl;}
  21. }
  22. string visualize_check = argv[5]; //plot data
  23. if (visualize_check == "vis_true") {visualize = true;}
  24. else{ visualize= false;}
  25. return 1;
  26. }
  27. int closedatafiles(){
  28. if (file.is_open()) file.close();
  29. // if (timestampfile.is_open()) timestampfile.close();
  30. //if (offsetfile.is_open()) offsetfile.close();
  31. rootFile->Write();
  32. rootFile->Close();
  33. }
  34. int analyse(int argc, char **argv)
  35. {
  36. int first_frame = 0; // 1440000
  37. int nr_frames = -1;
  38. int increment = 1;
  39. //Read first record to find board configuration
  40. Fullframe sampleframe;
  41. if (sampleframe.read(&file) == 0)
  42. {
  43. std::cerr << " ### Hitdata: First frame could not be read!" << std::endl;
  44. file.close();
  45. return 0;
  46. }
  47. else {
  48. std::cout << "Sample frame size (bytes): " << sampleframe.sizeInFile() << std::endl;
  49. }
  50. //Check file size
  51. file.seekg(0, std::ios::beg);
  52. std::streamsize fsize = file.tellg();
  53. file.seekg(0, std::ios::end);
  54. fsize = file.tellg() - fsize;
  55. //Determine real frames to read
  56. unsigned int max_frames = fsize / sampleframe.sizeInFile();
  57. if ((max_frames == -1) || (max_frames < nr_frames))
  58. nr_frames = max_frames;
  59. std::cout << " Hitdata: Nr frames to be read: " << nr_frames << std::endl;
  60. ///set the background levels from first N events
  61. int bkg_frames = 1000;
  62. if (set_background_v2(0, bkg_frames)==0) return 0;
  63. BPMbeamrecon_Zeroed.Position = -128.;
  64. BPMbeamrecon_Zeroed.Focus = -1.;
  65. BPMbeamrecon_Zeroed.Peak = -1.;
  66. BPMbeamrecon_Zeroed.Position = -128.;
  67. BPMbeamrecon_Zeroed.Rsqr = -1.;
  68. BPMbeamrecon_Zeroed.Skew = -128.;
  69. BPMbeamrecon_Zeroed.Position = -128.;
  70. BPMbeamrecon_Zeroed.Sum = 0.;
  71. BPMbeamrecon_Zeroed.n_channels = 0;
  72. //read board
  73. //Read!
  74. std::cout << "Reading data starting from frame: " << first_frame << std::endl;
  75. file.seekg(first_frame * sampleframe.sizeInFile(), std::ios::beg);
  76. for (int frame_nr = first_frame; frame_nr < nr_frames; frame_nr++)
  77. {
  78. eventID=frame_nr;
  79. if ((frame_nr%100000) == 0)
  80. std::cout << " Frame " << frame_nr << std::endl;
  81. file.seekg((frame_nr*increment) * sampleframe.sizeInFile() , std::ios::beg);
  82. if (sampleframe.read(&file) == 0) //read the next frame and catch if returns error
  83. {
  84. std::cerr << " ### Hitdata: Frame " << frame_nr << " could not be read! Stopping." << std::endl;
  85. file.close(); //read error, finish!
  86. return 0;
  87. }
  88. for (int boardnumber = 0; boardnumber<4; boardnumber++){
  89. board_b[boardnumber] = readboard(sampleframe,boardnumber);//a bit redundant but does some analysis
  90. // std::cout << board_b[0].integratedsignalamp << std::endl;
  91. if (boardnumber==0&&board_b[0].integratedsignalamp>1000 && board_b[0].maxchannel_amp>100.){
  92. BPMbeamrecon_0 = beamreconstruction(board_b[0], 80.); // do the linear regression fit of the beam;
  93. // std::cout << "doing regression" << std::endl;
  94. }
  95. else if (boardnumber==0) {BPMbeamrecon_0=BPMbeamrecon_Zeroed;}
  96. if (boardnumber==1&&board_b[1].integratedsignalamp>1000 && board_b[1].maxchannel_amp>100.){
  97. BPMbeamrecon_1 = beamreconstruction(board_b[1], 80.); // do the linear regression fit of the beam;
  98. // std::cout << "doing regression" << std::endl;
  99. }
  100. else if (boardnumber==1) {BPMbeamrecon_1=BPMbeamrecon_Zeroed;}
  101. if (boardnumber==2&&board_b[2].integratedsignalamp>1000 && board_b[2].maxchannel_amp>100.){
  102. BPMbeamrecon_2 = beamreconstruction(board_b[2], 80.); // do the linear regression fit of the beam;
  103. // std::cout << "doing regression" << std::endl;
  104. }
  105. else if (boardnumber==2) {BPMbeamrecon_2=BPMbeamrecon_Zeroed;}
  106. if (boardnumber==3&&board_b[3].integratedsignalamp>1000 && board_b[3].maxchannel_amp>100.){
  107. BPMbeamrecon_3 = beamreconstruction(board_b[3], 80.); // do the linear regression fit of the beam;
  108. // std::cout << "doing regression" << std::endl;
  109. }
  110. else if (boardnumber==3) {BPMbeamrecon_3=BPMbeamrecon_Zeroed;}
  111. }
  112. // cout << "fill hist " << int(board_b[0].nrChannels) << endl;
  113. for (int j = 0;j< board_b[0].nrChannels;j++){
  114. if (board_b[0].maxchannel_amp>100.) TH2D_b0_signal_vs_channel->Fill(j, board_b[0].channel_amp[j]);
  115. }
  116. for (int j = 0;j< board_b[1].nrChannels;j++){
  117. if (board_b[1].maxchannel_amp>100.) TH2D_b1_signal_vs_channel->Fill(j, board_b[1].channel_amp[j]);
  118. }
  119. for (int j = 0;j< board_b[2].nrChannels;j++){
  120. if (board_b[2].maxchannel_amp>100.) TH2D_b2_signal_vs_channel->Fill(j, board_b[2].channel_amp[j]);
  121. }
  122. for (int j = 0;j< board_b[3].nrChannels;j++){
  123. if (board_b[3].maxchannel_amp>100.) TH2D_b3_signal_vs_channel->Fill(j, board_b[3].channel_amp[j]);
  124. }
  125. // cout << "fill tree" << endl;
  126. rootTree->Fill();
  127. }
  128. return 1;
  129. }
  130. void histograms(int fargc, char ** argv){
  131. //open output root file
  132. rootfilename = Form("%s/root/%s.root",argv[1],argv[2]);
  133. rootFile = new TFile(rootfilename,"RECREATE");
  134. if ( rootFile->IsOpen() ) {printf("ROOT file opened successfully\n");
  135. }
  136. else { printf("ROOT file failed to open. \n");}
  137. rootTree = new TTree("t","HIT Data Root Tree");
  138. rootTree ->Branch("BPMbeamrecon_0", &BPMbeamrecon_0, "Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I");
  139. rootTree ->Branch("BPMbeamrecon_1", &BPMbeamrecon_1, "Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I");
  140. rootTree ->Branch("BPMbeamrecon_2", &BPMbeamrecon_2, "Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I");
  141. rootTree ->Branch("BPMbeamrecon_3", &BPMbeamrecon_3, "Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I");
  142. rootTree ->Branch("eventID",&eventID,"eventID/I");
  143. TH2D_b0_signal_vs_channel = new TH2D("TH2D_b0_signal_vs_channel","TH2D_b0_signal_vs_channel",320,0,320,1200,-2000,20000);
  144. TH2D_b1_signal_vs_channel = new TH2D("TH2D_b1_signal_vs_channel","TH2D_b1_signal_vs_channel",320,0,320,1200,-2000,20000);
  145. TH2D_b2_signal_vs_channel = new TH2D("TH2D_b2_signal_vs_channel","TH2D_b2_signal_vs_channel",320,0,320,1200,-2000,20000);
  146. TH2D_b3_signal_vs_channel = new TH2D("TH2D_b3_signal_vs_channel","TH2D_b3_signal_vs_channel",320,0,320,1200,-2000,20000);
  147. }
  148. //Function for average
  149. double avg ( vector<Channel> v )
  150. {
  151. double return_value = 0.0;
  152. int n = v.size();
  153. for ( int i=0; i < n; i++)
  154. {
  155. return_value += v[i].chnumber;
  156. }
  157. return ( return_value / double(n));
  158. }
  159. //****************End of average funtion****************
  160. //Function for variance
  161. double variance ( vector<Channel> v , double mean )
  162. {
  163. double sum = 0.0;
  164. double temp =0.0;
  165. double var =0.0;
  166. for ( int j =0; j < v.size(); j++)
  167. {
  168. temp = pow((v[j].chnumber - mean) , 2);
  169. sum += temp;
  170. }
  171. return var = sum/double(v.size() -2);
  172. }
  173. //****************End of variance funtion****************
  174. int set_background_v2(int start_frame, int max_frames){
  175. std::cout << "Setting background levels." << std::endl;
  176. for (int j = 0; j<320; j++){
  177. for (int k = 0; k<4; k++){
  178. board_b_bkg[k].channel_amp[j] = 0.;
  179. }
  180. }
  181. //Read first record to find board configuration
  182. Fullframe sampleframe;
  183. file.seekg(start_frame * sampleframe.sizeInFile() , std::ios::beg);
  184. if (sampleframe.read(&file) == 0) //read the next frame and catch if returns error
  185. {
  186. std::cerr << " ### Hitdata: First frame could not be read!" << std::endl;
  187. file.close(); //read error, finish!
  188. return 0;
  189. }
  190. //Read
  191. // file.seekg(sampleframe.sizeInFile(), std::ios::beg);
  192. for (int frame_nr = start_frame; frame_nr < max_frames; frame_nr++)
  193. {
  194. file.seekg(frame_nr * sampleframe.sizeInFile() , std::ios::beg);
  195. if (sampleframe.read(&file) == 0) //read the next frame and catch if returns error
  196. {
  197. std::cerr << " ### Hitdata: Frame " << frame_nr << " could not be read!" << std::endl;
  198. file.close(); //read error, finish!
  199. return 0;
  200. }
  201. for (int boardnumber = 0; boardnumber<4; boardnumber++){
  202. for (int j = 0; j<sampleframe.boards[boardnumber].nrChannels;j++){
  203. board_b_bkg[boardnumber].channel_amp[j] += sampleframe.boards[boardnumber].data[j] / double(max_frames);
  204. // std::cout << j << " " << board.channel_amp[j] << " " << dataptr->sensor_data[j] << std::endl;
  205. }
  206. }
  207. }
  208. std::cout << "Background set." << std::endl;
  209. return 1;
  210. }
  211. bpm_frame_v2 readboard(Fullframe frame, int boardnumber){
  212. bpm_frame_v2 board;
  213. board.integratedsignalamp = 0.;
  214. board.maxchannel_amp = 0.;
  215. board.nrChannels = frame.boards[boardnumber].nrChannels;
  216. board.board_number = boardnumber;
  217. // file.seekg(boardnumber*sizeof(BufferData)+4*frame*sizeof(BufferData));
  218. //file.read ((char*)dataptr ,sizeof(BufferData));
  219. if (frame.boards[boardnumber].syncframe.device_nr==boardnumber){
  220. // cout << "nrChannels" << frame.boards[boardnumber].nrChannels << endl;
  221. for (int j = 0; j<frame.boards[boardnumber].nrChannels;j++){
  222. //subtract the background from the data
  223. board.channel_amp[j] = frame.boards[boardnumber].data[j] - board_b_bkg[boardnumber].channel_amp[j];
  224. // std::cout << j << " " << board.channel_amp[j] << " " << frame.boards[boardnumber].data[j] << std::endl;
  225. //sum the signal across channels
  226. board.integratedsignalamp += board.channel_amp[j];
  227. //find the peak channel
  228. if (board.channel_amp[j]> board.maxchannel_amp) {
  229. board.maxchannel = j;
  230. board.maxchannel_amp = board.channel_amp[j];
  231. // cout << maxchannel_b0 << " " <<maxchannelamp_b0 << endl;
  232. }
  233. //set the channel positions in mm
  234. board.channel_position[j] = 0.8*j + 0.2*(floor(j/64));
  235. //cout << board.channel_position[j] << " " << j << " " << (floor(j/64)) << endl;
  236. }
  237. }
  238. else std::cerr << "Error reading board data." << std::endl;
  239. return board;
  240. }
  241. beamRecon beamreconstruction(bpm_frame_v2 frametoanalyse, double threshold = 30.){
  242. ///////////////// linear regression using Integration by parts of gaussian function.
  243. beamRecon beam;
  244. double SumT, SumS, SumS2, SumST, SumT2, SumY, SumYS, SumYT, sigmaABC, muABC,p,c, b, b_den, b_num, SumYYP, SumYYM, MeanY;
  245. TMatrixD M1(3,3);
  246. TMatrixD M1inv(3,3);
  247. TVectorD ABC(3);
  248. TVectorD M2(3);
  249. vector<double> signal_list;
  250. vector<double> channel_list;
  251. SumY = 0.;
  252. SumS = 0.;
  253. SumT = 0.;
  254. SumS2 = 0.;
  255. SumST = 0.;
  256. SumT2 = 0.;
  257. SumYS = 0.;
  258. SumYT = 0.;
  259. b_den = 0.;
  260. b_num = 0.;
  261. b = 0.;
  262. p = 0.;
  263. c = 0.;
  264. SumYYM = 0.;
  265. SumYYP = 0.;
  266. MeanY = 0.;
  267. // const int array_length = sizeof(frametoanalyse.channel_amp)/sizeof(double);
  268. const int array_length = frametoanalyse.nrChannels ;
  269. vector<Channel> channel_reducedlist; //for anomaly detection
  270. vector<Channel> channel_reducedlistcopy; //for anomaly detection
  271. //hardcoded pixels to mask for this data set.
  272. const int arr_0[] = {139 };
  273. //const int arr_1[] = {};
  274. const int arr_2[] = { 11,12 };
  275. const int arr_3[] = { 1, 2, };
  276. vector<int> masked_channels[4];
  277. masked_channels[0].assign( arr_0, arr_0 + sizeof(arr_0) / sizeof(*arr_0) );
  278. // masked_channels[0].assign( arr_0, arr_0 + sizeof(arr_0) / sizeof(*arr_0) );
  279. masked_channels[2].assign( arr_2, arr_2 + sizeof(arr_2) / sizeof(*arr_2) );
  280. masked_channels[3].assign( arr_3, arr_3 + sizeof(arr_3) / sizeof(*arr_3) );
  281. Channel tmp;
  282. int temp_lastneighbour= -128;
  283. for (int i = 0; i< array_length; i++){
  284. if (std::count( masked_channels[frametoanalyse.board_number].begin(), masked_channels[frametoanalyse.board_number].end(), i)) continue; //check masked pixel list, and do not add it to the list of channels for analysis.
  285. if (frametoanalyse.channel_amp[i]>=threshold) {
  286. // cout << "ch: " << i << endl;
  287. // signal_list.push_back(frametoanalyse.channel_amp[i]);
  288. // channel_list.push_back(frametoanalyse.channel_position[i]);
  289. tmp.amplitude = frametoanalyse.channel_amp[i];
  290. tmp.position = frametoanalyse.channel_position[i];
  291. tmp.chnumber = i;
  292. tmp.last_neighbour = temp_lastneighbour;
  293. temp_lastneighbour = i ;
  294. channel_reducedlist.push_back(tmp);
  295. if (channel_reducedlist.size()>1){
  296. channel_reducedlist[channel_reducedlist.size() - 2].next_neighbour = i;
  297. }
  298. }
  299. }
  300. //anomaly detection
  301. //remove channels without neighbours.
  302. for (int i = 0; i<channel_reducedlist.size() ;i++){
  303. if (abs(channel_reducedlist[i].chnumber - channel_reducedlist[i].last_neighbour)<=1 || abs(channel_reducedlist[i].chnumber-channel_reducedlist[i].next_neighbour)<=1 ){
  304. channel_reducedlistcopy.push_back(channel_reducedlist[i]);
  305. // cout << channel_reducedlist[i].chnumber << " " << channel_reducedlist[i].last_neighbour << " " << channel_reducedlist[i].next_neighbour << endl;
  306. }
  307. }
  308. // channel_reducedlist.clear();//empty list to reuse it.
  309. double cluster_average;
  310. double cluster_variance;
  311. if(channel_reducedlistcopy.size()>2){
  312. cluster_average = avg(channel_reducedlistcopy);
  313. cluster_variance = variance(channel_reducedlistcopy, cluster_average);
  314. // cout << cluster_average << " " << cluster_variance << endl;
  315. }
  316. //include all channels +/- 2*variance of the main cluster
  317. for (int i = 0; i< array_length; i++){
  318. if (abs(i-cluster_average)<2*cluster_variance){
  319. signal_list.push_back(frametoanalyse.channel_amp[i]);
  320. channel_list.push_back(frametoanalyse.channel_position[i]);
  321. }
  322. }
  323. // sort(channel_reducedlist.begin(),channel_reducedlist.end(),CompareChannels);
  324. const int vector_length = channel_list.size();
  325. beam.n_channels = vector_length;
  326. beam.Sum = std::accumulate(signal_list.begin(), signal_list.end(),0);
  327. if (vector_length<=3) return beam;
  328. double S[vector_length];
  329. double T[vector_length];
  330. for(int k=0; k<vector_length;k++){
  331. if (k==0){
  332. S[k]=0.; T[k]=0.;
  333. }
  334. else{
  335. S[k] = S[k-1]+0.5*( signal_list[k] + signal_list[k-1] ) * ( channel_list[k] - channel_list[k-1] );
  336. T[k] = T[k-1]+0.5*( channel_list[k] * signal_list[k] + channel_list[k-1] * signal_list[k-1] ) * ( channel_list[k] - channel_list[k-1] );
  337. }
  338. // cout << S[k] << " " << T[k] << endl;
  339. SumS += S[k]; SumT += T[k];
  340. SumY += signal_list[k];
  341. SumS2 += S[k]*S[k]; SumST += S[k]*T[k]; SumT2 += T[k]*T[k];
  342. SumYS += signal_list[k]*S[k];
  343. SumYT += signal_list[k]*T[k];
  344. MeanY+=signal_list[k];
  345. }
  346. MeanY/=vector_length;
  347. M1(0,0) = SumT2; M1(0,1) = SumST; M1(0,2) = SumT; M1(1,0) = SumST; M1(1,1) = SumS2;
  348. M1(1,2) = SumS; M1(2,0) = SumT; M1(2,1) = SumS;
  349. M1(2,2) = vector_length;
  350. M2(0) = SumYT; M2(1) = SumYS; M2(2) = SumY;
  351. M1inv = M1.Invert(); ABC = M1inv * M2;
  352. //calculate b,p,c ---> y = b*exp(-p*(x-c)*(x-c))
  353. p = -ABC(0)/2.; c = -ABC(1)/ABC(0);
  354. for(int k=0; k<vector_length;k++){
  355. b_num += exp(-p*(channel_list[k]-c)*(channel_list[k]-c)) * signal_list[k];
  356. b_den += exp(-2*p*(channel_list[k]-c)*(channel_list[k]-c));
  357. }
  358. b = b_num/b_den;
  359. beam.Position = -ABC(1)/ ABC(0);
  360. beam.Focus = 2.3548/sqrt(2*p);
  361. beam.Peak = b;
  362. beam.Rsqr = SumYYP/SumYYM;
  363. beam.Skew = gsl_stats_wskew_m_sd(&signal_list[0],1,&channel_list[0],1,vector_length,beam.Position,beam.Focus/2.3548); //skewness (symmetry)
  364. beam.Kurtosis = gsl_stats_wkurtosis_m_sd(&signal_list[0],1,&channel_list[0],1,vector_length,beam.Position,beam.Focus/2.3548); //excess kurtosis (well behaved tails)
  365. return beam;
  366. }