Changeset 10798 in ntrip for trunk/BNC


Ignore:
Timestamp:
Dec 10, 2025, 2:58:23 PM (7 days ago)
Author:
stuerze
Message:

minor changes

Location:
trunk/BNC/scripts
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/scripts/Bnc.pm

    r10585 r10798  
    2828# =============================================================================
    2929sub 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'",    # 1024x768x24
    46     #                "$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        #    );
    5050
    5151#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");
    5353}
    5454
    5555# Converts options map to string used for calling BNC.
    5656sub 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;
    6666}
    6767
     
    8282# =============================================================================
    8383sub 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;
    157163}
    158164
     
    169175# =============================================================================
    170176sub _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;
    263273}
    264274
     
    274284# =============================================================================
    275285sub 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;
    336357}
    337358
     
    348369# =============================================================================
    349370sub 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 ) {
    392417
    393418# DEBUG ($ln);
    394419# 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
    395420# 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;
    465493}
    466494
     
    478506# =============================================================================
    479507sub 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 );
    635690}
    636691
     
    647702# =============================================================================
    648703sub 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;
    776842}
    777843
  • trunk/BNC/scripts/pppPlot.pl

    r10644 r10798  
    2525
    2626BEGIN {
    27     use FindBin qw($Bin);
    28     use lib "$Bin";
     27        use FindBin qw($Bin);
     28        use lib "$Bin";
    2929}
    3030
     
    4444
    4545use 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.
    5150
    5251# Logging
    5352Log::Log4perl->easy_init(
    54     {
    55 
    56         #file   => "plotPPP.log",
    57         layout => '%d [%c l%L] %p: %m%n',
    58         level  => $TRACE
    59     }
     53        {
     54
     55                #file   => "plotPPP.log",
     56                layout => '%d [%c l%L] %p: %m%n',
     57                level  => $TRACE
     58        }
    6059);
    6160
     
    6867
    6968GetOptions(
    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,
    7473);
    7574
    7675HELP_MESSAGE() if $help;
    7776@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 ) );
    8079unless (@logFiles) { ERROR "logfiles missing"; HELP_MESSAGE() }
    81 DEBUG("\n       plotTpes: @plotTypes\n       logfiles: @logFiles\n       sampling:  $sampling");
     80DEBUG(
     81"\n       plotTpes: @plotTypes\n       logfiles: @logFiles\n       sampling:  $sampling"
     82);
    8283
    8384# -----------------------------------------------------------------------------
     
    9293# Loop over logfiles
    9394foreach 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        }
    580647}    # -----  next logfile  -----
    581648
    582649# newChart returns a default chart.
    583650sub 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        );
    593660}
    594661
    595662sub HELP_MESSAGE {
    596     print <<EOI_HILFE;
     663        print <<EOI_HILFE;
    597664$prog - plot BNC's PPP results using gnuplot
    598665
     
    6116782021 andrea.stuerze\@bkg.bund.de
    612679EOI_HILFE
    613     exit;
     680        exit;
    614681}
Note: See TracChangeset for help on using the changeset viewer.