- Timestamp:
- Dec 10, 2025, 2:58:23 PM (7 days ago)
- Location:
- trunk/BNC/scripts
- Files:
-
- 2 edited
-
Bnc.pm (modified) (7 diffs)
-
pppPlot.pl (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/scripts/Bnc.pm
r10585 r10798 28 28 # ============================================================================= 29 29 sub callBnc { 30 my ( $bnc, $bnc_ini, $opts ) = @_;31 32 my $config_file = "";33 if ( $bnc_ini && -s $bnc_ini ) {34 $config_file = "--conf $bnc_ini";35 }36 else {37 DEBUG("callBnc: Use default bnc-ini file");38 }39 40 my $opts_str = "";41 if ($opts) { $opts_str = options2string($opts) }42 43 # my @cmd = (44 # 'xvfb-run',45 # "--server-args='-screen 0, 1280x1024x8'", # 1024x768x2446 # "$bnc",47 # "--nw",48 # $opts_str,49 # );30 my ( $bnc, $bnc_ini, $opts ) = @_; 31 32 my $config_file = ""; 33 if ( $bnc_ini && -s $bnc_ini ) { 34 $config_file = "--conf $bnc_ini"; 35 } 36 else { 37 DEBUG("callBnc: Use default bnc-ini file"); 38 } 39 40 my $opts_str = ""; 41 if ($opts) { $opts_str = options2string($opts) } 42 43 # my @cmd = ( 44 # 'xvfb-run', 45 # "--server-args='-screen 0, 1280x1024x8'", # 1024x768x24 46 # "$bnc", 47 # "--nw", 48 # $opts_str, 49 # ); 50 50 51 51 #my $rc = call_system("xvfb-run -a -e /home/user/xvfb.err --server-args='-screen 0 1280x1024x8' $bnc --nw $config_file $opts_str"); 52 return Common::runCmd("$bnc --nw $config_file $opts_str");52 return Common::runCmd("$bnc --nw $config_file $opts_str"); 53 53 } 54 54 55 55 # Converts options map to string used for calling BNC. 56 56 sub options2string { 57 my ($opts) = shift;58 59 my $opts_str = "";60 if ($opts) {61 foreach my $key ( keys %{$opts} ) {62 $opts_str .= "--key $key" . ' "' . $opts->{$key} . '" ';63 }64 }65 return $opts_str;57 my ($opts) = shift; 58 59 my $opts_str = ""; 60 if ($opts) { 61 foreach my $key ( keys %{$opts} ) { 62 $opts_str .= "--key $key" . ' "' . $opts->{$key} . '" '; 63 } 64 } 65 return $opts_str; 66 66 } 67 67 … … 82 82 # ============================================================================= 83 83 sub parseMessageTypesFromFile { 84 my ( $logfile, $caAbbr, $mytmpPath ) = @_; 85 86 unless ( -s $logfile ) { 87 ERROR "File [$logfile] is empty or does not exist"; 88 return; 89 } 90 91 my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.messtyps' ); 92 my $casterMessTypeFile = $tmp->filename; 93 94 #my $caster = $logfilename =~ s/\.log\.messtyps//r; 95 #INFO "Process caster '$caster'"; 96 97 INFO "Process $logfile"; 98 99 # scan beginns with that line: 16-02-18 23:58:02 WTZ37: Get data in RTCM 3.x format 100 101 # First grep for message type lines in bnc-logfile and write them to local temp. directory 102 # NOTE: 'sort -u' because Ephemeries message-types 1019 (GPS), 1020 (GLONASS), 1045 (Galileo) come 103 # for every sat. at the same time/second. This is done for getting the repetition rate 104 system ("grep \"Received message type\" $logfile | sort -u > $casterMessTypeFile") == 0 105 or ERROR "Fehler: $!"; 106 107 # -------------------------------------------- 108 # Get message types foreach station/mountpoint 109 # -------------------------------------------- 110 my $cmd = "cat $casterMessTypeFile | awk '{print \$3, \$7}' | sort -u"; 111 my @messTypes = `$cmd`; # ['DARX1: 1004\n','DARX1: 1006\n',... ] 112 if ( scalar @messTypes < 1 ) { 113 ERROR "Could not retrieve message types from file $casterMessTypeFile"; 114 return; 115 } 116 117 # Note: Skip first 1500 lines because BNC is weird here, all lines with same timestamp, buffer problem? 118 119 # ------------------------------------------------------ 120 # Guess repetition rate for each mountpoint/message-type 121 # ------------------------------------------------------ 122 # For that get the first $minSamples appearances of mountp with same message type 123 # and build the differences between them 124 my $minSamples = 4; 125 foreach my $mpType (@messTypes) { 126 chomp $mpType; # 'AUBG3: 1004' 127 my ( $mp, $mt ) = split ( /:\s*/, $mpType ); 128 my $cmd = "grep \"$mp: Received message type $mt\" $logfile"; 129 my @rows = `$cmd`; 130 if ( scalar @rows < 1 ) { 131 ERROR "Could not retrieve message types for $mpType from file $casterMessTypeFile"; 132 next; 133 } 134 135 if ( scalar @rows <= $minSamples ) { 136 WARN "Could not guess repetition rate for message type $mpType: only " . scalar @rows . " matches found"; 137 next; 138 } 139 140 my $repRate = _computeMessTypRepetitonRate( \@rows, $caAbbr ); 141 if ($repRate) { 142 $mpType .= '(' . $repRate . ')'; 143 } 144 } # ----- end foreach messageType ----- 145 146 #if ( unlink $casterMessTypeFile ) { TRACE "Removed file [$casterMessTypeFile]" } 147 148 # Return an HASH OF ARRAYS with mp as key and the list of messTypes as value 149 my %messTypesHash; 150 foreach (@messTypes) { 151 my @ele = split ( ': ', $_ ); 152 my $mp = shift @ele; 153 push ( @{ $messTypesHash{$mp} }, shift @ele ); 154 } 155 156 return \%messTypesHash; 84 my ( $logfile, $caAbbr, $mytmpPath ) = @_; 85 86 unless ( -s $logfile ) { 87 ERROR "File [$logfile] is empty or does not exist"; 88 return; 89 } 90 91 my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.messtyps' ); 92 my $casterMessTypeFile = $tmp->filename; 93 94 #my $caster = $logfilename =~ s/\.log\.messtyps//r; 95 #INFO "Process caster '$caster'"; 96 97 INFO "Process $logfile"; 98 99 # scan beginns with that line: 16-02-18 23:58:02 WTZ37: Get data in RTCM 3.x format 100 101 # First grep for message type lines in bnc-logfile and write them to local temp. directory 102 # NOTE: 'sort -u' because Ephemeries message-types 1019 (GPS), 1020 (GLONASS), 1045 (Galileo) come 103 # for every sat. at the same time/second. This is done for getting the repetition rate 104 system( 105 "grep \"Received message type\" $logfile | sort -u > $casterMessTypeFile" 106 ) == 0 107 or ERROR "Fehler: $!"; 108 109 # -------------------------------------------- 110 # Get message types foreach station/mountpoint 111 # -------------------------------------------- 112 my $cmd = "cat $casterMessTypeFile | awk '{print \$3, \$7}' | sort -u"; 113 my @messTypes = `$cmd`; # ['DARX1: 1004\n','DARX1: 1006\n',... ] 114 if ( scalar @messTypes < 1 ) { 115 ERROR "Could not retrieve message types from file $casterMessTypeFile"; 116 return; 117 } 118 119 # Note: Skip first 1500 lines because BNC is weird here, all lines with same timestamp, buffer problem? 120 121 # ------------------------------------------------------ 122 # Guess repetition rate for each mountpoint/message-type 123 # ------------------------------------------------------ 124 # For that get the first $minSamples appearances of mountp with same message type 125 # and build the differences between them 126 my $minSamples = 4; 127 foreach my $mpType (@messTypes) { 128 chomp $mpType; # 'AUBG3: 1004' 129 my ( $mp, $mt ) = split( /:\s*/, $mpType ); 130 my $cmd = "grep \"$mp: Received message type $mt\" $logfile"; 131 my @rows = `$cmd`; 132 if ( scalar @rows < 1 ) { 133 ERROR 134 "Could not retrieve message types for $mpType from file $casterMessTypeFile"; 135 next; 136 } 137 138 if ( scalar @rows <= $minSamples ) { 139 WARN 140 "Could not guess repetition rate for message type $mpType: only " 141 . scalar @rows 142 . " matches found"; 143 next; 144 } 145 146 my $repRate = _computeMessTypRepetitonRate( \@rows, $caAbbr ); 147 if ($repRate) { 148 $mpType .= '(' . $repRate . ')'; 149 } 150 } # ----- end foreach messageType ----- 151 152 #if ( unlink $casterMessTypeFile ) { TRACE "Removed file [$casterMessTypeFile]" } 153 154 # Return an HASH OF ARRAYS with mp as key and the list of messTypes as value 155 my %messTypesHash; 156 foreach (@messTypes) { 157 my @ele = split( ': ', $_ ); 158 my $mp = shift @ele; 159 push( @{ $messTypesHash{$mp} }, shift @ele ); 160 } 161 162 return \%messTypesHash; 157 163 } 158 164 … … 169 175 # ============================================================================= 170 176 sub _computeMessTypRepetitonRate { 171 my ( $rows, $caAbbr ) = @_; 172 173 my $maxGap = 600; # if gap > 10min then we guess it is a new scan 174 175 $rows->[0] =~ /.{18}([a-x0-9]+): Received message type (\d+)/i; 176 my $stat = $1; 177 my $mestp = $2; 178 179 # Create list of unix timestamps 180 my @scans; 181 my $scan = 0; 182 my ( $prevTime, $deltaT ) = ( 0, 0 ); 183 foreach (@$rows) { 184 my $uxtime = date2unix( substr ( $_, 0, 17 ) ); 185 if ( !$uxtime ) { 186 ERROR "Could not parse date from line $_"; 187 next; 188 } 189 $deltaT = $uxtime - $prevTime; 190 next if ( $deltaT == 0 ); # e.g. eph 1019,1020 one message for each sat. 191 next if ( $deltaT <= 1 && $mestp =~ /10(19|20|42|43|44|45|46)|63/ ); 192 if ( $prevTime && $deltaT > $maxGap ) { 193 $scan++; 194 } 195 push ( @{ $scans[$scan] }, $uxtime ); 196 $prevTime = $uxtime; 197 } 198 199 my @repRates; 200 my $highest_nof_diffs = 0; 201 foreach (@scans) { 202 my @timestamps = @{$_}; 203 204 # Compute the differences 205 my @diffs; 206 for ( my $i = 1; $i <= $#timestamps; $i++ ) { 207 push ( @diffs, $timestamps[$i] - $timestamps[ $i - 1 ] ); 208 } 209 my $nof_diffs = scalar @diffs; 210 211 if ( $nof_diffs < 2 ) { 212 WARN("$stat: $mestp: only $nof_diffs diffs"); 213 next; 214 } 215 216 my ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats( pdl \@diffs ); 217 $mean = sprintf ( "%.0f", $mean ); 218 $rms_n = sprintf ( "%.02f", $rms_n ); 219 print $stat, ": ", $mestp, ": ", join ( ' ', @diffs ), "[Sig: $mean, $rms_n]\n"; 220 221 if ( $rms_n > 10 ) { 222 WARN("$stat: $mestp: RMS too high: $rms_n"); 223 next; 224 } 225 226 # get the most frequent value 227 my %counti = (); 228 $counti{$_}++ foreach (@diffs); 229 my ( $ni, $mfv ) = ( 0, 0 ); 230 while ( my ( $k, $v ) = each %counti ) { 231 if ( $v > $ni ) { 232 $ni = $v; 233 $mfv = $k; 234 } 235 } 236 237 my $rounded_val = $mfv; # init 238 foreach ( ( 1, 5, 10, 15, 30, 60, 120, 150, 300 ) ) { # most likely values 239 my $mdiff = abs ( $mfv - $_ ); 240 if ( $mdiff <= 2 ) { 241 $rounded_val = $_; 242 } 243 } 244 push ( @repRates, [ $rounded_val, $nof_diffs ] ); 245 246 if ( $nof_diffs > $highest_nof_diffs ) { 247 $highest_nof_diffs = $nof_diffs; 248 } 249 } # ----- end foreach scan ----- 250 251 my @mostLikelyRates = grep { $_->[1] == $highest_nof_diffs } @repRates; 252 my $mostLikelyRate = $mostLikelyRates[0]->[0]; 253 foreach (@repRates) { 254 if ( abs ( $_->[0] - $mostLikelyRate ) > 2 ) { 255 ERROR "$stat: $caAbbr: $mestp: repetition rates from different scans differ: $mostLikelyRate $_->[0]"; 256 if ( scalar @repRates == 2 ) { 257 return; 258 } 259 } 260 } 261 262 return $mostLikelyRate; 177 my ( $rows, $caAbbr ) = @_; 178 179 my $maxGap = 600; # if gap > 10min then we guess it is a new scan 180 181 $rows->[0] =~ /.{18}([a-x0-9]+): Received message type (\d+)/i; 182 my $stat = $1; 183 my $mestp = $2; 184 185 # Create list of unix timestamps 186 my @scans; 187 my $scan = 0; 188 my ( $prevTime, $deltaT ) = ( 0, 0 ); 189 foreach (@$rows) { 190 my $uxtime = date2unix( substr( $_, 0, 17 ) ); 191 if ( !$uxtime ) { 192 ERROR "Could not parse date from line $_"; 193 next; 194 } 195 $deltaT = $uxtime - $prevTime; 196 next if ( $deltaT == 0 ); # e.g. eph 1019,1020 one message for each sat. 197 next if ( $deltaT <= 1 && $mestp =~ /10(19|20|42|43|44|45|46)|63/ ); 198 if ( $prevTime && $deltaT > $maxGap ) { 199 $scan++; 200 } 201 push( @{ $scans[$scan] }, $uxtime ); 202 $prevTime = $uxtime; 203 } 204 205 my @repRates; 206 my $highest_nof_diffs = 0; 207 foreach (@scans) { 208 my @timestamps = @{$_}; 209 210 # Compute the differences 211 my @diffs; 212 for ( my $i = 1 ; $i <= $#timestamps ; $i++ ) { 213 push( @diffs, $timestamps[$i] - $timestamps[ $i - 1 ] ); 214 } 215 my $nof_diffs = scalar @diffs; 216 217 if ( $nof_diffs < 2 ) { 218 WARN("$stat: $mestp: only $nof_diffs diffs"); 219 next; 220 } 221 222 my ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = 223 stats( pdl \@diffs ); 224 $mean = sprintf( "%.0f", $mean ); 225 $rms_n = sprintf( "%.02f", $rms_n ); 226 print $stat, ": ", $mestp, ": ", join( ' ', @diffs ), 227 "[Sig: $mean, $rms_n]\n"; 228 229 if ( $rms_n > 10 ) { 230 WARN("$stat: $mestp: RMS too high: $rms_n"); 231 next; 232 } 233 234 # get the most frequent value 235 my %counti = (); 236 $counti{$_}++ foreach (@diffs); 237 my ( $ni, $mfv ) = ( 0, 0 ); 238 while ( my ( $k, $v ) = each %counti ) { 239 if ( $v > $ni ) { 240 $ni = $v; 241 $mfv = $k; 242 } 243 } 244 245 my $rounded_val = $mfv; # init 246 foreach ( ( 1, 5, 10, 15, 30, 60, 120, 150, 300 ) ) 247 { # most likely values 248 my $mdiff = abs( $mfv - $_ ); 249 if ( $mdiff <= 2 ) { 250 $rounded_val = $_; 251 } 252 } 253 push( @repRates, [ $rounded_val, $nof_diffs ] ); 254 255 if ( $nof_diffs > $highest_nof_diffs ) { 256 $highest_nof_diffs = $nof_diffs; 257 } 258 } # ----- end foreach scan ----- 259 260 my @mostLikelyRates = grep { $_->[1] == $highest_nof_diffs } @repRates; 261 my $mostLikelyRate = $mostLikelyRates[0]->[0]; 262 foreach (@repRates) { 263 if ( abs( $_->[0] - $mostLikelyRate ) > 2 ) { 264 ERROR 265 "$stat: $caAbbr: $mestp: repetition rates from different scans differ: $mostLikelyRate $_->[0]"; 266 if ( scalar @repRates == 2 ) { 267 return; 268 } 269 } 270 } 271 272 return $mostLikelyRate; 263 273 } 264 274 … … 274 284 # ============================================================================= 275 285 sub parseConfig { 276 my ($confFile) = @_; 277 278 -s $confFile || LOGDIE "BNC config file \"$confFile\" does not exist\n"; 279 TRACE "Parse BNC config file $confFile"; 280 open ( my $INP, '<', $confFile ) || die "Could not open file '$confFile': $!"; 281 my @confLines = <$INP>; 282 close ($INP); 283 284 my %conf; 285 my $section; # [General], [PPP] 286 foreach (@confLines) { 287 chomp; 288 s/#.*//; # entfernt Kommentare 289 s/^\s*//; # whitespace am Anfang entfernen 290 s/\s+$//; # entfernt alle whitespaces am Ende 291 next unless length; 292 if ( $_ =~ /\[(\S+)\]/ ) { $section = $1 } 293 next if ( !$section ); 294 my ( $key, $val ) = split ( /\s*=\s*/, $_, 2 ); 295 if ( !defined $val ) { $val = "" } 296 297 if ( $key eq "mountPoints" ) { 298 299 # Simple parsing 300 $val =~ s/^\/\///; 301 my @mpts = split ( /,\s?\/{2}/, $val ); 302 $conf{$section}->{$key} = \@mpts; 303 304 # Extended parsing 305 my @mpts_def = (); 306 foreach (@mpts) { 307 308 # user:passwd@igs-ip.net:2101/ASPA0 RTCM_3.0 ASM -14.33 189.28 no 1 309 if ( $_ =~ 310 /^([\w-]+):(.+[^@])@([\w\.-]+):(\d{3,5})\/([-\w]+) ([\w\.]+) ?(\w{3})? ([\+\-\d\.]+) ([\+\-\d\.]+) no (\w+)/i 311 ) 312 { 313 push ( @mpts_def, { caster => $3, port => $4, mp => $5, ntripVers => $10 } ); 314 } 315 else { ERROR "$confFile: Could not parse mountPoints string $_" } 316 } 317 $conf{$section}->{'mountPoints_parsed'} = \@mpts_def; 318 } 319 elsif ( $key eq "cmbStreams" ) { 320 my @cmbStrs = split ( /\s*,\s*/, $val ); 321 foreach (@cmbStrs) { 322 s/"//g; 323 s/\s+$//; # entfernt alle whitespaces am Ende 324 } 325 $conf{$section}->{$key} = \@cmbStrs; 326 } 327 else { $conf{$section}->{$key} = $val } 328 } 329 330 my @nofPar = keys %conf; 331 if ( scalar @nofPar < 1 ) { 332 ERROR "No parameter found in BNC conf \"$confFile\""; 333 return; 334 } 335 return \%conf; 286 my ($confFile) = @_; 287 288 -s $confFile || LOGDIE "BNC config file \"$confFile\" does not exist\n"; 289 TRACE "Parse BNC config file $confFile"; 290 open( my $INP, '<', $confFile ) 291 || die "Could not open file '$confFile': $!"; 292 my @confLines = <$INP>; 293 close($INP); 294 295 my %conf; 296 my $section; # [General], [PPP] 297 foreach (@confLines) { 298 chomp; 299 s/#.*//; # entfernt Kommentare 300 s/^\s*//; # whitespace am Anfang entfernen 301 s/\s+$//; # entfernt alle whitespaces am Ende 302 next unless length; 303 if ( $_ =~ /\[(\S+)\]/ ) { $section = $1 } 304 next if ( !$section ); 305 my ( $key, $val ) = split( /\s*=\s*/, $_, 2 ); 306 if ( !defined $val ) { $val = "" } 307 308 if ( $key eq "mountPoints" ) { 309 310 # Simple parsing 311 $val =~ s/^\/\///; 312 my @mpts = split( /,\s?\/{2}/, $val ); 313 $conf{$section}->{$key} = \@mpts; 314 315 # Extended parsing 316 my @mpts_def = (); 317 foreach (@mpts) { 318 319 # user:passwd@igs-ip.net:2101/ASPA0 RTCM_3.0 ASM -14.33 189.28 no 1 320 if ( $_ =~ 321 /^([\w-]+):(.+[^@])@([\w\.-]+):(\d{3,5})\/([-\w]+) ([\w\.]+) ?(\w{3})? ([\+\-\d\.]+) ([\+\-\d\.]+) no (\w+)/i 322 ) 323 { 324 push( 325 @mpts_def, 326 { 327 caster => $3, 328 port => $4, 329 mp => $5, 330 ntripVers => $10 331 } 332 ); 333 } 334 else { 335 ERROR "$confFile: Could not parse mountPoints string $_"; 336 } 337 } 338 $conf{$section}->{'mountPoints_parsed'} = \@mpts_def; 339 } 340 elsif ( $key eq "cmbStreams" ) { 341 my @cmbStrs = split( /\s*,\s*/, $val ); 342 foreach (@cmbStrs) { 343 s/"//g; 344 s/\s+$//; # entfernt alle whitespaces am Ende 345 } 346 $conf{$section}->{$key} = \@cmbStrs; 347 } 348 else { $conf{$section}->{$key} = $val } 349 } 350 351 my @nofPar = keys %conf; 352 if ( scalar @nofPar < 1 ) { 353 ERROR "No parameter found in BNC conf \"$confFile\""; 354 return; 355 } 356 return \%conf; 336 357 } 337 358 … … 348 369 # ============================================================================= 349 370 sub parseLogfile { 350 my $file = shift; 351 my $sampling = shift // 1; 352 my $logMode = shift // 0; 353 354 open ( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n"; 355 356 # Goto last position from last read 357 #my $fPos = filePosition($file); 358 #TRACE "Current file pos: $fPos"; 359 $logMode && seek ( $fh, &Common::filePosition($file), 0 ); 360 361 #$logMode && seek ( $fh, $fPos, 0 ); 362 my $ln = ""; 363 my ( @hlp, @epochs, @latencies, @restarts ); 364 my $rec = {}; 365 while (<$fh>) { 366 chomp ( $ln = $_ ); 367 $rec = {}; 368 369 if ( $ln =~ /\bNEU/ ) { # NEU displacements 370 @hlp = split ( /\s+/, $ln ); 371 my $tp = Time::Piece->strptime( substr ( $hlp[2], 0, 19 ), '%Y-%m-%d_%H:%M:%S' ); 372 373 if ( $hlp[14] eq '-nan' || $hlp[15] eq '-nan' || $hlp[16] eq '-nan' ) { 374 WARN("$hlp[2] $hlp[3]: NEU displacements are NAN"); 375 next; 376 } 377 378 #DEBUG ($tp->epoch, $hlp[3]); 379 push ( 380 @epochs, 381 { 382 time => $tp->epoch, 383 site => $hlp[3], 384 dN => $hlp[14], 385 dE => $hlp[15], 386 dU => $hlp[16], 387 TRP => $hlp[18] + $hlp[19], 388 } 389 ); 390 } 391 elsif ( index ( $ln, "latency", 25 ) > 1 ) { 371 my $file = shift; 372 my $sampling = shift // 1; 373 my $logMode = shift // 0; 374 375 open( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n"; 376 377 # Goto last position from last read 378 #my $fPos = filePosition($file); 379 #TRACE "Current file pos: $fPos"; 380 $logMode && seek( $fh, &Common::filePosition($file), 0 ); 381 382 #$logMode && seek ( $fh, $fPos, 0 ); 383 my $ln = ""; 384 my ( @hlp, @epochs, @latencies, @restarts ); 385 my $rec = {}; 386 while (<$fh>) { 387 chomp( $ln = $_ ); 388 $rec = {}; 389 390 if ( $ln =~ /\bNEU/ ) { # NEU displacements 391 @hlp = split( /\s+/, $ln ); 392 my $tp = Time::Piece->strptime( substr( $hlp[2], 0, 19 ), 393 '%Y-%m-%d_%H:%M:%S' ); 394 395 if ( $hlp[14] eq '-nan' 396 || $hlp[15] eq '-nan' 397 || $hlp[16] eq '-nan' ) 398 { 399 WARN("$hlp[2] $hlp[3]: NEU displacements are NAN"); 400 next; 401 } 402 403 #DEBUG ($tp->epoch, $hlp[3]); 404 push( 405 @epochs, 406 { 407 time => $tp->epoch, 408 site => $hlp[3], 409 dN => $hlp[14], 410 dE => $hlp[15], 411 dU => $hlp[16], 412 TRP => $hlp[18] + $hlp[19], 413 } 414 ); 415 } 416 elsif ( index( $ln, "latency", 25 ) > 1 ) { 392 417 393 418 # DEBUG ($ln); 394 419 # altes format: 15-10-06 15:29:02 POTS0: Mean latency 2.34 sec, min 1.58, max 3, rms 0.48, 43 epochs, 17 gaps 395 420 # neu in BNC 2.12.4: 17-06-06 15:35:02 OHI37 Observations: Mean latency 1.51 sec, min 0.57, max 2.7, rms 0.5, 203 epochs, 73 gaps 396 @hlp = split ( /\s+/, $ln ); 397 398 # old latency log format 399 if ( $hlp[2] =~ /:$/ ) { 400 splice @hlp, 3, 0, 'Placeholder:'; 401 $hlp[2] =~ s/:$//; 402 } 403 $hlp[3] =~ s/:$//; 404 405 my $tp = Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' ); 406 $rec = { 407 time => $tp->epoch, 408 mp => $hlp[2], 409 meanLat => $hlp[6] + 0.0, 410 epochs => int ( $hlp[14] ), 411 type => $hlp[3] 412 }; 413 414 # Unter bestimmten Bedingungen werden die gaps nicht rausgeschrieben! 415 if ( $ln =~ /gaps/ ) { 416 $rec->{'gaps'} = int ( $hlp[16] ); 417 } 418 419 push ( @latencies, $rec ); 420 } 421 elsif ( index ( $ln, "Start BNC" ) > 1 ) { 422 423 # 17-06-13 07:06:58 ========== Start BNC v2.12.3 (LINUX) ========== 424 @hlp = split ( /\s+/, $ln ); 425 my $tp = Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' ); 426 push ( 427 @restarts, 428 { 429 time => $tp->epoch, 430 bncvers => $hlp[5] 431 } 432 ); 433 } 434 435 } # ----- next line ----- 436 437 $logMode && &Common::filePosition( $file, tell ($fh) ); # Remember pos for next read 438 close $fh; 439 440 # Sampling must be done afterwords, for each station separated! 441 my @epochs_sampled; 442 my @sites = map { $_->{'site'} } @epochs; 443 444 #@sites = uniq @sites; 445 my %hlp1 = (); 446 @sites = grep { !$hlp1{$_}++ } @sites; 447 foreach my $s (@sites) { 448 my $epoch_selected = 0; 449 foreach my $rec (@epochs) { 450 next if ( $rec->{'site'} ne $s ); 451 if ( $rec->{'time'} - $epoch_selected >= $sampling ) { 452 push ( @epochs_sampled, $rec ); 453 $epoch_selected = $rec->{'time'}; 454 } 455 } 456 } 457 458 my %data = ( 459 EPOCHS => \@epochs_sampled, 460 LATENCIES => \@latencies, 461 RESTARTS => \@restarts 462 ); 463 464 return \%data; 421 @hlp = split( /\s+/, $ln ); 422 423 # old latency log format 424 if ( $hlp[2] =~ /:$/ ) { 425 splice @hlp, 3, 0, 'Placeholder:'; 426 $hlp[2] =~ s/:$//; 427 } 428 $hlp[3] =~ s/:$//; 429 430 my $tp = 431 Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' ); 432 $rec = { 433 time => $tp->epoch, 434 mp => $hlp[2], 435 meanLat => $hlp[6] + 0.0, 436 epochs => int( $hlp[14] ), 437 type => $hlp[3] 438 }; 439 440 # Unter bestimmten Bedingungen werden die gaps nicht rausgeschrieben! 441 if ( $ln =~ /gaps/ ) { 442 $rec->{'gaps'} = int( $hlp[16] ); 443 } 444 445 push( @latencies, $rec ); 446 } 447 elsif ( index( $ln, "Start BNC" ) > 1 ) { 448 449 # 17-06-13 07:06:58 ========== Start BNC v2.12.3 (LINUX) ========== 450 @hlp = split( /\s+/, $ln ); 451 my $tp = 452 Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' ); 453 push( 454 @restarts, 455 { 456 time => $tp->epoch, 457 bncvers => $hlp[5] 458 } 459 ); 460 } 461 462 } # ----- next line ----- 463 464 $logMode 465 && &Common::filePosition( $file, tell($fh) ); # Remember pos for next read 466 close $fh; 467 468 # Sampling must be done afterwords, for each station separated! 469 my @epochs_sampled; 470 my @sites = map { $_->{'site'} } @epochs; 471 472 #@sites = uniq @sites; 473 my %hlp1 = (); 474 @sites = grep { !$hlp1{$_}++ } @sites; 475 foreach my $s (@sites) { 476 my $epoch_selected = 0; 477 foreach my $rec (@epochs) { 478 next if ( $rec->{'site'} ne $s ); 479 if ( $rec->{'time'} - $epoch_selected >= $sampling ) { 480 push( @epochs_sampled, $rec ); 481 $epoch_selected = $rec->{'time'}; 482 } 483 } 484 } 485 486 my %data = ( 487 EPOCHS => \@epochs_sampled, 488 LATENCIES => \@latencies, 489 RESTARTS => \@restarts 490 ); 491 492 return \%data; 465 493 } 466 494 … … 478 506 # ============================================================================= 479 507 sub parsePPPLogfile { 480 my $file = shift; 481 my $sampling = shift // 1; 482 my $goBackSecs = shift // 0; 483 my $logMode = shift // 0; 484 485 if ($logMode) { $goBackSecs = 0 } 486 487 my $startSec; 488 if ($goBackSecs) { 489 $startSec = time () - $goBackSecs; 490 } 491 my $epo; 492 my $old_epochSec = 0; 493 my $epochSec = 0; 494 my $epochDiff = 0; 495 my ( @hlp, @N, @E, @U, %SATNUM, @TRP); 496 my ( @EPOCH, ); 497 my ( %RECCLK, %AMB, %RES, %ELE, %ION, %BIA); 498 my ( $station, $lki, $sys, $sat, $amb); 499 open ( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n"; 500 501 # Goto last position from last read 502 #my $fPos = filePosition($file); 503 #TRACE "Current file pos: $fPos"; 504 $logMode && seek ( $fh, filePosition($file), 0 ); 505 506 #$logMode && seek ( $fh, $fPos, 0 ); 507 my $ln = ""; 508 while (<$fh>) { 509 chomp ( $ln = $_ ); 510 511 if ( $ln =~ /\bof Epoch\b/ ) { 512 513 # PPP of Epoch 2015-08-27_14:00:15.000 514 if ( $ln =~ /PPP of Epoch (\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})\.\d+/ ) { 515 $epo = $1; #print "$epo\n"; 516 } 517 else { ERROR "strange line: \"$ln\""; next } 518 519 my $tp = Time::Piece->strptime( $epo, '%Y-%m-%d_%H:%M:%S' ); 520 $epochSec = $tp->epoch(); 521 $epochDiff = $epochSec - $old_epochSec; 522 next; 523 } 524 525 next if ( !$epo ); 526 next if ( defined $startSec && $epochSec < $startSec ); 527 next if ( $epochDiff && $epochDiff < $sampling ); 528 529 @hlp = split ( /\s+/, $ln ); 530 531 if ( $ln =~ /\bdN\b/ ) { 532 push ( @EPOCH, $epochSec ); # besser $epo ? 533 $old_epochSec = $epochSec; 534 535 #2015-08-27_13:59:50.000 DIEP1 X = 3842152.9054 +- 0.0242 Y = 563402.0331 +- 0.0176 Z = 5042888.5182 +- 0.0319 dN = 0.0130 +- 0.0193 dE = -0.0032 +- 0.0178 dU = -0.0248 +- 0.0349 536 $station = $hlp[1]; 537 538 if ( $hlp[19] eq '-nan' || $hlp[24] eq '-nan' || $hlp[29] eq '-nan' ) { 539 WARN("$hlp[0] $station: NEU displacements are NAN"); 540 } 541 542 push @N, $hlp[19]; 543 push @E, $hlp[24]; 544 push @U, $hlp[29]; 545 } 546 elsif ( ( $ln =~ /\bAMB\b/ ) && ( $ln !~ /RESET/ ) ) { 547 548 # 2015-08... AMB lIF G04 253.0000 -8.9924 +- 1.7825 el = 22.03 epo = 86 549 $lki = $hlp[2]; 550 $sat = $hlp[3]; 551 $sys = substr ( $sat, 0, 1 ); 552 $amb = $hlp[4] + $hlp[5]; 553 push @{ $AMB{$lki}{$sys}{$sat}{EPOCH} }, $epochSec; 554 push @{ $AMB{$lki}{$sys}{$sat}{DATA} }, $amb; 555 push @{ $AMB{$lki}{$sys}{$sat}{NUMEPO} }, $hlp[13]; 556 push @{ $ELE{$sys}{$sat}{EPOCH} }, $epochSec; 557 push @{ $ELE{$sys}{$sat}{DATA} }, $hlp[10]; 558 } 559 elsif ( $ln =~ /\bRES\b/ && $ln !~ /Neglected/ ) { 560 561 # 2015-08... RES lIF G30 -0.0076 562 $sat = $hlp[3]; 563 $lki = $hlp[2]; 564 $sys = substr ( $sat, 0, 1 ); 565 566 #print "$epo $lki $sys $sat $res\n"; 567 push @{ $RES{$lki}{$sys}{$sat}{EPOCH} }, $epochSec; 568 push @{ $RES{$lki}{$sys}{$sat}{DATA} }, $hlp[4]; 569 } 570 elsif ( ( $ln =~ /\bION\b/ ) && ( $ln !~ /RESET/ ) ) { 571 572 # 2018-12-01_20:37:58.000 ION G02 0.0000 -0.3277 +- 2.4663 573 $sat = $hlp[2]; 574 $sys = substr ( $sat, 0, 1 ); 575 push @{ $ION{$sys}{$sat}{EPOCH} }, $epochSec; 576 push @{ $ION{$sys}{$sat}{DATA} }, $hlp[4]; 577 } 578 elsif ( ( $ln =~ /\bBIA\b/ ) && ( $ln !~ /RESET/ ) ) { 579 580 # 2020-12-09_00:55:19.000 BIA c1 G 0.0000 +2.5149 +- 9.6543 581 $lki = $hlp[2]; 582 $sys = $hlp[3]; 583 push @{ $BIA{$lki}{$sys}{EPOCH} }, $epochSec; 584 push @{ $BIA{$lki}{$sys}{DATA} }, $hlp[4] + $hlp[5]; 585 } 586 elsif ( $ln =~ /\bSATNUM\b/ ) { # 2015-09... SATNUM G 8 587 push ( @{ $SATNUM{ $hlp[2] } }, $hlp[3] ); 588 } 589 elsif ( $ln =~ /\bTRP\b/ ) { # 2015-08... TRP 2.3803 +0.1009 +- 0.0324 590 push ( @TRP, $hlp[2] + $hlp[3] ); 591 } 592 elsif ( $ln =~ /\bREC_CLK\b/) { 593 # 2024-10-20_03:57:30.000 RECCLK G 0.0000 -1.7861 +- 0.5268 594 $sys = $hlp[2]; 595 push @{ $RECCLK{$sys}{EPOCH} }, $epochSec; 596 push @{ $RECCLK{$sys}{DATA} }, $hlp[3] + $hlp[4]; 597 } 598 } # ----- next line ----- 599 600 $logMode && filePosition( $file, tell ($fh) ); # Remember pos for next read 601 close $fh; 602 603 my $nof_epochs = scalar @EPOCH; 604 DEBUG( "$station: epochs:$nof_epochs, North displac.: " 605 . scalar @N 606 . ", East displac.: " 607 . scalar @E 608 . ", Up displac.: " 609 . scalar @U 610 . ", TRP:" 611 . scalar @TRP 612 ); 613 if ( $nof_epochs != scalar @N ) { LOGDIE "number of epochs and residuals not equal\n" } 614 if ( $nof_epochs != scalar @TRP ) { LOGDIE "number of epochs and TRP not equal\n" } 615 616 617 if ( !$station ) { WARN "could not grep stationname from file: $file\n" } 618 619 my %data = ( 620 EPOCH => \@EPOCH, 621 N => \@N, 622 E => \@E, 623 U => \@U, 624 SATNUM => \%SATNUM, 625 TRP => \@TRP, 626 RECCLK => \%RECCLK, 627 RES => \%RES, 628 AMB => \%AMB, 629 ELE => \%ELE, 630 ION => \%ION, 631 BIA => \%BIA, 632 ); 633 634 return ( $station, \%data, 0 ); 508 my $file = shift; 509 my $sampling = shift // 1; 510 my $goBackSecs = shift // 0; 511 my $logMode = shift // 0; 512 513 if ($logMode) { $goBackSecs = 0 } 514 515 my $startSec; 516 if ($goBackSecs) { 517 $startSec = time() - $goBackSecs; 518 } 519 my $epo; 520 my $old_epochSec = 0; 521 my $epochSec = 0; 522 my $epochDiff = 0; 523 my ( @hlp, @N, @E, @U, @ISFIX, @NUMFIX, @TRP ); 524 my ( @EPOCH, ); 525 my ( %SATNUM, %RECCLK, %AMB, %RES, %ELE, %ION, %BIA ); 526 my ( $station, $lki, $sys, $sat, $amb ); 527 open( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n"; 528 529 # Goto last position from last read 530 #my $fPos = filePosition($file); 531 #TRACE "Current file pos: $fPos"; 532 $logMode && seek( $fh, filePosition($file), 0 ); 533 534 #$logMode && seek ( $fh, $fPos, 0 ); 535 my $ln = ""; 536 while (<$fh>) { 537 chomp( $ln = $_ ); 538 539 if ( $ln =~ /\bof Epoch\b/ ) { 540 541 # PPP of Epoch 2015-08-27_14:00:15.000 542 if ( $ln =~ 543 /PPP of Epoch (\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})\.\d+/ ) 544 { 545 $epo = $1; #print "$epo\n"; 546 } 547 else { ERROR "strange line: \"$ln\""; next } 548 549 my $tp = Time::Piece->strptime( $epo, '%Y-%m-%d_%H:%M:%S' ); 550 $epochSec = $tp->epoch(); 551 $epochDiff = $epochSec - $old_epochSec; 552 next; 553 } 554 555 next if ( !$epo ); 556 next if ( defined $startSec && $epochSec < $startSec ); 557 next if ( $epochDiff && $epochDiff < $sampling ); 558 559 @hlp = split( /\s+/, $ln ); 560 my $numFix = 0; 561 my $isFix; 562 my $strFix = "fix"; 563 if ( $ln =~ /\bdN\b/ ) { 564 push( @EPOCH, $epochSec ); # besser $epo ? 565 $old_epochSec = $epochSec; 566 567 #2025-11-29_16:55:09.000 WTZR00DEU0 X = 4075580.2482 +- 0.0500 Y = 931854.1736 +- 0.0314 Z = 4801568.3044 +- 0.0591 dN = 0.0074 +- 0.0407 dE = 0.0895 +- 0.0284 dU = -0.0072 +- 0.0672 fix 96 % 568 $station = $hlp[1]; 569 570 if ( $hlp[19] eq '-nan' 571 || $hlp[24] eq '-nan' 572 || $hlp[29] eq '-nan' ) 573 { 574 WARN("$hlp[0] $station: NEU displacements are NAN"); 575 } 576 577 push @N, $hlp[19]; 578 push @E, $hlp[24]; 579 push @U, $hlp[29]; 580 581 if ( $hlp[32] eq $strFix ) { 582 $isFix = 1; 583 $numFix = int( $hlp[33] ); 584 } 585 else { 586 $isFix = 0; 587 $numFix = 0; 588 } 589 push @ISFIX, $isFix; 590 push @NUMFIX, $numFix; 591 } 592 elsif ( ( $ln =~ /\bAMB\b/ ) && ( $ln !~ /RESET/ ) ) { 593 594 # 2015-08... AMB lIF G04 253.0000 -8.9924 +- 1.7825 el = 22.03 epo = 86 595 $lki = $hlp[2]; 596 $sat = $hlp[3]; 597 $sys = substr( $sat, 0, 1 ); 598 $amb = $hlp[4] + $hlp[5]; 599 push @{ $AMB{$lki}{$sys}{$sat}{EPOCH} }, $epochSec; 600 push @{ $AMB{$lki}{$sys}{$sat}{DATA} }, $amb; 601 push @{ $AMB{$lki}{$sys}{$sat}{NUMEPO} }, $hlp[13]; 602 push @{ $ELE{$sys}{$sat}{EPOCH} }, $epochSec; 603 push @{ $ELE{$sys}{$sat}{DATA} }, $hlp[10]; 604 } 605 elsif ( $ln =~ /\bRES\b/ && $ln !~ /Neglected/ ) { 606 607 # 2015-08... RES lIF G30 -0.0076 608 $sat = $hlp[3]; 609 $lki = $hlp[2]; 610 $sys = substr( $sat, 0, 1 ); 611 612 #print "$epo $lki $sys $sat $res\n"; 613 push @{ $RES{$lki}{$sys}{$sat}{EPOCH} }, $epochSec; 614 push @{ $RES{$lki}{$sys}{$sat}{DATA} }, $hlp[4]; 615 } 616 elsif ( ( $ln =~ /\bION\b/ ) && ( $ln !~ /RESET/ ) ) { 617 618 # 2018-12-01_20:37:58.000 ION G02 0.0000 -0.3277 +- 2.4663 619 $sat = $hlp[2]; 620 $sys = substr( $sat, 0, 1 ); 621 push @{ $ION{$sys}{$sat}{EPOCH} }, $epochSec; 622 push @{ $ION{$sys}{$sat}{DATA} }, $hlp[4]; 623 } 624 elsif ( ( $ln =~ /\bBIA\b/ ) && ( $ln !~ /RESET/ ) ) { 625 626 # 2020-12-09_00:55:19.000 BIA c1 G 0.0000 +2.5149 +- 9.6543 627 $lki = $hlp[2]; 628 $sys = $hlp[3]; 629 push @{ $BIA{$lki}{$sys}{EPOCH} }, $epochSec; 630 push @{ $BIA{$lki}{$sys}{DATA} }, $hlp[4] + $hlp[5]; 631 } 632 elsif ( $ln =~ /\bSATNUM\b/ ) { # 2015-09... SATNUM G 8 633 push( @{ $SATNUM{ $hlp[2] } }, $hlp[3] ); 634 } 635 elsif ( $ln =~ /\bTRP\b/ ) { # 2015-08... TRP 2.3803 +0.1009 +- 0.0324 636 push( @TRP, $hlp[2] + $hlp[3] ); 637 } 638 elsif ( $ln =~ /\bREC_CLK\b/ ) { 639 640 # 2024-10-20_03:57:30.000 RECCLK G 0.0000 -1.7861 +- 0.5268 641 $sys = $hlp[2]; 642 push @{ $RECCLK{$sys}{EPOCH} }, $epochSec; 643 push @{ $RECCLK{$sys}{DATA} }, $hlp[3] + $hlp[4]; 644 } 645 } # ----- next line ----- 646 647 $logMode && filePosition( $file, tell($fh) ); # Remember pos for next read 648 close $fh; 649 650 my $nof_epochs = scalar @EPOCH; 651 DEBUG( "$station: epochs:$nof_epochs, North displac.: " 652 . scalar @N 653 . ", East displac.: " 654 . scalar @E 655 . ", Up displac.: " 656 . scalar @U 657 . ", isfix: " 658 . scalar @ISFIX 659 . ", numfix: " 660 . scalar @NUMFIX 661 . ", TRP:" 662 . scalar @TRP ); 663 if ( $nof_epochs != scalar @N ) { 664 LOGDIE "number of epochs and residuals not equal\n"; 665 } 666 if ( $nof_epochs != scalar @TRP ) { 667 LOGDIE "number of epochs and TRP not equal\n"; 668 } 669 670 if ( !$station ) { WARN "could not grep stationname from file: $file\n" } 671 672 my %data = ( 673 EPOCH => \@EPOCH, 674 N => \@N, 675 E => \@E, 676 U => \@U, 677 ISFIX => \@ISFIX, 678 NUMFIX => \@NUMFIX, 679 TRP => \@TRP, 680 SATNUM => \%SATNUM, 681 RECCLK => \%RECCLK, 682 RES => \%RES, 683 AMB => \%AMB, 684 ELE => \%ELE, 685 ION => \%ION, 686 BIA => \%BIA, 687 ); 688 689 return ( $station, \%data, 0 ); 635 690 } 636 691 … … 647 702 # ============================================================================= 648 703 sub BncStillWorks { 649 my ($bncConfFile) = @_; 650 651 my $timep = Time::Piece->new; 652 653 # for safety if it is exatly at 00:00, add 30 sec 654 my $min_tmp = $timep->strftime("%M"); 655 if ( $min_tmp =~ /00|15|30|45/ && $timep->strftime("%S") < 15 ) { 656 $timep += 30; 657 sleep 30; 658 } 659 my $yyyy = $timep->year; 660 my $yy = $timep->yy; 661 my $doy = sprintf "%03d", $timep->yday + 1; 662 my $hh = $timep->strftime("%H"); 663 my $h = uc ( chr ( 65 + $hh ) ); 664 my $min = $timep->min; 665 my $startmin; 666 if ( $min < 15 ) { $startmin = "00" } 667 elsif ( $min < 30 ) { $startmin = "15" } 668 elsif ( $min < 45 ) { $startmin = "30" } 669 elsif ( $min <= 59 ) { $startmin = "45" } 670 my $bncConf = parseConf($bncConfFile); 671 my $bncLogFileStub = $bncConf->{'General'}->{'logFile'}; 672 673 # BNC log file 674 # ------------ 675 my $bncLogFile = "${bncLogFileStub}_" . $timep->strftime("%y%m%d"); # -> bnc.log_160425 676 unless ( -s $bncLogFile ) { 677 WARN("BNC logfile \"$bncLogFile\" is empty or does not exist"); 678 return 0; 679 } 680 681 # RINEX Obs Generation 682 # -------------------- 683 if ( $bncConf->{'General'}->{'rnxPath'} ) { 684 my $rnxPath = $bncConf->{'General'}->{'rnxPath'}; 685 $rnxPath =~ s/\/$//; 686 687 # Write Rnx3 files (i.e. long Rnx3 filenames) 2: on ('rnxV3filenames' is deprecated since 2.12.8!!!) 688 my $writeRnxV3 = $bncConf->{'General'}->{'rnxV3'}; 689 my $rnxIntr = $bncConf->{'General'}->{'rnxIntr'}; 690 my $fileMask; 691 692 if ($writeRnxV3) { 693 if ( $rnxIntr eq "1 hour" ) { 694 $fileMask = "*_S_${yyyy}${doy}${hh}??_01H_30S_?O.rnx"; 695 } 696 elsif ( $rnxIntr eq "15 min" ) { 697 $fileMask = "*_S_${yyyy}${doy}${hh}${startmin}_15M_01S_?O.rnx"; 698 } 699 else { # daily? 700 $fileMask = "*_S_${yyyy}${doy}????_01D_30S_?O.rnx"; # HRAG00ZAF_S_20191220000_01D_30S_MO.rnx 701 } 702 } 703 else { # Rnx2 704 if ( $rnxIntr eq "1 hour" ) { 705 $fileMask = "????${doy}${h}.${yy}O"; 706 } 707 elsif ( $rnxIntr eq "15 min" ) { 708 $fileMask = "????${doy}${h}${startmin}.${yy}O"; 709 } 710 else { # daily? 711 $fileMask = "????${doy}*.${yy}O"; 712 } 713 } 714 715 my @rnxFiles = glob "$rnxPath/$fileMask"; 716 if ( scalar @rnxFiles < 1 ) { 717 ERROR("BNC does not create RINEX Obs files. (Filemask: \"$fileMask\" Path: $rnxPath)"); 718 719 #return 0; 720 } 721 } 722 723 # RINEX Ephemerides Generation 724 # ---------------------------- 725 if ( $bncConf->{'General'}->{'ephPath'} ) { 726 my $rnxPath = $bncConf->{'General'}->{'ephPath'}; 727 $rnxPath =~ s/\/$//; 728 my $writeRnxV3 = $bncConf->{'General'}->{'ephV3'}; 729 my $rnxIntr = $bncConf->{'General'}->{'ephIntr'}; 730 my $fileMask; 731 732 if ($writeRnxV3) { 733 if ( $rnxIntr eq "1 hour" ) { 734 $fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}00_01H_?N.rnx"; 735 } 736 elsif ( $rnxIntr eq "15 min" ) { 737 $fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}${startmin}_15M_?N.rnx"; # BRDC00WRD_S_20191220900_15M_MN.rnx 738 } 739 else { # daily? 740 $fileMask = $fileMask = "BRD?00WRD_S_${yyyy}${doy}0000_01D_?N.rnx"; 741 } 742 } 743 else { # Rnx2 744 $fileMask = "BRD?${doy}*.${yy}N"; 745 } 746 747 my @rnxFiles = glob "$rnxPath/$fileMask"; 748 if ( scalar @rnxFiles < 1 ) { 749 ERROR("BNC does not create RINEX Nav files. (Filemask: \"$fileMask\" Path: $rnxPath)"); 750 751 #return 0; 752 } 753 } 754 755 # Check jobs making PPP 756 # --------------------- 757 if ( $bncConf->{'PPP'}->{'corrMount'} && $bncConf->{'PPP'}->{'staTable'} ) { 758 my $timeOfLastCoo = `grep "NEU:" $bncLogFile | tail -1 | cut -d ' ' -f1,2`; 759 chomp $timeOfLastCoo; 760 if ( !$timeOfLastCoo ) { 761 ERROR "BNC does not compute coordinates"; 762 return 0; 763 } 764 765 my $tp = Time::Piece->strptime( $timeOfLastCoo, '%y-%m-%d %H:%M:%S' ); 766 my $now = Time::Piece->new; 767 my $tdiff = $now - $tp; 768 if ( $tdiff > 1200 ) { 769 ERROR( "Last computed coordinates are " . $tdiff / 60 . " min old" ); 770 return 0; 771 } 772 } 773 774 # BNC works 775 return 1; 704 my ($bncConfFile) = @_; 705 706 my $timep = Time::Piece->new; 707 708 # for safety if it is exatly at 00:00, add 30 sec 709 my $min_tmp = $timep->strftime("%M"); 710 if ( $min_tmp =~ /00|15|30|45/ && $timep->strftime("%S") < 15 ) { 711 $timep += 30; 712 sleep 30; 713 } 714 my $yyyy = $timep->year; 715 my $yy = $timep->yy; 716 my $doy = sprintf "%03d", $timep->yday + 1; 717 my $hh = $timep->strftime("%H"); 718 my $h = uc( chr( 65 + $hh ) ); 719 my $min = $timep->min; 720 my $startmin; 721 if ( $min < 15 ) { $startmin = "00" } 722 elsif ( $min < 30 ) { $startmin = "15" } 723 elsif ( $min < 45 ) { $startmin = "30" } 724 elsif ( $min <= 59 ) { $startmin = "45" } 725 my $bncConf = parseConf($bncConfFile); 726 my $bncLogFileStub = $bncConf->{'General'}->{'logFile'}; 727 728 # BNC log file 729 # ------------ 730 my $bncLogFile = 731 "${bncLogFileStub}_" . $timep->strftime("%y%m%d"); # -> bnc.log_160425 732 unless ( -s $bncLogFile ) { 733 WARN("BNC logfile \"$bncLogFile\" is empty or does not exist"); 734 return 0; 735 } 736 737 # RINEX Obs Generation 738 # -------------------- 739 if ( $bncConf->{'General'}->{'rnxPath'} ) { 740 my $rnxPath = $bncConf->{'General'}->{'rnxPath'}; 741 $rnxPath =~ s/\/$//; 742 743 # Write Rnx3 files (i.e. long Rnx3 filenames) 2: on ('rnxV3filenames' is deprecated since 2.12.8!!!) 744 my $writeRnxV3 = $bncConf->{'General'}->{'rnxV3'}; 745 my $rnxIntr = $bncConf->{'General'}->{'rnxIntr'}; 746 my $fileMask; 747 748 if ($writeRnxV3) { 749 if ( $rnxIntr eq "1 hour" ) { 750 $fileMask = "*_S_${yyyy}${doy}${hh}??_01H_30S_?O.rnx"; 751 } 752 elsif ( $rnxIntr eq "15 min" ) { 753 $fileMask = "*_S_${yyyy}${doy}${hh}${startmin}_15M_01S_?O.rnx"; 754 } 755 else { # daily? 756 $fileMask = "*_S_${yyyy}${doy}????_01D_30S_?O.rnx" 757 ; # HRAG00ZAF_S_20191220000_01D_30S_MO.rnx 758 } 759 } 760 else { # Rnx2 761 if ( $rnxIntr eq "1 hour" ) { 762 $fileMask = "????${doy}${h}.${yy}O"; 763 } 764 elsif ( $rnxIntr eq "15 min" ) { 765 $fileMask = "????${doy}${h}${startmin}.${yy}O"; 766 } 767 else { # daily? 768 $fileMask = "????${doy}*.${yy}O"; 769 } 770 } 771 772 my @rnxFiles = glob "$rnxPath/$fileMask"; 773 if ( scalar @rnxFiles < 1 ) { 774 ERROR( 775 "BNC does not create RINEX Obs files. (Filemask: \"$fileMask\" Path: $rnxPath)" 776 ); 777 778 #return 0; 779 } 780 } 781 782 # RINEX Ephemerides Generation 783 # ---------------------------- 784 if ( $bncConf->{'General'}->{'ephPath'} ) { 785 my $rnxPath = $bncConf->{'General'}->{'ephPath'}; 786 $rnxPath =~ s/\/$//; 787 my $writeRnxV3 = $bncConf->{'General'}->{'ephV3'}; 788 my $rnxIntr = $bncConf->{'General'}->{'ephIntr'}; 789 my $fileMask; 790 791 if ($writeRnxV3) { 792 if ( $rnxIntr eq "1 hour" ) { 793 $fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}00_01H_?N.rnx"; 794 } 795 elsif ( $rnxIntr eq "15 min" ) { 796 $fileMask = 797 "BRD?00WRD_S_${yyyy}${doy}${hh}${startmin}_15M_?N.rnx" 798 ; # BRDC00WRD_S_20191220900_15M_MN.rnx 799 } 800 else { # daily? 801 $fileMask = $fileMask = 802 "BRD?00WRD_S_${yyyy}${doy}0000_01D_?N.rnx"; 803 } 804 } 805 else { # Rnx2 806 $fileMask = "BRD?${doy}*.${yy}N"; 807 } 808 809 my @rnxFiles = glob "$rnxPath/$fileMask"; 810 if ( scalar @rnxFiles < 1 ) { 811 ERROR( 812 "BNC does not create RINEX Nav files. (Filemask: \"$fileMask\" Path: $rnxPath)" 813 ); 814 815 #return 0; 816 } 817 } 818 819 # Check jobs making PPP 820 # --------------------- 821 if ( $bncConf->{'PPP'}->{'corrMount'} && $bncConf->{'PPP'}->{'staTable'} ) { 822 my $timeOfLastCoo = 823 `grep "NEU:" $bncLogFile | tail -1 | cut -d ' ' -f1,2`; 824 chomp $timeOfLastCoo; 825 if ( !$timeOfLastCoo ) { 826 ERROR "BNC does not compute coordinates"; 827 return 0; 828 } 829 830 my $tp = Time::Piece->strptime( $timeOfLastCoo, '%y-%m-%d %H:%M:%S' ); 831 my $now = Time::Piece->new; 832 my $tdiff = $now - $tp; 833 if ( $tdiff > 1200 ) { 834 ERROR( 835 "Last computed coordinates are " . $tdiff / 60 . " min old" ); 836 return 0; 837 } 838 } 839 840 # BNC works 841 return 1; 776 842 } 777 843 -
trunk/BNC/scripts/pppPlot.pl
r10644 r10798 25 25 26 26 BEGIN { 27 use FindBin qw($Bin);28 use lib "$Bin";27 use FindBin qw($Bin); 28 use lib "$Bin"; 29 29 } 30 30 … … 44 44 45 45 use constant { 46 mm => 25.4 / 72, 47 inch => 1 / 72, 48 pt => 1, 49 }; # There are 72 postscript points in an inch and there are 25.4 millimeters in an inch. 50 46 mm => 25.4 / 72, 47 inch => 1 / 72, 48 pt => 1, 49 }; # There are 72 postscript points in an inch and there are 25.4 millimeters in an inch. 51 50 52 51 # Logging 53 52 Log::Log4perl->easy_init( 54 {55 56 #file => "plotPPP.log",57 layout => '%d [%c l%L] %p: %m%n',58 level => $TRACE59 }53 { 54 55 #file => "plotPPP.log", 56 layout => '%d [%c l%L] %p: %m%n', 57 level => $TRACE 58 } 60 59 ); 61 60 … … 68 67 69 68 GetOptions( 70 'help' => \$help,71 'plotTypes=s' => \@plotTypes,72 'logFiles=s' => \@logFiles,73 'sampling=s' => \$sampling,69 'help' => \$help, 70 'plotTypes=s' => \@plotTypes, 71 'logFiles=s' => \@logFiles, 72 'sampling=s' => \$sampling, 74 73 ); 75 74 76 75 HELP_MESSAGE() if $help; 77 76 @plotTypes = qw(NEU) unless (@plotTypes); 78 @plotTypes = map { uc} split( /[, ]/, join( ',', @plotTypes ) );79 @logFiles = split ( /[, ]/, join( ',', @logFiles ) );77 @plotTypes = map { uc } split( /[, ]/, join( ',', @plotTypes ) ); 78 @logFiles = split( /[, ]/, join( ',', @logFiles ) ); 80 79 unless (@logFiles) { ERROR "logfiles missing"; HELP_MESSAGE() } 81 DEBUG("\n plotTpes: @plotTypes\n logfiles: @logFiles\n sampling: $sampling"); 80 DEBUG( 81 "\n plotTpes: @plotTypes\n logfiles: @logFiles\n sampling: $sampling" 82 ); 82 83 83 84 # ----------------------------------------------------------------------------- … … 92 93 # Loop over logfiles 93 94 foreach my $file (@logFiles) { 94 DEBUG "Parse logfile $file"; 95 96 # ----------------------------------------------------------------------------- 97 # Create pdf for plot results 98 # ----------------------------------------------------------------------------- 99 my ( $inputFilename, $inputDir, $inputSuffix ) = fileparse( $file, '\..*' ); 100 my $pdf_name = sprintf ( "%s.pdf", $inputFilename ); 101 my $pdf = PDF::API2->new( -file => "$inputDir$pdf_name" ); 102 my $font1 = $pdf->corefont('Helvetica-Bold'); 103 104 # ----------------------------------------------------------------------------- 105 # Read logfile 106 # ----------------------------------------------------------------------------- 107 my ( $station, $file ) = Bnc::parsePPPLogfile( $file, $sampling ); 108 my $EPOCH = $file->{'EPOCH'}; 109 my %RECCLK = %{ $file->{'RECCLK'} }; 110 my %AMB = %{ $file->{'AMB'} }; 111 my %RES = %{ $file->{'RES'} }; 112 my %ELE = %{ $file->{'ELE'} }; 113 my %ION = %{ $file->{'ION'} }; 114 my %BIA = %{ $file->{'BIA'} }; 115 116 # ----------------------------------------------------------------------------- 117 # RMS computation 118 # ----------------------------------------------------------------------------- 119 my ( $mean, $prms, $median, $min, $max, $adev, $rms_n, $rms_e, $rms_u, $rms_trp ); 120 my ( $n, $e, $u, $trp, $str_rms_n, $str_rms_e, $str_rms_u, $str_rms_trp ); 121 $n = pdl( $file->{'N'} ); 122 ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats($n); 123 $e = pdl( $file->{'E'} ); 124 ( $mean, $prms, $median, $min, $max, $adev, $rms_e ) = stats($e); 125 $u = pdl( $file->{'U'} ); 126 ( $mean, $prms, $median, $min, $max, $adev, $rms_u ) = stats($u); 127 $trp = pdl( $file->{'TRP'} ); 128 ( $mean, $prms, $median, $min, $max, $adev, $rms_trp ) = stats($trp); 129 $str_rms_n = sprintf ( " %.2f ", $rms_n ); 130 $str_rms_e = sprintf ( " %.2f ", $rms_e ); 131 $str_rms_u = sprintf ( " %.2f ", $rms_u ); 132 $str_rms_trp = sprintf ( " %.2f ", $rms_trp ); 133 DEBUG("RMS: North: $str_rms_n, East: $str_rms_e, Up: $str_rms_u, TRP: $str_rms_trp"); 134 135 # ----------------------------------------------------------------------------- 136 # Plot several data sets 137 # ----------------------------------------------------------------------------- 138 my $dataset; 139 ######### NEU ##################### 140 DEBUG "Plot NEU"; 141 $page = $pdf->page(); 142 $page->mediabox('A4'); 143 $headline = sprintf ( "PPP results for station %s", $station ); 144 $headline_text = $page->text; 145 $headline_text->font( $font1, 11 / pt ); 146 $headline_text->translate( 15 / mm, 280 / mm ); 147 $headline_text->text($headline); 148 $y = $y0; 149 my $pngNameNEU = sprintf ( "%s_NEU.png", $station ); 150 my $chartNEU = newChart($station); 151 $chartNEU->set( output => $pngNameNEU); 152 $chartNEU->set( ylabel => "Displacements [m]", yrange => [ " -0.5 ", " 0.5 " ] ); 153 154 #y2label => "Number of Satellites [-]", y2range => [" 0 ", " 20 "], y2tics => 'on', 155 156 my $dataN = Chart::Gnuplot::DataSet->new( 157 xdata => $EPOCH, 158 ydata => $file->{'N'}, 159 title => "Displacements N, RMS + -$str_rms_n m", 160 timefmt => '%s', 161 style => "linespoints", 162 ); 163 my $dataE = Chart::Gnuplot::DataSet->new( 164 xdata => $EPOCH, 165 ydata => $file->{'E'}, 166 title => "Displacements E, RMS + -$str_rms_e m", 167 timefmt => '%s', 168 style => "linespoints", 169 ); 170 my $dataU = Chart::Gnuplot::DataSet->new( 171 xdata => $EPOCH, 172 ydata => $file->{'U'}, 173 title => "Displacements U, RMS + -$str_rms_u m", 174 timefmt => '%s', 175 style => "linespoints", 176 ); 177 my @datasets = ( $dataN, $dataE, $dataU ); 178 $chartNEU->plot2d(@datasets); 179 180 $png = $page->gfx(); 181 LOGDIE("could not find image file: $!\n") unless -e $pngNameNEU; 182 $png->image( $pdf->image_png($pngNameNEU), $x, $y, $width, $height ); #print "y= : $y \n" 183 184 ######### TRP ##################### 185 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 186 DEBUG "Plot TRP"; 187 my $pngNameTRP = sprintf ( "%s_TRP.png", $station ); 188 my $chartTRP = newChart($station); 189 $chartTRP->set( output => $pngNameTRP); 190 $chartTRP->set( ylabel => "Tropospheric Delay [m]", yrange => [ " 1.0 ", " 3.0 " ] ); 191 192 my $dataTRP = Chart::Gnuplot::DataSet->new( 193 xdata => $EPOCH, 194 ydata => $file->{'TRP'}, 195 title => "Tropospheric Delay, RMS + -$str_rms_trp m", 196 timefmt => '%s', 197 style => "points", 198 ); 199 $chartTRP->plot2d($dataTRP); 200 $y = $y - $dy; 201 202 if ( $y < 30 / mm ) { 203 $page = $pdf->page(); 204 $page->mediabox('A4'); 205 $y = $y0; 206 } 207 $png = $page->gfx(); 208 LOGDIE("could not find image file: $!\n") unless -e $pngNameTRP; 209 $png->image( $pdf->image_png($pngNameTRP), $x, $y, $width, $height ); 210 211 ######### RECCLK ##################### 212 DEBUG "Plot Receiver Clocks"; 213 $page = $pdf->page(); 214 $page->mediabox('A4'); 215 $y = $y0 + $dy; 216 $headline = sprintf ( "Receiver Clocks for station %s", $station ); 217 $headline_text = $page->text; 218 $headline_text->font( $font1, 11 / pt ); 219 $headline_text->translate( 15 / mm, 280 / mm ); 220 $headline_text->text($headline); 221 222 my $chartRECCLK = newChart($station); 223 $chartRECCLK->set( legend => { position => "outside right" } ); 224 my @datasets = (); # init datasets 225 my $pngNameRECCLK = sprintf ( "%s_RECCLK.png", $station); 226 $chartRECCLK->set( output => $pngNameRECCLK); 227 $chartRECCLK->set( ylabel => "Receiver Clocks [m]" ); 228 # SYSTEM 229 foreach my $key_sys ( sort keys %RECCLK ) { 230 231 $dataset = Chart::Gnuplot::DataSet->new( 232 xdata => \@{ $RECCLK{$key_sys}{EPOCH} }, # array of epochs 233 ydata => \@{ $RECCLK{$key_sys}{DATA} }, # array of elevations of one satellite 234 title => "$key_sys", 235 timefmt => '%s', 236 237 #style => "points", 238 style => "points", 239 ); 240 push ( @datasets, $dataset ); 241 } 242 $chartRECCLK->plot2d(@datasets); 243 244 # system ("display $pngName&"); 245 $y = $y - $dy; 246 if ( $y < 30 / mm ) { 247 $page = $pdf->page(); 248 $page->mediabox('A4'); 249 $y = $y0; 250 } 251 $png = $page->gfx(); 252 die ("could not find image file: $!") unless -e $pngNameRECCLK; 253 $png->image( $pdf->image_png($pngNameRECCLK), $x, $y, $width, $height ); 254 255 ######### ELE ##################### 256 DEBUG "Plot Elevations"; 257 $page = $pdf->page(); 258 $page->mediabox('A4'); 259 $y = $y0 + $dy; 260 $headline = sprintf ( "Satellite Elevations for station %s", $station ); 261 $headline_text = $page->text; 262 $headline_text->font( $font1, 11 / pt ); 263 $headline_text->translate( 15 / mm, 280 / mm ); 264 $headline_text->text($headline); 265 266 my $chartELE = newChart($station); 267 $chartELE->set( legend => { position => "outside right" } ); 268 269 # SYSTEM #print Dumper \%ELE; 270 foreach my $key_sys ( sort keys %ELE ) { 271 272 # print "$key_sys \n";# print Dumper $ELE{$key_sys}; 273 my @datasets = (); # init datasets 274 my $pngNameELE = sprintf ( "%s_ELE_%s.png", $station, $key_sys ); 275 $chartELE->set( output => $pngNameELE); 276 $chartELE->set( ylabel => "Elevation [°]", yrange => [ " 0.0 ", " 90.0 " ] ); 277 278 # SATELLITE 279 foreach my $key_sat ( sort keys %{ $ELE{$key_sys} } ) { 280 281 # print "$key_sat = $ELE{$key_sys}{$key_sat} \n"; 282 $dataset = Chart::Gnuplot::DataSet->new( 283 xdata => \@{ $ELE{$key_sys}{$key_sat}{EPOCH} }, # array of epochs 284 ydata => \@{ $ELE{$key_sys}{$key_sat}{DATA} }, # array of elevations of one satellite 285 title => "$key_sat", 286 timefmt => '%s', 287 288 #style => "points", 289 style => "points", 290 ); 291 push ( @datasets, $dataset ); 292 } 293 $chartELE->plot2d(@datasets); 294 295 # system ("display $pngName&"); 296 $y = $y - $dy; 297 if ( $y < 30 / mm ) { 298 $page = $pdf->page(); 299 $page->mediabox('A4'); 300 $y = $y0; 301 } 302 $png = $page->gfx(); 303 die ("could not find image file: $!") unless -e $pngNameELE; 304 $png->image( $pdf->image_png($pngNameELE), $x, $y, $width, $height ); 305 } 306 307 ######### AMB ##################### 308 DEBUG "Plot Ambiguities"; 309 $page = $pdf->page(); 310 $page->mediabox('A4'); 311 $y = $y0 + $dy; 312 $headline = sprintf ( "Ambiguities for station %s", $station ); 313 $headline_text = $page->text; 314 $headline_text->font( $font1, 11 / pt ); 315 $headline_text->translate( 15 / mm, 280 / mm ); 316 $headline_text->text($headline); 317 318 # AMBIGUITY_TYPE #print Dumper \%AMB; 319 foreach my $key_ambType (%AMB) { #print "$key_ambType \n"; 320 foreach my $key_sys ( sort keys %{ $AMB{$key_ambType} } ) { 321 322 #print "$key_sys \n"; print Dumper $AMB{$key_ambType}; 323 my ( @datasets_amb, @datasets_epo ); # init datasets 324 my $pngNameAMB = sprintf ( "%s_AMB_%s_%s.png", $station, $key_ambType, $key_sys ); 325 my $pngNameEPO = sprintf ( "%s_EPO_%s_%s.png", $station, $key_ambType, $key_sys ); 326 my $chartAMB = Chart::Gnuplot->new( 327 output => $pngNameAMB, 328 terminal => 'png', 329 title => $station, 330 ylabel => "Ambiguities $key_ambType [m]", 331 332 # yrange => [" 0.0 ", " 90.0 "], 333 xlabel => "Time [h]", 334 timeaxis => 'x', 335 xtics => { labelfmt => '%H:%M', rotate => '-270', }, 336 legend => { position => "outside right", }, 337 grid => 'on', 338 ); 339 my $chartEPO = Chart::Gnuplot->new( 340 output => $pngNameEPO, 341 terminal => 'png', 342 title => $station, 343 ylabel => "Number of Epochs $key_ambType [-]", 344 345 # yrange => [" 0.0 ", " 90.0 "], 346 xlabel => "Time [h]", 347 timeaxis => 'x', 348 xtics => { labelfmt => '%H:%M', rotate => '-270', }, 349 legend => { position => "outside right", }, 350 grid => 'on', 351 ); 352 353 # SATELLITE 354 foreach my $key_sat ( sort keys %{ $AMB{$key_ambType}{$key_sys} } ) { 355 356 #print "$key_sat = $AMB{$key_ambType}{$key_sys}{$key_sat} \n"; 357 # ambiguities 358 my $dataset_amb = Chart::Gnuplot::DataSet->new( 359 xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH}, # array of epochs 360 ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{DATA}, # array of ambiguities of one satellite 361 title => "$key_sat", 362 timefmt => '%s', 363 style => "points", 364 365 #style => "points", 366 ); 367 push ( @datasets_amb, $dataset_amb ); 368 369 # number of epochs used for ambiguity 370 my $dataset_epo = Chart::Gnuplot::DataSet->new( 371 xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH}, # array of epochs 372 ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{NUMEPO}, # array of ambiguities of one satellite 373 title => "$key_sat", 374 timefmt => '%s', 375 376 #style => "points", 377 style => "points", 378 ); 379 push ( @datasets_epo, $dataset_epo ); 380 } 381 382 # ambiguities 383 $chartAMB->plot2d(@datasets_amb); 384 385 # system ("display $pngName_amb&"); 386 $y = $y - $dy; 387 if ( $y < 30 / mm ) { 388 $page = $pdf->page(); 389 $page->mediabox('A4'); 390 $y = $y0; 391 } 392 $png = $page->gfx(); 393 LOGDIE("could not find image file: $!\n") unless -e $pngNameAMB; 394 $png->image( $pdf->image_png($pngNameAMB), $x, $y, $width, $height ); 395 396 # number of epochs used for ambiguity 397 $chartEPO->plot2d(@datasets_epo); 398 399 # system ("display $pngName_epo&"); 400 $y = $y - $dy; 401 if ( $y < 30 / mm ) { 402 $page = $pdf->page(); 403 $page->mediabox('A4'); 404 $y = $y0; 405 } 406 $png = $page->gfx(); 407 LOGDIE("could not find image file $pngNameEPO: $!\n") unless -e $pngNameEPO; 408 $png->image( $pdf->image_png($pngNameEPO), $x, $y, $width, $height ); 409 } 410 } 411 412 ######### ION ##################### 413 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 414 DEBUG "Plot ION"; 415 $page = $pdf->page(); 416 $page->mediabox('A4'); 417 $y = $y0 + $dy; 418 $headline = sprintf ( "Ionosphere Delay for station %s", $station ); 419 $headline_text = $page->text; 420 $headline_text->font( $font1, 11 / pt ); 421 $headline_text->translate( 15 / mm, 280 / mm ); 422 $headline_text->text($headline); 423 424 my $chartION = newChart($station); 425 $chartION->set( ylabel => "Ionophere Delay [m]" ); 426 $chartION->set( legend => { position => "outside right" } ); 427 428 # SYSTEM 429 foreach my $ksys ( sort keys %ION ) { #print "$key_sys \n"; #print Dumper $ION{$key_sys}; 430 my @datasets; # init datasets 431 my $pngNameION = sprintf ( "%s_ION_%s.png", $station, $ksys ); 432 $chartION->set( output => $pngNameION); 433 434 # SATELLITE 435 foreach my $sat ( sort keys %{ $ION{$ksys} } ) { #print "$key_sat = $ION{$key_sys}{$key_sat} \n"; 436 my $dataset = Chart::Gnuplot::DataSet->new( 437 xdata => $ION{$ksys}{$sat}{EPOCH}, # array of epochs 438 ydata => $ION{$ksys}{$sat}{DATA}, # array of ionvations of one satellite 439 title => "$sat", 440 timefmt => '%s', 441 442 #style => " points ", 443 style => "points", 444 ); 445 push ( @datasets, $dataset ); 446 } 447 448 $chartION->plot2d(@datasets); #system ("display $pngName&"); 449 $y = $y - $dy; 450 if ( $y < 30 / mm ) { 451 $page = $pdf->page(); 452 $page->mediabox('A4'); 453 $y = $y0; 454 } 455 $png = $page->gfx(); 456 die ("could not find image file: $!") unless -e $pngNameION; 457 $png->image( $pdf->image_png($pngNameION), $x, $y, $width, $height ); 458 } 459 } 460 461 ######### BIAS ##################### 462 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 463 DEBUG "Plot BIAS"; 464 $page = $pdf->page(); 465 $page->mediabox('A4'); 466 $y = $y0 + $dy; 467 $headline = sprintf ( "Receiver Biases for station %s", $station ); 468 $headline_text = $page->text; 469 $headline_text->font( $font1, 11 / pt ); 470 $headline_text->translate( 15 / mm, 280 / mm ); 471 $headline_text->text($headline); 472 473 my $chartBIAS = newChart($station); 474 $chartBIAS->set( legend => { position => "outside right" } ); 475 476 # BIAS_TYPE #print Dumper \%BIA; 477 foreach my $key_biasType ( sort keys %BIA ) { #print "key_biasType: $key_biasType \n"; 478 foreach my $key_sys ( sort keys %{ $BIA{$key_biasType} } ) { 479 480 #print "key_sys: $key_sys \n"; #print Dumper $BIA{$key_biasType}; 481 my @datasets; # init datasets 482 my $pngNameBIA = sprintf ( "%s_BIAS_%s_%s.png", $station, $key_biasType, $key_sys ); 483 $chartBIAS->set( output => $pngNameBIA); 484 $chartBIAS->set( ylabel => "Receiver Bias $key_biasType [m]" ); 485 486 my $dataset = 487 Chart::Gnuplot::DataSet->new( 488 xdata => $BIA{$key_biasType}{$key_sys}{EPOCH}, 489 ydata => $BIA{$key_biasType}{$key_sys}{DATA}, 490 title => "$key_sys", 491 timefmt => '%s', 492 style => "points", 493 ); 494 push ( @datasets, $dataset ); 495 496 $chartBIAS->plot2d(@datasets); 497 $y = $y - $dy; 498 if ( $y < 30 / mm ) { 499 $page = $pdf->page(); 500 $page->mediabox('A4'); 501 $y = $y0; 502 } 503 $png = $page->gfx(); 504 die ("could not find image file: $!") unless -e $pngNameBIA; 505 $png->image( $pdf->image_png($pngNameBIA), $x, $y, $width, $height ); 506 } 507 } 508 } 509 510 ######### RES ##################### 511 DEBUG "Plot Residuals"; 512 $page = $pdf->page(); 513 $page->mediabox('A4'); 514 $y = $y0 + $dy; 515 $headline = sprintf ( "Residuals for station %s", $station ); 516 $headline_text = $page->text; 517 $headline_text->font( $font1, 11 / pt ); 518 $headline_text->translate( 15 / mm, 280 / mm ); 519 $headline_text->text($headline); 520 521 my $chartRES = newChart($station); 522 $chartRES->set( legend => { position => "outside right" } ); 523 524 # RESIDUAL_TYPE #print Dumper \%RES; 525 foreach my $key_resType ( sort keys %RES ) { #print "key_resType: $key_resType \n"; 526 #SYSTEM 527 foreach my $key_sys ( sort keys %{ $RES{$key_resType} } ) { 528 529 #print "key_sys: $key_sys \n"; #print Dumper $RES{$key_resType}; 530 my @datasets; 531 my $pngNameRES = sprintf ( "%s_RES_%s_%s.png", $station, $key_resType, $key_sys ); 532 $chartRES->set( output => $pngNameRES); 533 $chartRES->set( ylabel => "Residuals $key_resType [m]" ); 534 535 if ( $key_resType =~ /^c/ ) { 536 $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] ); 537 } 538 elsif ( $key_resType =~ /^l/ ) { 539 $chartRES->set( yrange => [ " -0.06 ", " 0.06 " ] ); 540 } 541 542 elsif ( $key_resType =~ /^GIM/ ) { 543 $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] ); 544 } 545 546 # SATELLITE 547 foreach my $key_sat ( sort keys %{ $RES{$key_resType}{$key_sys} } ) { 548 549 #print "$key_sat = $RES{$key_resType}{$key_sys}{$key_sat} \n"; 550 $dataset = Chart::Gnuplot::DataSet->new( 551 xdata => $RES{$key_resType}{$key_sys}{$key_sat}{EPOCH}, # array of epochs 552 ydata => $RES{$key_resType}{$key_sys}{$key_sat}{DATA}, # array of residuals of one satellite 553 title => "$key_sat", 554 timefmt => '%s', 555 style => "points", 556 ); 557 push ( @datasets, $dataset ); 558 } 559 $chartRES->plot2d(@datasets); 560 $y = $y - $dy; 561 if ( $y < 30 / mm ) { 562 $page = $pdf->page(); 563 $page->mediabox('A4'); 564 $y = $y0; 565 } 566 $png = $page->gfx(); 567 LOGDIE("could not find image file: $!\n") unless -e $pngNameRES; 568 $png->image( $pdf->image_png($pngNameRES), $x, $y, $width, $height ); 569 } 570 } 571 } # end if ALL @plotTypes 572 573 $pdf->save(); 574 $pdf->end(); 575 576 system ("rm *.png"); 577 if (Common::amInteractiv ) { 578 system ("evince $inputDir/$pdf_name"); 579 } 95 DEBUG "Parse logfile $file"; 96 97 # ----------------------------------------------------------------------------- 98 # Create pdf for plot results 99 # ----------------------------------------------------------------------------- 100 my ( $inputFilename, $inputDir, $inputSuffix ) = fileparse( $file, '\..*' ); 101 my $pdf_name = sprintf( "%s.pdf", $inputFilename ); 102 my $pdf = PDF::API2->new( -file => "$inputDir$pdf_name" ); 103 my $font1 = $pdf->corefont('Helvetica-Bold'); 104 105 # ----------------------------------------------------------------------------- 106 # Read logfile 107 # ----------------------------------------------------------------------------- 108 my ( $station, $file ) = Bnc::parsePPPLogfile( $file, $sampling ); 109 my $EPOCH = $file->{'EPOCH'}; 110 my $N = $file->{'N'}; 111 my $E = $file->{'E'}; 112 my $U = $file->{'U'}; 113 my $ISFIX = $file->{'ISFIX'}; 114 my $NUMFIX = $file->{'NUMFIX'}; 115 my %RECCLK = %{ $file->{'RECCLK'} }; 116 my %AMB = %{ $file->{'AMB'} }; 117 my %RES = %{ $file->{'RES'} }; 118 my %ELE = %{ $file->{'ELE'} }; 119 my %ION = %{ $file->{'ION'} }; 120 my %BIA = %{ $file->{'BIA'} }; 121 122 # ----------------------------------------------------------------------------- 123 # RMS computation 124 # ----------------------------------------------------------------------------- 125 my ( 126 $mean, $prms, $median, $min, $max, 127 $adev, $rms_n, $rms_e, $rms_u, $rms_trp 128 ); 129 my ( $n, $e, $u, $trp, $str_rms_n, $str_rms_e, $str_rms_u, $str_rms_trp ); 130 $n = pdl( $file->{'N'} ); 131 ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats($n); 132 $e = pdl( $file->{'E'} ); 133 ( $mean, $prms, $median, $min, $max, $adev, $rms_e ) = stats($e); 134 $u = pdl( $file->{'U'} ); 135 ( $mean, $prms, $median, $min, $max, $adev, $rms_u ) = stats($u); 136 $trp = pdl( $file->{'TRP'} ); 137 ( $mean, $prms, $median, $min, $max, $adev, $rms_trp ) = stats($trp); 138 $str_rms_n = sprintf( " %.2f ", $rms_n ); 139 $str_rms_e = sprintf( " %.2f ", $rms_e ); 140 $str_rms_u = sprintf( " %.2f ", $rms_u ); 141 $str_rms_trp = sprintf( " %.2f ", $rms_trp ); 142 DEBUG("RMS: North: $str_rms_n, East: $str_rms_e, Up: $str_rms_u, TRP: $str_rms_trp"); 143 144 # ----------------------------------------------------------------------------- 145 # Plot several data sets 146 # ----------------------------------------------------------------------------- 147 my $dataset; 148 $page = $pdf->page(); 149 $page->mediabox('A4'); 150 $headline = sprintf( "PPP results for station %s", $station ); 151 $headline_text = $page->text; 152 $headline_text->font( $font1, 11 / pt ); 153 $headline_text->translate( 15 / mm, 280 / mm ); 154 $headline_text->text($headline); 155 $y = $y0; 156 157 ######### NEU ##################### 158 DEBUG "Plot NEU"; 159 my $pngNameNEU = sprintf( "%s_NEU.png", $station ); 160 my $chartNEU = newChart($station); 161 $chartNEU->set( 162 output => $pngNameNEU, 163 ylabel => "Displacements [m]", 164 yrange => [ " -0.5 ", " 0.5 " ], 165 ); 166 my $dataN = Chart::Gnuplot::DataSet->new( 167 xdata => $EPOCH, 168 ydata => $N, 169 title => "Displacements N, RMS + -$str_rms_n m", 170 timefmt => '%s', 171 style => "dots", 172 ); 173 my $dataE = Chart::Gnuplot::DataSet->new( 174 xdata => $EPOCH, 175 ydata => $E, 176 title => "Displacements E, RMS + -$str_rms_e m", 177 timefmt => '%s', 178 style => "dots", 179 ); 180 my $dataU = Chart::Gnuplot::DataSet->new( 181 xdata => $EPOCH, 182 ydata => $U, 183 title => "Displacements U, RMS + -$str_rms_u m", 184 timefmt => '%s', 185 style => "dots", 186 ); 187 188 my @datasets = ( $dataN, $dataE, $dataU ); 189 $chartNEU->plot2d(@datasets); 190 191 $png = $page->gfx(); 192 LOGDIE("could not find image file: $!\n") unless -e $pngNameNEU; 193 $png->image( $pdf->image_png($pngNameNEU), $x, $y, $width, $height ); 194 195 ######### FIX ##################### 196 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 197 DEBUG "Plot FIX"; 198 my $pngNameFIX = sprintf( "%s_FIX.png", $station ); 199 my $chartFIX = newChart($station); 200 $chartFIX->set( 201 output => $pngNameFIX, 202 ylabel => "Fixed [%]", 203 yrange => [ "0", "100" ], 204 ytics => 20, 205 ); 206 207 my $dataNUMFIX = Chart::Gnuplot::DataSet->new( 208 xdata => $EPOCH, 209 ydata => $NUMFIX, 210 timefmt => '%s', 211 style => "impulse", 212 color => "green", 213 ); 214 215 $chartFIX->plot2d($dataNUMFIX); 216 $y = $y - $dy; 217 if ( $y < 30 / mm ) { 218 $page = $pdf->page(); 219 $page->mediabox('A4'); 220 $y = $y0; 221 } 222 $png = $page->gfx(); 223 LOGDIE("could not find image file: $!\n") unless -e $pngNameFIX; 224 $png->image( $pdf->image_png($pngNameFIX), $x, $y, $width, $height ); 225 } 226 ######### TRP ##################### 227 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 228 DEBUG "Plot TRP"; 229 my $pngNameTRP = sprintf( "%s_TRP.png", $station ); 230 my $chartTRP = newChart($station); 231 $chartTRP->set( output => $pngNameTRP ); 232 $chartTRP->set( 233 ylabel => "Tropospheric Delay [m]", 234 yrange => [ " 1.0 ", " 3.0 " ] 235 ); 236 my $dataTRP = Chart::Gnuplot::DataSet->new( 237 xdata => $EPOCH, 238 ydata => $file->{'TRP'}, 239 title => "Tropospheric Delay, RMS + -$str_rms_trp m", 240 timefmt => '%s', 241 style => "dots", 242 ); 243 $chartTRP->plot2d($dataTRP); 244 $y = $y - $dy; 245 246 if ( $y < 30 / mm ) { 247 $page = $pdf->page(); 248 $page->mediabox('A4'); 249 $y = $y0; 250 } 251 $png = $page->gfx(); 252 LOGDIE("could not find image file: $!\n") unless -e $pngNameTRP; 253 $png->image( $pdf->image_png($pngNameTRP), $x, $y, $width, $height ); 254 255 ######### RECCLK ##################### 256 DEBUG "Plot Receiver Clocks"; 257 $page = $pdf->page(); 258 $page->mediabox('A4'); 259 $y = $y0 + $dy; 260 $headline = sprintf( "Receiver Clocks for station %s", $station ); 261 $headline_text = $page->text; 262 $headline_text->font( $font1, 11 / pt ); 263 $headline_text->translate( 15 / mm, 280 / mm ); 264 $headline_text->text($headline); 265 266 my $chartRECCLK = newChart($station); 267 $chartRECCLK->set( legend => { position => "outside right" } ); 268 my @datasets = (); # init datasets 269 my $pngNameRECCLK = sprintf( "%s_RECCLK.png", $station ); 270 $chartRECCLK->set( output => $pngNameRECCLK ); 271 $chartRECCLK->set( ylabel => "Receiver Clocks [m]" ); 272 273 # SYSTEM 274 foreach my $key_sys ( sort keys %RECCLK ) { 275 276 $dataset = Chart::Gnuplot::DataSet->new( 277 xdata => \@{ $RECCLK{$key_sys}{EPOCH} }, # array of epochs 278 ydata => \@{ $RECCLK{$key_sys}{DATA} } 279 , # array of elevations of one satellite 280 title => "$key_sys", 281 timefmt => '%s', 282 style => "dots", 283 ); 284 push( @datasets, $dataset ); 285 } 286 $chartRECCLK->plot2d(@datasets); 287 288 # system ("display $pngName&"); 289 $y = $y - $dy; 290 if ( $y < 30 / mm ) { 291 $page = $pdf->page(); 292 $page->mediabox('A4'); 293 $y = $y0; 294 } 295 $png = $page->gfx(); 296 die("could not find image file: $!") unless -e $pngNameRECCLK; 297 $png->image( $pdf->image_png($pngNameRECCLK), $x, $y, $width, $height ); 298 299 ######### ELE ##################### 300 DEBUG "Plot Elevations"; 301 $page = $pdf->page(); 302 $page->mediabox('A4'); 303 $y = $y0 + $dy; 304 $headline = sprintf( "Satellite Elevations for station %s", $station ); 305 $headline_text = $page->text; 306 $headline_text->font( $font1, 11 / pt ); 307 $headline_text->translate( 15 / mm, 280 / mm ); 308 $headline_text->text($headline); 309 310 my $chartELE = newChart($station); 311 $chartELE->set( legend => { position => "outside right" } ); 312 313 # SYSTEM #print Dumper \%ELE; 314 foreach my $key_sys ( sort keys %ELE ) { 315 316 # print "$key_sys \n";# print Dumper $ELE{$key_sys}; 317 my @datasets = (); # init datasets 318 my $pngNameELE = sprintf( "%s_ELE_%s.png", $station, $key_sys ); 319 $chartELE->set( output => $pngNameELE ); 320 $chartELE->set( 321 ylabel => "Elevation [°]", 322 yrange => [ " 0.0 ", " 90.0 " ] 323 ); 324 325 # SATELLITE 326 foreach my $key_sat ( sort keys %{ $ELE{$key_sys} } ) { 327 328 # print "$key_sat = $ELE{$key_sys}{$key_sat} \n"; 329 $dataset = Chart::Gnuplot::DataSet->new( 330 xdata => \@{ $ELE{$key_sys}{$key_sat}{EPOCH} } 331 , # array of epochs 332 ydata => \@{ $ELE{$key_sys}{$key_sat}{DATA} } 333 , # array of elevations of one satellite 334 title => "$key_sat", 335 timefmt => '%s', 336 style => "dots", 337 ); 338 push( @datasets, $dataset ); 339 } 340 $chartELE->plot2d(@datasets); 341 342 # system ("display $pngName&"); 343 $y = $y - $dy; 344 if ( $y < 30 / mm ) { 345 $page = $pdf->page(); 346 $page->mediabox('A4'); 347 $y = $y0; 348 } 349 $png = $page->gfx(); 350 die("could not find image file: $!") unless -e $pngNameELE; 351 $png->image( $pdf->image_png($pngNameELE), $x, $y, $width, 352 $height ); 353 } 354 355 ######### AMB ##################### 356 DEBUG "Plot Ambiguities"; 357 $page = $pdf->page(); 358 $page->mediabox('A4'); 359 $y = $y0 + $dy; 360 $headline = sprintf( "Ambiguities for station %s", $station ); 361 $headline_text = $page->text; 362 $headline_text->font( $font1, 11 / pt ); 363 $headline_text->translate( 15 / mm, 280 / mm ); 364 $headline_text->text($headline); 365 366 # AMBIGUITY_TYPE #print Dumper \%AMB; 367 foreach my $key_ambType (%AMB) { #print "$key_ambType \n"; 368 foreach my $key_sys ( sort keys %{ $AMB{$key_ambType} } ) { 369 370 #print "$key_sys \n"; print Dumper $AMB{$key_ambType}; 371 my ( @datasets_amb, @datasets_epo ); # init datasets 372 my $pngNameAMB = sprintf( "%s_AMB_%s_%s.png", 373 $station, $key_ambType, $key_sys ); 374 my $pngNameEPO = sprintf( "%s_EPO_%s_%s.png", 375 $station, $key_ambType, $key_sys ); 376 my $chartAMB = Chart::Gnuplot->new( 377 output => $pngNameAMB, 378 terminal => 'png', 379 title => $station, 380 ylabel => "Ambiguities $key_ambType [m]", 381 382 # yrange => [" 0.0 ", " 90.0 "], 383 xlabel => "Time [h]", 384 timeaxis => 'x', 385 xtics => { labelfmt => '%H:%M', rotate => '-270', }, 386 legend => { position => "outside right", }, 387 grid => 'on', 388 ); 389 my $chartEPO = Chart::Gnuplot->new( 390 output => $pngNameEPO, 391 terminal => 'png', 392 title => $station, 393 ylabel => "Number of Epochs $key_ambType [-]", 394 395 # yrange => [" 0.0 ", " 90.0 "], 396 xlabel => "Time [h]", 397 timeaxis => 'x', 398 xtics => { labelfmt => '%H:%M', rotate => '-270', }, 399 legend => { position => "outside right", }, 400 grid => 'on', 401 ); 402 403 # SATELLITE 404 foreach 405 my $key_sat ( sort keys %{ $AMB{$key_ambType}{$key_sys} } ) 406 { 407 408 #print "$key_sat = $AMB{$key_ambType}{$key_sys}{$key_sat} \n"; 409 # ambiguities 410 my $dataset_amb = Chart::Gnuplot::DataSet->new( 411 xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH} 412 , # array of epochs 413 ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{DATA} 414 , # array of ambiguities of one satellite 415 title => "$key_sat", 416 timefmt => '%s', 417 style => "dots", 418 ); 419 push( @datasets_amb, $dataset_amb ); 420 421 # number of epochs used for ambiguity 422 my $dataset_epo = Chart::Gnuplot::DataSet->new( 423 xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH} 424 , # array of epochs 425 ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{NUMEPO} 426 , # array of ambiguities of one satellite 427 title => "$key_sat", 428 timefmt => '%s', 429 style => "dots", 430 ); 431 push( @datasets_epo, $dataset_epo ); 432 } 433 434 # ambiguities 435 $chartAMB->plot2d(@datasets_amb); 436 437 # system ("display $pngName_amb&"); 438 $y = $y - $dy; 439 if ( $y < 30 / mm ) { 440 $page = $pdf->page(); 441 $page->mediabox('A4'); 442 $y = $y0; 443 } 444 $png = $page->gfx(); 445 LOGDIE("could not find image file: $!\n") unless -e $pngNameAMB; 446 $png->image( $pdf->image_png($pngNameAMB), 447 $x, $y, $width, $height ); 448 449 # number of epochs used for ambiguity 450 $chartEPO->plot2d(@datasets_epo); 451 452 # system ("display $pngName_epo&"); 453 $y = $y - $dy; 454 if ( $y < 30 / mm ) { 455 $page = $pdf->page(); 456 $page->mediabox('A4'); 457 $y = $y0; 458 } 459 $png = $page->gfx(); 460 LOGDIE("could not find image file $pngNameEPO: $!\n") 461 unless -e $pngNameEPO; 462 $png->image( $pdf->image_png($pngNameEPO), 463 $x, $y, $width, $height ); 464 } 465 } 466 467 ######### ION ##################### 468 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 469 DEBUG "Plot ION"; 470 $page = $pdf->page(); 471 $page->mediabox('A4'); 472 $y = $y0 + $dy; 473 $headline = sprintf( "Ionosphere Delay for station %s", $station ); 474 $headline_text = $page->text; 475 $headline_text->font( $font1, 11 / pt ); 476 $headline_text->translate( 15 / mm, 280 / mm ); 477 $headline_text->text($headline); 478 479 my $chartION = newChart($station); 480 $chartION->set( ylabel => "Ionophere Delay [m]" ); 481 $chartION->set( legend => { position => "outside right" } ); 482 483 # SYSTEM 484 foreach my $ksys ( sort keys %ION ) 485 { #print "$key_sys \n"; #print Dumper $ION{$key_sys}; 486 my @datasets; # init datasets 487 my $pngNameION = sprintf( "%s_ION_%s.png", $station, $ksys ); 488 $chartION->set( output => $pngNameION ); 489 490 # SATELLITE 491 foreach my $sat ( sort keys %{ $ION{$ksys} } ) 492 { #print "$key_sat = $ION{$key_sys}{$key_sat} \n"; 493 my $dataset = Chart::Gnuplot::DataSet->new( 494 xdata => $ION{$ksys}{$sat}{EPOCH}, # array of epochs 495 ydata => $ION{$ksys}{$sat}{DATA} 496 , # array of ionvations of one satellite 497 title => "$sat", 498 timefmt => '%s', 499 style => "dots", 500 ); 501 push( @datasets, $dataset ); 502 } 503 504 $chartION->plot2d(@datasets); #system ("display $pngName&"); 505 $y = $y - $dy; 506 if ( $y < 30 / mm ) { 507 $page = $pdf->page(); 508 $page->mediabox('A4'); 509 $y = $y0; 510 } 511 $png = $page->gfx(); 512 die("could not find image file: $!") unless -e $pngNameION; 513 $png->image( $pdf->image_png($pngNameION), 514 $x, $y, $width, $height ); 515 } 516 } 517 518 ######### BIAS ##################### 519 if ( grep ( $_ eq "ALL", @plotTypes ) ) { 520 DEBUG "Plot BIAS"; 521 $page = $pdf->page(); 522 $page->mediabox('A4'); 523 $y = $y0 + $dy; 524 $headline = sprintf( "Receiver Biases for station %s", $station ); 525 $headline_text = $page->text; 526 $headline_text->font( $font1, 11 / pt ); 527 $headline_text->translate( 15 / mm, 280 / mm ); 528 $headline_text->text($headline); 529 530 my $chartBIAS = newChart($station); 531 $chartBIAS->set( legend => { position => "outside right" } ); 532 533 # BIAS_TYPE #print Dumper \%BIA; 534 foreach my $key_biasType ( sort keys %BIA ) 535 { #print "key_biasType: $key_biasType \n"; 536 foreach my $key_sys ( sort keys %{ $BIA{$key_biasType} } ) { 537 538 #print "key_sys: $key_sys \n"; #print Dumper $BIA{$key_biasType}; 539 my @datasets; # init datasets 540 my $pngNameBIA = sprintf( "%s_BIAS_%s_%s.png", 541 $station, $key_biasType, $key_sys ); 542 $chartBIAS->set( output => $pngNameBIA ); 543 $chartBIAS->set( 544 ylabel => "Receiver Bias $key_biasType [m]" ); 545 546 my $dataset = Chart::Gnuplot::DataSet->new( 547 xdata => $BIA{$key_biasType}{$key_sys}{EPOCH}, 548 ydata => $BIA{$key_biasType}{$key_sys}{DATA}, 549 title => "$key_sys", 550 timefmt => '%s', 551 style => "dots", 552 ); 553 push( @datasets, $dataset ); 554 555 $chartBIAS->plot2d(@datasets); 556 $y = $y - $dy; 557 if ( $y < 30 / mm ) { 558 $page = $pdf->page(); 559 $page->mediabox('A4'); 560 $y = $y0; 561 } 562 $png = $page->gfx(); 563 die("could not find image file: $!") unless -e $pngNameBIA; 564 $png->image( $pdf->image_png($pngNameBIA), 565 $x, $y, $width, $height ); 566 } 567 } 568 } 569 570 ######### RES ##################### 571 DEBUG "Plot Residuals"; 572 $page = $pdf->page(); 573 $page->mediabox('A4'); 574 $y = $y0 + $dy; 575 $headline = sprintf( "Residuals for station %s", $station ); 576 $headline_text = $page->text; 577 $headline_text->font( $font1, 11 / pt ); 578 $headline_text->translate( 15 / mm, 280 / mm ); 579 $headline_text->text($headline); 580 581 my $chartRES = newChart($station); 582 $chartRES->set( legend => { position => "outside right" } ); 583 584 # RESIDUAL_TYPE #print Dumper \%RES; 585 foreach my $key_resType ( sort keys %RES ) 586 { #print "key_resType: $key_resType \n"; 587 #SYSTEM 588 foreach my $key_sys ( sort keys %{ $RES{$key_resType} } ) { 589 590 #print "key_sys: $key_sys \n"; #print Dumper $RES{$key_resType}; 591 my @datasets; 592 my $pngNameRES = sprintf( "%s_RES_%s_%s.png", 593 $station, $key_resType, $key_sys ); 594 $chartRES->set( output => $pngNameRES ); 595 $chartRES->set( ylabel => "Residuals $key_resType [m]" ); 596 597 if ( $key_resType =~ /^c/ ) { 598 $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] ); 599 } 600 elsif ( $key_resType =~ /^l/ ) { 601 $chartRES->set( yrange => [ " -0.06 ", " 0.06 " ] ); 602 } 603 604 elsif ( $key_resType =~ /^GIM/ ) { 605 $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] ); 606 } 607 608 # SATELLITE 609 foreach 610 my $key_sat ( sort keys %{ $RES{$key_resType}{$key_sys} } ) 611 { 612 613 #print "$key_sat = $RES{$key_resType}{$key_sys}{$key_sat} \n"; 614 $dataset = Chart::Gnuplot::DataSet->new( 615 xdata => $RES{$key_resType}{$key_sys}{$key_sat}{EPOCH} 616 , # array of epochs 617 ydata => $RES{$key_resType}{$key_sys}{$key_sat}{DATA} 618 , # array of residuals of one satellite 619 title => "$key_sat", 620 timefmt => '%s', 621 style => "dots", 622 ); 623 push( @datasets, $dataset ); 624 } 625 $chartRES->plot2d(@datasets); 626 $y = $y - $dy; 627 if ( $y < 30 / mm ) { 628 $page = $pdf->page(); 629 $page->mediabox('A4'); 630 $y = $y0; 631 } 632 $png = $page->gfx(); 633 LOGDIE("could not find image file: $!\n") unless -e $pngNameRES; 634 $png->image( $pdf->image_png($pngNameRES), 635 $x, $y, $width, $height ); 636 } 637 } 638 } # end if ALL @plotTypes 639 640 $pdf->save(); 641 $pdf->end(); 642 643 system("rm *.png"); 644 if (Common::amInteractiv) { 645 system("evince $inputDir/$pdf_name"); 646 } 580 647 } # ----- next logfile ----- 581 648 582 649 # newChart returns a default chart. 583 650 sub newChart { 584 my $title = shift;585 return Chart::Gnuplot->new(586 terminal => 'png',587 title => $title,588 xlabel => "Time [h]",589 timeaxis => 'x',590 xtics => { labelfmt => '%H:%M', rotate => '-270' },591 grid => 'on',592 );651 my $title = shift; 652 return Chart::Gnuplot->new( 653 terminal => 'png', 654 title => $title, 655 xlabel => "Time [h]", 656 timeaxis => 'x', 657 xtics => { labelfmt => '%H:%M', rotate => '-270' }, 658 grid => 'on', 659 ); 593 660 } 594 661 595 662 sub HELP_MESSAGE { 596 print <<EOI_HILFE;663 print <<EOI_HILFE; 597 664 $prog - plot BNC's PPP results using gnuplot 598 665 … … 611 678 2021 andrea.stuerze\@bkg.bund.de 612 679 EOI_HILFE 613 exit;680 exit; 614 681 }
Note:
See TracChangeset
for help on using the changeset viewer.
