@ -36,8 +36,9 @@ int closedatafiles(){
/ / if ( timestampfile . is_open ( ) ) timestampfile . close ( ) ;
/ / if ( offsetfile . is_open ( ) ) offsetfile . close ( ) ;
rootFile - > Write ( ) ;
/ / rootFile - > Write ( ) ;
rootFile - > Close ( ) ;
return 1 ;
}
@ -47,6 +48,61 @@ int analyse(int argc, char **argv)
int nr_frames = - 1 ;
int increment = 1 ;
/ / / timestamp finding variables
float fs = 10000 ; / / 10 kHz fibre bpm
float threshold = 0.5 ;
/ / fs = 20 kHz for ethercat IC , threshold = 2500
/ / fs = 10 kHz for fBPM , threshold = 0.5
/ / Decodes timestamp data from synchro stream .
/ / fs is frame rate in Hz .
/ / threshold is the threshold value . Use e . g . 0.5 for boolean data
/ / Timestamper bitrate is assumed to be 250 bps , 4 transmissions / s
int current_pos_in_samples = 0 ;
int samples_per_50ms = floor ( 50e-3 * fs ) ;
int samples_per_one_transmission = floor ( 250e-3 * fs ) ;
int samples_per_bit = floor ( 4e-3 * fs ) ;
string outfilename ;
outfilename + = argv [ 1 ] ;
outfilename + = " root/timestamp/ " ;
outfilename + = argv [ 2 ] ;
outfilename + = " _timestamp.txt " ;
outfile . open ( outfilename ) ;
if ( outfile . good ( ) ) { cout < < outfilename < < " opened successfully. " < < endl ; }
else { cout < < outfilename < < " opening failed. " < < endl ; }
cout < < " samples_per_50ms: " < < samples_per_50ms < < endl ;
cout < < " samples_per_one_transmission : " < < samples_per_one_transmission < < endl ;
cout < < " samples_per_bit: " < < samples_per_bit < < endl ;
/ / % this is used for byte decoding
int bit_multipliers [ 10 ] = { 0 , 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 0 } ; / / 1 + byte + 1
/ / % and this for word decoding
int byte_multipliers [ 4 ] = { 1 , 256 , 65536 , 16777216 } ;
/ / % Here are positions of each transmission and decoded values
vector < int > block_positions ;
vector < float > block_data ;
vector < float > byte_data ;
vector < float > bit_data ;
vector < int > bit_pattern_to_test ;
vector < float > sample_buffer ;
sample_buffer . assign ( floor ( 4 * 10 * samples_per_bit + samples_per_50ms ) , 0 ) ;
float byte_value ;
int block_nr = 0 ;
float block_value ;
int nbelowthreshold = 0 ;
int nabovethreshold = 0 ;
int last_nbelowthreshold = 0 ;
int last_nabovethreshold = 0 ;
float intime ;
float analog_in2 ;
float last_analog_in2 = 0 ;
int transmission_start_in_samples = 0 ;
@ -146,12 +202,108 @@ int analyse(int argc, char **argv)
for ( int j = 0 ; j < board_b [ 3 ] . nrChannels ; j + + ) {
if ( board_b [ 3 ] . maxchannel_amp > 100. ) TH2D_b3_signal_vs_channel - > Fill ( j , board_b [ 3 ] . channel_amp [ j ] ) ;
}
/ / cout < < " fill tree " < < endl ;
rootTree - > Fill ( ) ;
/ / / find timestamps in sma_state data for the BPM
analog_in2 = board_b [ 3 ] . sma_state ;
/ / cout < < current_pos_in_samples < < " : " < < intime < < " " < < analog_in2 < < " " ;
current_pos_in_samples = eventID ;
sample_buffer . erase ( sample_buffer . begin ( ) ) ; / / remove the first bit in the sample_buffer , and then add the new value at the end .
sample_buffer . push_back ( analog_in2 ) ;
last_nbelowthreshold = nbelowthreshold ;
last_nabovethreshold = nabovethreshold ;
/ / look for 50 ms gap between transmissions ( 1000 * 0.05 ms frames in ethercat IC ) then process the sample buffer
if ( analog_in2 < threshold ) {
nbelowthreshold + + ;
nabovethreshold = 0 ;
}
else {
nbelowthreshold = 0 ; / / reset search window counter if you go above threshold again without reaching the 50 ms gap
nabovethreshold + + ;
}
/ / cout < < " below: " < < nbelowthreshold < < " above: " < < nabovethreshold < < endl ;
/ / if ( last_nbelowthreshold > nbelowthreshold ) cout < < " last below " < < last_nbelowthreshold < < endl ;
/ / if ( last_nabovethreshold > nabovethreshold ) cout < < " last above " < < last_nabovethreshold < < endl ;
if ( nabovethreshold > = samples_per_50ms + samples_per_bit ) { / / last stop bit + 50 ms above thresholds
nabovethreshold = 0 ; / / reset search window counter
transmission_start_in_samples = current_pos_in_samples - samples_per_50ms - 4 * 10 * samples_per_bit ;
/ / % if the gap was found , proceed to finding start and stop bits in sample buffer . . .
/ / cout < < transmission_start_in_samples < < " : sample buffer[ " < < sample_buffer . size ( ) < < " ] " < < endl ;
/ / for ( auto i : sample_buffer ) std : : cout < < i < < " " ;
/ / cout < < endl ;
/ / % initialize byte counter
/ / fill with the middle values where the bits should be
byte_data . clear ( ) ;
bit_pattern_to_test . clear ( ) ;
cout < < transmission_start_in_samples < < " : bit pattern[40] " ;
int count = 0 ;
for ( int byte_nr = 0 ; byte_nr < 4 ; byte_nr + + ) {
for ( int bit_nr = 0 ; bit_nr < 10 ; bit_nr + + ) {
bit_pattern_to_test . push_back ( sample_buffer [ floor ( ( bit_nr + byte_nr * 10 + 0.5 ) * samples_per_bit ) ] > = threshold ? 1 : 0 ) ; / / 1 if greater than threshold else 0
/ / std : : cout < < bit_pattern_to_test [ count ] < < " " ;
count + + ;
} / / 10 bits filled
/ / cout < < endl ;
} / / 4 bytes filled
/ / check that the stop and start bits are in the correct place
if ( bit_pattern_to_test [ 0 ] = = 0 & & bit_pattern_to_test [ 9 ] = = 1 & &
bit_pattern_to_test [ 10 ] = = 0 & & bit_pattern_to_test [ 19 ] = = 1 & &
bit_pattern_to_test [ 20 ] = = 0 & & bit_pattern_to_test [ 29 ] = = 1 & &
bit_pattern_to_test [ 30 ] = = 0 & & bit_pattern_to_test [ 39 ] = = 1 ) {
/ / then
cout < < " Timestamp found at entry " < < transmission_start_in_samples < < endl ;
/ / fill byte
for ( int jbyte_nr = 0 ; jbyte_nr < 4 ; jbyte_nr + + ) {
byte_value = 0 ;
for ( int jbit = 1 ; jbit < 9 ; jbit + + ) {
byte_value + = bit_pattern_to_test [ jbit + 10 * jbyte_nr ] * bit_multipliers [ jbit ] ;
/ / cout < < bit_pattern_to_test [ jbit + 10 * jbyte_nr ] < < " * " < < bit_multipliers [ jbit ] < < " + " ;
}
/ / cout < < " = " < < byte_value < < " " < < endl ; ;
byte_data . push_back ( byte_value ) ;
}
/ / cout < < endl ;
/ / % now calculate the result
block_nr + + ;
block_positions . push_back ( transmission_start_in_samples ) ;
block_value = 0 ;
for ( int jbyte = 0 ; jbyte < 4 ; jbyte + + ) {
block_value + = byte_data [ jbyte ] * byte_multipliers [ jbyte ] ;
}
block_data . push_back ( block_value ) ;
if ( block_nr > 1 ) { printf ( " Block %i at %1.1i: %f ms Delta=%f ms \n " , block_nr , block_positions [ block_nr - 1 ] , block_data [ block_nr - 1 ] , block_data [ block_nr - 1 ] - block_data [ block_nr - 2 ] ) ; }
else { printf ( " Block %i at %1.1i: %f ms \n " , block_nr , block_positions [ block_nr - 1 ] , block_data [ block_nr - 1 ] ) ; }
outfile < < std : : setprecision ( 11 ) < < block_data [ block_nr - 1 ] < < " " < < block_positions [ block_nr - 1 ] < < endl ;
}
else {
cout < < " Bad Block at entry " < < transmission_start_in_samples < < endl ;
}
/ / no matter what , clear the sample buffer and try again .
sample_buffer . clear ( ) ;
sample_buffer . assign ( floor ( 4 * 10 * samples_per_bit + samples_per_50ms ) , 0 ) ;
} / / end of beloww threshold for 50 ms
/ / cout < < " fill tree " < < endl ;
rootTree - > Fill ( ) ;
} / / end of frame loop
outfile . close ( ) ;
return 1 ;
}
@ -168,6 +320,10 @@ void histograms(int fargc, char ** argv){
rootTree - > Branch ( " BPMbeamrecon_1 " , & BPMbeamrecon_1 , " Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I " ) ;
rootTree - > Branch ( " BPMbeamrecon_2 " , & BPMbeamrecon_2 , " Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I " ) ;
rootTree - > Branch ( " BPMbeamrecon_3 " , & BPMbeamrecon_3 , " Position/D:Focus:Peak:Rsqr:Skew:Kurtosis:Sum:n_channels/I " ) ;
/ / rootTree - > Branch ( " board_0 " , & board_b [ 0 ] , " channel_amp[320]/D:channel_position[320]:avg_position:avg_width:integratedsignalamp:max_channel_amp:maxchannel/I:nrChannels:board_number:sma_state " ) ;
/ / rootTree - > Branch ( " board_1 " , & board_b [ 1 ] , " channel_amp[320]/D:channel_position[320]:avg_position:avg_width:integratedsignalamp:max_channel_amp:maxchannel/I:nrChannels:board_number:sma_state " ) ;
/ / rootTree - > Branch ( " board_2 " , & board_b [ 2 ] , " channel_amp[320]/D:channel_position[320]:avg_position:avg_width:integratedsignalamp:max_channel_amp:maxchannel/I:nrChannels:board_number:sma_state " ) ;
/ / rootTree - > Branch ( " board_3 " , & board_b [ 3 ] , " channel_amp[320]/D:channel_position[320]:avg_position:avg_width:integratedsignalamp:max_channel_amp:maxchannel/I:nrChannels:board_number:sma_state " ) ;
rootTree - > Branch ( " eventID " , & eventID , " eventID/I " ) ;
@ -264,7 +420,7 @@ bpm_frame_v2 readboard(Fullframe frame, int boardnumber){
board . maxchannel_amp = 0. ;
board . nrChannels = frame . boards [ boardnumber ] . nrChannels ;
board . board_number = boardnumber ;
board . sma_state = frame . boards [ boardnumber ] . syncframe . sma_state ;
/ / file . seekg ( boardnumber * sizeof ( BufferData ) + 4 * frame * sizeof ( BufferData ) ) ;
/ / file . read ( ( char * ) dataptr , sizeof ( BufferData ) ) ;