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.

259 lines
7.5 KiB

  1. #define hit_analyse_cxx
  2. #include "hit_analyse.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.dat",argv[1],argv[2]);
  14. file.open(filename, ifstream::in | ifstream::binary);
  15. fileframesize = getFileSize(filename) / ( 4*sizeof(BufferData) );
  16. if (fileframesize>0){ std::cout << "Number of frames in data file: " << fileframesize << std::endl;}
  17. else { std:cout << "BPM .dat dile not found." << endl; return -1;}
  18. //bpm data timestamps
  19. timestampfilename = Form("%s%s_timestamp.csv",argv[1],argv[2]);
  20. timestampfile.open(timestampfilename, ifstream::in);
  21. if (!timestampfile.is_open()){
  22. printf("timestamp.csv did not open.\n");
  23. ethercat = false;
  24. //return -1; //file could not be opened
  25. }
  26. //open ethercat file
  27. if (argc>3){
  28. ethercatfile = argv[3];
  29. tree2 = new TTree("t2", "t2");
  30. std::cout << " Loading Ethercat data." << std::endl;
  31. tree2->ReadFile(ethercatfile, "RELTIME2/D:IC1/D:MW1_POSX/D:MW1_POSY/D:ANALOG_IN1/D:ENERGY_INDEX/D:INTENSITY_INDEX/D:ION-SORT/D:TIME2/D", '\t');
  32. std::cout << "Ethercat data loaded." << std::endl;
  33. tree2->Print();
  34. }
  35. //open amplitude offset correction file
  36. if (argc>4){
  37. offsetfilename = Form("%s",argv[4]);
  38. offsetfile.open(offsetfilename, ifstream::in);
  39. if (!offsetfile.is_open()){
  40. printf("no offset.txt file found\n");
  41. // return -1; //file could not be opened
  42. }
  43. }
  44. dataptr = new BufferData();
  45. return 1;
  46. }
  47. int closedatafiles(int argc, char ** argv){
  48. if (file.is_open()) file.close();
  49. if (timestampfile.is_open()) timestampfile.close();
  50. if (offsetfile.is_open()) offsetfile.close();
  51. rootFile->Write();
  52. rootFile->Close();
  53. }
  54. int analyse(int argc, char **argv)
  55. {
  56. int bkg_frames = 1000;
  57. set_background_v1(bkg_frames);
  58. for (int frame = 0; frame< fileframesize - bkg_frames; frame++ ){
  59. if (frame%10000==0) std::cout << "Frame: " << frame << " (" <<double(frame)/double(fileframesize)*100.0 << "%)" << std::endl;
  60. //must read all boards to keep read correct position in data file
  61. for (int boardnumber = 0; boardnumber<4;boardnumber++){
  62. board_b[boardnumber] = readboard(frame, boardnumber); //read in the frame
  63. BPMbeamrecon[boardnumber] = beamreconstruction(board_b[boardnumber], 50.); // do the linear regression fit of the beam;
  64. }
  65. }
  66. return 1;
  67. }
  68. bpm_frame_v1 readboard(int frame, int boardnumber){
  69. bpm_frame_v1 board;
  70. board.integratedsignalamp = 0.;
  71. file.seekg(boardnumber*sizeof(BufferData)+4*frame*sizeof(BufferData));
  72. file.read ((char*)dataptr ,sizeof(BufferData));
  73. if (dataptr->sync_frame.device_nr==boardnumber){
  74. for (int j = 1; j<128;j++){
  75. //subtract the background from the data
  76. board.channel_amp[j] = dataptr->sensor_data[j] - board_b_bkg[boardnumber].channel_amp[j];
  77. // std::cout << j << " " << board.channel_amp[j] << " " << dataptr->sensor_data[j] << std::endl;
  78. //sum the signal across channels
  79. board.integratedsignalamp += board.channel_amp[j];
  80. //find the peak channel
  81. if (board.channel_amp[j]> board.maxchannel_amp) {
  82. board.maxchannel = j;
  83. board.maxchannel_amp = board.channel_amp[j];
  84. // cout << maxchannel_b0 << " " <<maxchannelamp_b0 << endl;
  85. }
  86. }
  87. }
  88. else std::cerr << "Error reading board data." << std::endl;
  89. return board;
  90. }
  91. void histograms(){
  92. //open output root file
  93. rootfilename = Form("%s/root/%s.root",argv[1],argv[2]);
  94. rootFile = new TFile(rootfilename,"RECREATE");
  95. if ( rootFile->IsOpen() ) printf("ROOT file opened successfully\n");
  96. }
  97. else return -1;
  98. TTree *rootTree = new TTree("t","HIT Data Root Tree");
  99. }
  100. void set_background_v1(int max_frames){
  101. for (int j = 0; j<128; j++){
  102. for (int k = 0; k<4; k++){
  103. board_b_bkg[k].channel_amp[j] = 0.;
  104. }
  105. }
  106. for (int i = 0;i<max_frames;i++){
  107. //must read all boards to keep read correct position in data file
  108. for (int boardnumber = 0; boardnumber<4; boardnumber++){
  109. file.seekg(boardnumber*sizeof(BufferData)+4*i*sizeof(BufferData));
  110. file.read ((char*)dataptr ,sizeof(BufferData));
  111. if (dataptr->sync_frame.device_nr==boardnumber){
  112. for (int j = 1; j<128;j++){
  113. board_b_bkg[boardnumber].channel_amp[j] += double(dataptr->sensor_data[j]) / double(max_frames);
  114. // std::cout << j << " " << board.channel_amp[j] << " " << dataptr->sensor_data[j] << std::endl;
  115. }
  116. }
  117. else std::cerr << "Error reading board data." << std::endl;
  118. }
  119. }
  120. }
  121. beamRecon beamreconstruction(bpm_frame_v1 frametoanalyse, double threshold = 50.){
  122. ///////////////// linear regression using Integration by parts of gaussian function.
  123. beamRecon beam;
  124. double SumT, SumS, SumS2, SumST, SumT2, SumY, SumYS, SumYT, sigmaABC, muABC,p,c, b, b_den, b_num, SumYYP, SumYYM, MeanY;
  125. TMatrixD M1(3,3);
  126. TMatrixD M1inv(3,3);
  127. TVectorD ABC(3);
  128. TVectorD M2(3);
  129. vector<double> signal_list;
  130. vector<double> channel_list;
  131. SumY = 0.;
  132. SumS = 0.;
  133. SumT = 0.;
  134. SumS2 = 0.;
  135. SumST = 0.;
  136. SumT2 = 0.;
  137. SumYS = 0.;
  138. SumYT = 0.;
  139. b_den = 0.;
  140. b_num = 0.;
  141. b = 0.;
  142. p = 0.;
  143. c = 0.;
  144. SumYYM = 0.;
  145. SumYYP = 0.;
  146. MeanY = 0.;
  147. // const int array_length = sizeof(frametoanalyse.channel_amp)/sizeof(double);
  148. const int array_length = 128;
  149. for (int i = 0; i< array_length; i++){
  150. if (frametoanalyse.channel_amp[i]>=threshold) {
  151. signal_list.push_back(frametoanalyse.channel_amp[i]);
  152. channel_list.push_back(i);//correct for actual detector position
  153. }
  154. }
  155. const int vector_length = channel_list.size();
  156. if (vector_length<=3) return beam;
  157. double S[vector_length];
  158. double T[vector_length];
  159. for(int k=0; k<vector_length;k++){
  160. if (k==0){
  161. S[k]=0.; T[k]=0.;
  162. }
  163. else{
  164. S[k] = S[k-1]+0.5*( signal_list[k] + signal_list[k-1] ) * ( channel_list[k] - channel_list[k-1] );
  165. 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] );
  166. }
  167. // cout << S[k] << " " << T[k] << endl;
  168. SumS += S[k]; SumT += T[k];
  169. SumY += signal_list[k];
  170. SumS2 += S[k]*S[k]; SumST += S[k]*T[k]; SumT2 += T[k]*T[k];
  171. SumYS += signal_list[k]*S[k];
  172. SumYT += signal_list[k]*T[k];
  173. MeanY+=signal_list[k];
  174. }
  175. MeanY/=vector_length;
  176. M1(0,0) = SumT2; M1(0,1) = SumST; M1(0,2) = SumT; M1(1,0) = SumST; M1(1,1) = SumS2;
  177. M1(1,2) = SumS; M1(2,0) = SumT; M1(2,1) = SumS;
  178. M1(2,2) = vector_length;
  179. M2(0) = SumYT; M2(1) = SumYS; M2(2) = SumY;
  180. M1inv = M1.Invert(); ABC = M1inv * M2;
  181. //calculate b,p,c ---> y = b*exp(-p*(x-c)*(x-c))
  182. p = -ABC(0)/2.; c = -ABC(1)/ABC(0);
  183. for(int k=0; k<vector_length;k++){
  184. b_num += exp(-p*(channel_list[k]-c)*(channel_list[k]-c)) * signal_list[k];
  185. b_den += exp(-2*p*(channel_list[k]-c)*(channel_list[k]-c));
  186. }
  187. b = b_num/b_den;
  188. beam.Position = -ABC(1)/ ABC(0);
  189. beam.Focus = 2.3548/sqrt(2*p);
  190. beam.Peak = b;
  191. beam.Rsqr = SumYYP/SumYYM;
  192. 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)
  193. 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)
  194. return beam;
  195. }