Index: trunk/BNC/scripts/Bnc.pm
===================================================================
--- trunk/BNC/scripts/Bnc.pm	(revision 10795)
+++ trunk/BNC/scripts/Bnc.pm	(revision 10798)
@@ -28,40 +28,40 @@
 # =============================================================================
 sub callBnc {
-    my ( $bnc, $bnc_ini, $opts ) = @_;
-
-    my $config_file = "";
-    if ( $bnc_ini && -s $bnc_ini ) {
-        $config_file = "--conf $bnc_ini";
-    }
-    else {
-        DEBUG("callBnc: Use default bnc-ini file");
-    }
-
-    my $opts_str = "";
-    if ($opts) { $opts_str = options2string($opts) }
-
-    #    my @cmd = (
-    #                'xvfb-run',
-    #                "--server-args='-screen 0, 1280x1024x8'",    # 1024x768x24
-    #                "$bnc",
-    #                "--nw",
-    #                $opts_str,
-    #    );
+	my ( $bnc, $bnc_ini, $opts ) = @_;
+
+	my $config_file = "";
+	if ( $bnc_ini && -s $bnc_ini ) {
+		$config_file = "--conf $bnc_ini";
+	}
+	else {
+		DEBUG("callBnc: Use default bnc-ini file");
+	}
+
+	my $opts_str = "";
+	if ($opts) { $opts_str = options2string($opts) }
+
+	#    my @cmd = (
+	#                'xvfb-run',
+	#                "--server-args='-screen 0, 1280x1024x8'",    # 1024x768x24
+	#                "$bnc",
+	#                "--nw",
+	#                $opts_str,
+	#    );
 
 #my $rc = call_system("xvfb-run -a -e /home/user/xvfb.err --server-args='-screen 0 1280x1024x8' $bnc --nw $config_file $opts_str");
-    return Common::runCmd("$bnc --nw $config_file $opts_str");
+	return Common::runCmd("$bnc --nw $config_file $opts_str");
 }
 
 # Converts options map to string used for calling BNC.
 sub options2string {
-    my ($opts) = shift;
-
-    my $opts_str = "";
-    if ($opts) {
-        foreach my $key ( keys %{$opts} ) {
-            $opts_str .= "--key $key" . ' "' . $opts->{$key} . '" ';
-        }
-    }
-    return $opts_str;
+	my ($opts) = shift;
+
+	my $opts_str = "";
+	if ($opts) {
+		foreach my $key ( keys %{$opts} ) {
+			$opts_str .= "--key $key" . ' "' . $opts->{$key} . '" ';
+		}
+	}
+	return $opts_str;
 }
 
@@ -82,77 +82,83 @@
 # =============================================================================
 sub parseMessageTypesFromFile {
-    my ( $logfile, $caAbbr, $mytmpPath ) = @_;
-
-    unless ( -s $logfile ) {
-        ERROR "File [$logfile] is empty or does not exist";
-        return;
-    }
-
-    my $tmp                = File::Temp->new( UNLINK => 1, SUFFIX => '.messtyps' );
-    my $casterMessTypeFile = $tmp->filename;
-
-    #my $caster = $logfilename =~ s/\.log\.messtyps//r;
-    #INFO "Process caster '$caster'";
-
-    INFO "Process $logfile";
-
-    # scan beginns with that line: 16-02-18 23:58:02 WTZ37: Get data in RTCM 3.x format
-
-    # First grep for message type lines in bnc-logfile and write them to local temp. directory
-    # NOTE: 'sort -u' because Ephemeries message-types 1019 (GPS), 1020 (GLONASS), 1045 (Galileo) come
-    #       for every sat. at the same time/second. This is done for getting the repetition rate
-    system ("grep \"Received message type\" $logfile | sort -u > $casterMessTypeFile") == 0
-      or ERROR "Fehler: $!";
-
-    # --------------------------------------------
-    # Get message types foreach station/mountpoint
-    # --------------------------------------------
-    my $cmd = "cat $casterMessTypeFile | awk '{print \$3, \$7}' | sort -u";
-    my @messTypes = `$cmd`;    # ['DARX1: 1004\n','DARX1: 1006\n',... ]
-    if ( scalar @messTypes < 1 ) {
-        ERROR "Could not retrieve message types from file $casterMessTypeFile";
-        return;
-    }
-
-    # Note: Skip first 1500 lines because BNC is weird here, all lines with same timestamp, buffer problem?
-
-    # ------------------------------------------------------
-    # Guess repetition rate for each mountpoint/message-type
-    # ------------------------------------------------------
-    # For that get the first $minSamples appearances of mountp with same message type
-    # and build the differences between them
-    my $minSamples = 4;
-    foreach my $mpType (@messTypes) {
-        chomp $mpType;    # 'AUBG3: 1004'
-        my ( $mp, $mt ) = split ( /:\s*/, $mpType );
-        my $cmd  = "grep \"$mp: Received message type $mt\" $logfile";
-        my @rows = `$cmd`;
-        if ( scalar @rows < 1 ) {
-            ERROR "Could not retrieve message types for $mpType from file $casterMessTypeFile";
-            next;
-        }
-
-        if ( scalar @rows <= $minSamples ) {
-            WARN "Could not guess repetition rate for message type $mpType: only " . scalar @rows . " matches found";
-            next;
-        }
-
-        my $repRate = _computeMessTypRepetitonRate( \@rows, $caAbbr );
-        if ($repRate) {
-            $mpType .= '(' . $repRate . ')';
-        }
-    }    # -----  end foreach messageType -----
-
-    #if ( unlink $casterMessTypeFile ) { TRACE "Removed file [$casterMessTypeFile]" }
-
-    # Return an HASH OF ARRAYS with mp as key and the list of messTypes as value
-    my %messTypesHash;
-    foreach (@messTypes) {
-        my @ele = split ( ': ', $_ );
-        my $mp  = shift @ele;
-        push ( @{ $messTypesHash{$mp} }, shift @ele );
-    }
-
-    return \%messTypesHash;
+	my ( $logfile, $caAbbr, $mytmpPath ) = @_;
+
+	unless ( -s $logfile ) {
+		ERROR "File [$logfile] is empty or does not exist";
+		return;
+	}
+
+	my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.messtyps' );
+	my $casterMessTypeFile = $tmp->filename;
+
+	#my $caster = $logfilename =~ s/\.log\.messtyps//r;
+	#INFO "Process caster '$caster'";
+
+	INFO "Process $logfile";
+
+# scan beginns with that line: 16-02-18 23:58:02 WTZ37: Get data in RTCM 3.x format
+
+# First grep for message type lines in bnc-logfile and write them to local temp. directory
+# NOTE: 'sort -u' because Ephemeries message-types 1019 (GPS), 1020 (GLONASS), 1045 (Galileo) come
+#       for every sat. at the same time/second. This is done for getting the repetition rate
+	system(
+"grep \"Received message type\" $logfile | sort -u > $casterMessTypeFile"
+	  ) == 0
+	  or ERROR "Fehler: $!";
+
+	# --------------------------------------------
+	# Get message types foreach station/mountpoint
+	# --------------------------------------------
+	my $cmd = "cat $casterMessTypeFile | awk '{print \$3, \$7}' | sort -u";
+	my @messTypes = `$cmd`;    # ['DARX1: 1004\n','DARX1: 1006\n',... ]
+	if ( scalar @messTypes < 1 ) {
+		ERROR "Could not retrieve message types from file $casterMessTypeFile";
+		return;
+	}
+
+# Note: Skip first 1500 lines because BNC is weird here, all lines with same timestamp, buffer problem?
+
+# ------------------------------------------------------
+# Guess repetition rate for each mountpoint/message-type
+# ------------------------------------------------------
+# For that get the first $minSamples appearances of mountp with same message type
+# and build the differences between them
+	my $minSamples = 4;
+	foreach my $mpType (@messTypes) {
+		chomp $mpType;    # 'AUBG3: 1004'
+		my ( $mp, $mt ) = split( /:\s*/, $mpType );
+		my $cmd  = "grep \"$mp: Received message type $mt\" $logfile";
+		my @rows = `$cmd`;
+		if ( scalar @rows < 1 ) {
+			ERROR
+"Could not retrieve message types for $mpType from file $casterMessTypeFile";
+			next;
+		}
+
+		if ( scalar @rows <= $minSamples ) {
+			WARN
+			  "Could not guess repetition rate for message type $mpType: only "
+			  . scalar @rows
+			  . " matches found";
+			next;
+		}
+
+		my $repRate = _computeMessTypRepetitonRate( \@rows, $caAbbr );
+		if ($repRate) {
+			$mpType .= '(' . $repRate . ')';
+		}
+	}    # -----  end foreach messageType -----
+
+#if ( unlink $casterMessTypeFile ) { TRACE "Removed file [$casterMessTypeFile]" }
+
+	# Return an HASH OF ARRAYS with mp as key and the list of messTypes as value
+	my %messTypesHash;
+	foreach (@messTypes) {
+		my @ele = split( ': ', $_ );
+		my $mp  = shift @ele;
+		push( @{ $messTypesHash{$mp} }, shift @ele );
+	}
+
+	return \%messTypesHash;
 }
 
@@ -169,96 +175,100 @@
 # =============================================================================
 sub _computeMessTypRepetitonRate {
-    my ( $rows, $caAbbr ) = @_;
-
-    my $maxGap = 600;    # if gap > 10min then we guess it is a new scan
-
-    $rows->[0] =~ /.{18}([a-x0-9]+): Received message type (\d+)/i;
-    my $stat  = $1;
-    my $mestp = $2;
-
-    # Create list of unix timestamps
-    my @scans;
-    my $scan = 0;
-    my ( $prevTime, $deltaT ) = ( 0, 0 );
-    foreach (@$rows) {
-        my $uxtime = date2unix( substr ( $_, 0, 17 ) );
-        if ( !$uxtime ) {
-            ERROR "Could not parse date from line $_";
-            next;
-        }
-        $deltaT = $uxtime - $prevTime;
-        next if ( $deltaT == 0 );    # e.g. eph 1019,1020 one message for each sat.
-        next if ( $deltaT <= 1 && $mestp =~ /10(19|20|42|43|44|45|46)|63/ );
-        if ( $prevTime && $deltaT > $maxGap ) {
-            $scan++;
-        }
-        push ( @{ $scans[$scan] }, $uxtime );
-        $prevTime = $uxtime;
-    }
-
-    my @repRates;
-    my $highest_nof_diffs = 0;
-    foreach (@scans) {
-        my @timestamps = @{$_};
-
-        # Compute the differences
-        my @diffs;
-        for ( my $i = 1; $i <= $#timestamps; $i++ ) {
-            push ( @diffs, $timestamps[$i] - $timestamps[ $i - 1 ] );
-        }
-        my $nof_diffs = scalar @diffs;
-
-        if ( $nof_diffs < 2 ) {
-            WARN("$stat: $mestp: only $nof_diffs diffs");
-            next;
-        }
-
-        my ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats( pdl \@diffs );
-        $mean  = sprintf ( "%.0f",  $mean );
-        $rms_n = sprintf ( "%.02f", $rms_n );
-        print $stat, ": ", $mestp, ": ", join ( ' ', @diffs ), "[Sig: $mean, $rms_n]\n";
-
-        if ( $rms_n > 10 ) {
-            WARN("$stat: $mestp: RMS too high: $rms_n");
-            next;
-        }
-
-        # get the most frequent value
-        my %counti = ();
-        $counti{$_}++ foreach (@diffs);
-        my ( $ni, $mfv ) = ( 0, 0 );
-        while ( my ( $k, $v ) = each %counti ) {
-            if ( $v > $ni ) {
-                $ni  = $v;
-                $mfv = $k;
-            }
-        }
-
-        my $rounded_val = $mfv;                                  # init
-        foreach ( ( 1, 5, 10, 15, 30, 60, 120, 150, 300 ) ) {    # most likely values
-            my $mdiff = abs ( $mfv - $_ );
-            if ( $mdiff <= 2 ) {
-                $rounded_val = $_;
-            }
-        }
-        push ( @repRates, [ $rounded_val, $nof_diffs ] );
-
-        if ( $nof_diffs > $highest_nof_diffs ) {
-            $highest_nof_diffs = $nof_diffs;
-        }
-    }    # -----  end foreach scan -----
-
-    my @mostLikelyRates = grep { $_->[1] == $highest_nof_diffs } @repRates;
-    my $mostLikelyRate  = $mostLikelyRates[0]->[0];
-    foreach (@repRates) {
-        if ( abs ( $_->[0] - $mostLikelyRate ) > 2 ) {
-            ERROR "$stat: $caAbbr: $mestp: repetition rates from different scans differ: $mostLikelyRate $_->[0]";
-            if ( scalar @repRates == 2 ) {
-                return;
-            }
-        }
-    }
-
-    return $mostLikelyRate;
+	my ( $rows, $caAbbr ) = @_;
+
+	my $maxGap = 600;    # if gap > 10min then we guess it is a new scan
+
+	$rows->[0] =~ /.{18}([a-x0-9]+): Received message type (\d+)/i;
+	my $stat  = $1;
+	my $mestp = $2;
+
+	# Create list of unix timestamps
+	my @scans;
+	my $scan = 0;
+	my ( $prevTime, $deltaT ) = ( 0, 0 );
+	foreach (@$rows) {
+		my $uxtime = date2unix( substr( $_, 0, 17 ) );
+		if ( !$uxtime ) {
+			ERROR "Could not parse date from line $_";
+			next;
+		}
+		$deltaT = $uxtime - $prevTime;
+		next if ( $deltaT == 0 ); # e.g. eph 1019,1020 one message for each sat.
+		next if ( $deltaT <= 1 && $mestp =~ /10(19|20|42|43|44|45|46)|63/ );
+		if ( $prevTime && $deltaT > $maxGap ) {
+			$scan++;
+		}
+		push( @{ $scans[$scan] }, $uxtime );
+		$prevTime = $uxtime;
+	}
+
+	my @repRates;
+	my $highest_nof_diffs = 0;
+	foreach (@scans) {
+		my @timestamps = @{$_};
+
+		# Compute the differences
+		my @diffs;
+		for ( my $i = 1 ; $i <= $#timestamps ; $i++ ) {
+			push( @diffs, $timestamps[$i] - $timestamps[ $i - 1 ] );
+		}
+		my $nof_diffs = scalar @diffs;
+
+		if ( $nof_diffs < 2 ) {
+			WARN("$stat: $mestp: only $nof_diffs diffs");
+			next;
+		}
+
+		my ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) =
+		  stats( pdl \@diffs );
+		$mean  = sprintf( "%.0f",  $mean );
+		$rms_n = sprintf( "%.02f", $rms_n );
+		print $stat, ": ", $mestp, ": ", join( ' ', @diffs ),
+		  "[Sig: $mean, $rms_n]\n";
+
+		if ( $rms_n > 10 ) {
+			WARN("$stat: $mestp: RMS too high: $rms_n");
+			next;
+		}
+
+		# get the most frequent value
+		my %counti = ();
+		$counti{$_}++ foreach (@diffs);
+		my ( $ni, $mfv ) = ( 0, 0 );
+		while ( my ( $k, $v ) = each %counti ) {
+			if ( $v > $ni ) {
+				$ni  = $v;
+				$mfv = $k;
+			}
+		}
+
+		my $rounded_val = $mfv;    # init
+		foreach ( ( 1, 5, 10, 15, 30, 60, 120, 150, 300 ) )
+		{                          # most likely values
+			my $mdiff = abs( $mfv - $_ );
+			if ( $mdiff <= 2 ) {
+				$rounded_val = $_;
+			}
+		}
+		push( @repRates, [ $rounded_val, $nof_diffs ] );
+
+		if ( $nof_diffs > $highest_nof_diffs ) {
+			$highest_nof_diffs = $nof_diffs;
+		}
+	}    # -----  end foreach scan -----
+
+	my @mostLikelyRates = grep { $_->[1] == $highest_nof_diffs } @repRates;
+	my $mostLikelyRate  = $mostLikelyRates[0]->[0];
+	foreach (@repRates) {
+		if ( abs( $_->[0] - $mostLikelyRate ) > 2 ) {
+			ERROR
+"$stat: $caAbbr: $mestp: repetition rates from different scans differ: $mostLikelyRate $_->[0]";
+			if ( scalar @repRates == 2 ) {
+				return;
+			}
+		}
+	}
+
+	return $mostLikelyRate;
 }
 
@@ -274,64 +284,75 @@
 # =============================================================================
 sub parseConfig {
-    my ($confFile) = @_;
-
-    -s $confFile || LOGDIE "BNC config file \"$confFile\" does not exist\n";
-    TRACE "Parse BNC config file $confFile";
-    open ( my $INP, '<', $confFile ) || die "Could not open file '$confFile': $!";
-    my @confLines = <$INP>;
-    close ($INP);
-
-    my %conf;
-    my $section;    # [General], [PPP]
-    foreach (@confLines) {
-        chomp;
-        s/#.*//;     # entfernt Kommentare
-        s/^\s*//;    # whitespace am Anfang entfernen
-        s/\s+$//;    # entfernt alle whitespaces am Ende
-        next unless length;
-        if ( $_ =~ /\[(\S+)\]/ ) { $section = $1 }
-        next if ( !$section );
-        my ( $key, $val ) = split ( /\s*=\s*/, $_, 2 );
-        if ( !defined $val ) { $val = "" }
-
-        if ( $key eq "mountPoints" ) {
-
-            # Simple parsing
-            $val =~ s/^\/\///;
-            my @mpts = split ( /,\s?\/{2}/, $val );
-            $conf{$section}->{$key} = \@mpts;
-
-            # Extended parsing
-            my @mpts_def = ();
-            foreach (@mpts) {
-
-                #  user:passwd@igs-ip.net:2101/ASPA0 RTCM_3.0 ASM -14.33 189.28 no 1
-                if ( $_ =~
-                    /^([\w-]+):(.+[^@])@([\w\.-]+):(\d{3,5})\/([-\w]+) ([\w\.]+) ?(\w{3})? ([\+\-\d\.]+) ([\+\-\d\.]+) no (\w+)/i
-                  )
-                {
-                    push ( @mpts_def, { caster => $3, port => $4, mp => $5, ntripVers => $10 } );
-                }
-                else { ERROR "$confFile: Could not parse mountPoints string $_" }
-            }
-            $conf{$section}->{'mountPoints_parsed'} = \@mpts_def;
-        }
-        elsif ( $key eq "cmbStreams" ) {
-            my @cmbStrs = split ( /\s*,\s*/, $val );
-            foreach (@cmbStrs) {
-                s/"//g;
-                s/\s+$//;    # entfernt alle whitespaces am Ende
-            }
-            $conf{$section}->{$key} = \@cmbStrs;
-        }
-        else { $conf{$section}->{$key} = $val }
-    }
-
-    my @nofPar = keys %conf;
-    if ( scalar @nofPar < 1 ) {
-        ERROR "No parameter found in BNC conf \"$confFile\"";
-        return;
-    }
-    return \%conf;
+	my ($confFile) = @_;
+
+	-s $confFile || LOGDIE "BNC config file \"$confFile\" does not exist\n";
+	TRACE "Parse BNC config file $confFile";
+	open( my $INP, '<', $confFile )
+	  || die "Could not open file '$confFile': $!";
+	my @confLines = <$INP>;
+	close($INP);
+
+	my %conf;
+	my $section;    # [General], [PPP]
+	foreach (@confLines) {
+		chomp;
+		s/#.*//;     # entfernt Kommentare
+		s/^\s*//;    # whitespace am Anfang entfernen
+		s/\s+$//;    # entfernt alle whitespaces am Ende
+		next unless length;
+		if ( $_ =~ /\[(\S+)\]/ ) { $section = $1 }
+		next if ( !$section );
+		my ( $key, $val ) = split( /\s*=\s*/, $_, 2 );
+		if ( !defined $val ) { $val = "" }
+
+		if ( $key eq "mountPoints" ) {
+
+			# Simple parsing
+			$val =~ s/^\/\///;
+			my @mpts = split( /,\s?\/{2}/, $val );
+			$conf{$section}->{$key} = \@mpts;
+
+			# Extended parsing
+			my @mpts_def = ();
+			foreach (@mpts) {
+
+			#  user:passwd@igs-ip.net:2101/ASPA0 RTCM_3.0 ASM -14.33 189.28 no 1
+				if ( $_ =~
+/^([\w-]+):(.+[^@])@([\w\.-]+):(\d{3,5})\/([-\w]+) ([\w\.]+) ?(\w{3})? ([\+\-\d\.]+) ([\+\-\d\.]+) no (\w+)/i
+				  )
+				{
+					push(
+						@mpts_def,
+						{
+							caster    => $3,
+							port      => $4,
+							mp        => $5,
+							ntripVers => $10
+						}
+					);
+				}
+				else {
+					ERROR "$confFile: Could not parse mountPoints string $_";
+				}
+			}
+			$conf{$section}->{'mountPoints_parsed'} = \@mpts_def;
+		}
+		elsif ( $key eq "cmbStreams" ) {
+			my @cmbStrs = split( /\s*,\s*/, $val );
+			foreach (@cmbStrs) {
+				s/"//g;
+				s/\s+$//;    # entfernt alle whitespaces am Ende
+			}
+			$conf{$section}->{$key} = \@cmbStrs;
+		}
+		else { $conf{$section}->{$key} = $val }
+	}
+
+	my @nofPar = keys %conf;
+	if ( scalar @nofPar < 1 ) {
+		ERROR "No parameter found in BNC conf \"$confFile\"";
+		return;
+	}
+	return \%conf;
 }
 
@@ -348,119 +369,126 @@
 # =============================================================================
 sub parseLogfile {
-    my $file     = shift;
-    my $sampling = shift // 1;
-    my $logMode  = shift // 0;
-
-    open ( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n";
-
-    # Goto last position from last read
-    #my $fPos = filePosition($file);
-    #TRACE "Current file pos: $fPos";
-    $logMode && seek ( $fh, &Common::filePosition($file), 0 );
-
-    #$logMode && seek ( $fh, $fPos, 0 );
-    my $ln = "";
-    my ( @hlp, @epochs, @latencies, @restarts );
-    my $rec = {};
-    while (<$fh>) {
-        chomp ( $ln = $_ );
-        $rec = {};
-
-        if ( $ln =~ /\bNEU/ ) {    # NEU displacements
-            @hlp = split ( /\s+/, $ln );
-            my $tp = Time::Piece->strptime( substr ( $hlp[2], 0, 19 ), '%Y-%m-%d_%H:%M:%S' );
-
-            if ( $hlp[14] eq '-nan' || $hlp[15] eq '-nan' || $hlp[16] eq '-nan' ) {
-                WARN("$hlp[2] $hlp[3]: NEU displacements are NAN");
-                next;
-            }
-
-            #DEBUG ($tp->epoch, $hlp[3]);
-            push (
-                   @epochs,
-                   {
-                     time => $tp->epoch,
-                     site => $hlp[3],
-                     dN   => $hlp[14],
-                     dE   => $hlp[15],
-                     dU   => $hlp[16],
-                     TRP  => $hlp[18] + $hlp[19],
-                   }
-            );
-        }
-        elsif ( index ( $ln, "latency", 25 ) > 1 ) {
+	my $file     = shift;
+	my $sampling = shift // 1;
+	my $logMode  = shift // 0;
+
+	open( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n";
+
+	# Goto last position from last read
+	#my $fPos = filePosition($file);
+	#TRACE "Current file pos: $fPos";
+	$logMode && seek( $fh, &Common::filePosition($file), 0 );
+
+	#$logMode && seek ( $fh, $fPos, 0 );
+	my $ln = "";
+	my ( @hlp, @epochs, @latencies, @restarts );
+	my $rec = {};
+	while (<$fh>) {
+		chomp( $ln = $_ );
+		$rec = {};
+
+		if ( $ln =~ /\bNEU/ ) {    # NEU displacements
+			@hlp = split( /\s+/, $ln );
+			my $tp = Time::Piece->strptime( substr( $hlp[2], 0, 19 ),
+				'%Y-%m-%d_%H:%M:%S' );
+
+			if (   $hlp[14] eq '-nan'
+				|| $hlp[15] eq '-nan'
+				|| $hlp[16] eq '-nan' )
+			{
+				WARN("$hlp[2] $hlp[3]: NEU displacements are NAN");
+				next;
+			}
+
+			#DEBUG ($tp->epoch, $hlp[3]);
+			push(
+				@epochs,
+				{
+					time => $tp->epoch,
+					site => $hlp[3],
+					dN   => $hlp[14],
+					dE   => $hlp[15],
+					dU   => $hlp[16],
+					TRP  => $hlp[18] + $hlp[19],
+				}
+			);
+		}
+		elsif ( index( $ln, "latency", 25 ) > 1 ) {
 
 # DEBUG ($ln);
 # 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
 # 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
-            @hlp = split ( /\s+/, $ln );
-
-            # old latency log format
-            if ( $hlp[2] =~ /:$/ ) {
-                splice @hlp, 3, 0, 'Placeholder:';
-                $hlp[2] =~ s/:$//;
-            }
-            $hlp[3] =~ s/:$//;
-
-            my $tp = Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' );
-            $rec = {
-                     time    => $tp->epoch,
-                     mp      => $hlp[2],
-                     meanLat => $hlp[6] + 0.0,
-                     epochs  => int ( $hlp[14] ),
-                     type    => $hlp[3]
-            };
-
-            # Unter bestimmten Bedingungen werden die gaps nicht rausgeschrieben!
-            if ( $ln =~ /gaps/ ) {
-                $rec->{'gaps'} = int ( $hlp[16] );
-            }
-
-            push ( @latencies, $rec );
-        }
-        elsif ( index ( $ln, "Start BNC" ) > 1 ) {
-
-            # 17-06-13 07:06:58 ========== Start BNC v2.12.3 (LINUX) ==========
-            @hlp = split ( /\s+/, $ln );
-            my $tp = Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' );
-            push (
-                   @restarts,
-                   {
-                     time    => $tp->epoch,
-                     bncvers => $hlp[5]
-                   }
-            );
-        }
-
-    }    # -----  next line  -----
-
-    $logMode && &Common::filePosition( $file, tell ($fh) );    # Remember pos for next read
-    close $fh;
-
-    # Sampling must be done afterwords, for each station separated!
-    my @epochs_sampled;
-    my @sites = map { $_->{'site'} } @epochs;
-
-    #@sites = uniq @sites;
-    my %hlp1 = ();
-    @sites = grep { !$hlp1{$_}++ } @sites;
-    foreach my $s (@sites) {
-        my $epoch_selected = 0;
-        foreach my $rec (@epochs) {
-            next if ( $rec->{'site'} ne $s );
-            if ( $rec->{'time'} - $epoch_selected >= $sampling ) {
-                push ( @epochs_sampled, $rec );
-                $epoch_selected = $rec->{'time'};
-            }
-        }
-    }
-
-    my %data = (
-                 EPOCHS    => \@epochs_sampled,
-                 LATENCIES => \@latencies,
-                 RESTARTS  => \@restarts
-    );
-
-    return \%data;
+			@hlp = split( /\s+/, $ln );
+
+			# old latency log format
+			if ( $hlp[2] =~ /:$/ ) {
+				splice @hlp, 3, 0, 'Placeholder:';
+				$hlp[2] =~ s/:$//;
+			}
+			$hlp[3] =~ s/:$//;
+
+			my $tp =
+			  Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' );
+			$rec = {
+				time    => $tp->epoch,
+				mp      => $hlp[2],
+				meanLat => $hlp[6] + 0.0,
+				epochs  => int( $hlp[14] ),
+				type    => $hlp[3]
+			};
+
+		   # Unter bestimmten Bedingungen werden die gaps nicht rausgeschrieben!
+			if ( $ln =~ /gaps/ ) {
+				$rec->{'gaps'} = int( $hlp[16] );
+			}
+
+			push( @latencies, $rec );
+		}
+		elsif ( index( $ln, "Start BNC" ) > 1 ) {
+
+			# 17-06-13 07:06:58 ========== Start BNC v2.12.3 (LINUX) ==========
+			@hlp = split( /\s+/, $ln );
+			my $tp =
+			  Time::Piece->strptime( "$hlp[0] $hlp[1]", '%y-%m-%d %H:%M:%S' );
+			push(
+				@restarts,
+				{
+					time    => $tp->epoch,
+					bncvers => $hlp[5]
+				}
+			);
+		}
+
+	}    # -----  next line  -----
+
+	$logMode
+	  && &Common::filePosition( $file, tell($fh) ); # Remember pos for next read
+	close $fh;
+
+	# Sampling must be done afterwords, for each station separated!
+	my @epochs_sampled;
+	my @sites = map { $_->{'site'} } @epochs;
+
+	#@sites = uniq @sites;
+	my %hlp1 = ();
+	@sites = grep { !$hlp1{$_}++ } @sites;
+	foreach my $s (@sites) {
+		my $epoch_selected = 0;
+		foreach my $rec (@epochs) {
+			next if ( $rec->{'site'} ne $s );
+			if ( $rec->{'time'} - $epoch_selected >= $sampling ) {
+				push( @epochs_sampled, $rec );
+				$epoch_selected = $rec->{'time'};
+			}
+		}
+	}
+
+	my %data = (
+		EPOCHS    => \@epochs_sampled,
+		LATENCIES => \@latencies,
+		RESTARTS  => \@restarts
+	);
+
+	return \%data;
 }
 
@@ -478,159 +506,186 @@
 # =============================================================================
 sub parsePPPLogfile {
-    my $file       = shift;
-    my $sampling   = shift // 1;
-    my $goBackSecs = shift // 0;
-    my $logMode    = shift // 0;
-
-    if ($logMode) { $goBackSecs = 0 }
-
-    my $startSec;
-    if ($goBackSecs) {
-        $startSec = time () - $goBackSecs;
-    }
-    my $epo;
-    my $old_epochSec = 0;
-    my $epochSec     = 0;
-    my $epochDiff    = 0;
-    my ( @hlp, @N, @E, @U, %SATNUM, @TRP);
-    my ( @EPOCH, );
-    my ( %RECCLK, %AMB, %RES, %ELE, %ION, %BIA);
-    my ( $station, $lki, $sys, $sat, $amb);
-    open ( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n";
-
-    # Goto last position from last read
-    #my $fPos = filePosition($file);
-    #TRACE "Current file pos: $fPos";
-    $logMode && seek ( $fh, filePosition($file), 0 );
-
-    #$logMode && seek ( $fh, $fPos, 0 );
-    my $ln = "";
-    while (<$fh>) {
-        chomp ( $ln = $_ );
-
-        if ( $ln =~ /\bof Epoch\b/ ) {
-
-            # PPP of Epoch 2015-08-27_14:00:15.000
-            if ( $ln =~ /PPP of Epoch (\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})\.\d+/ ) {
-                $epo = $1;    #print "$epo\n";
-            }
-            else { ERROR "strange line: \"$ln\""; next }
-
-            my $tp = Time::Piece->strptime( $epo, '%Y-%m-%d_%H:%M:%S' );
-            $epochSec  = $tp->epoch();
-            $epochDiff = $epochSec - $old_epochSec;
-            next;
-        }
-
-        next if ( !$epo );
-        next if ( defined $startSec && $epochSec < $startSec );
-        next if ( $epochDiff && $epochDiff < $sampling );
-
-        @hlp = split ( /\s+/, $ln );
-
-        if ( $ln =~ /\bdN\b/ ) {
-            push ( @EPOCH, $epochSec );    # besser $epo ?
-            $old_epochSec = $epochSec;
-
-            #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
-            $station = $hlp[1];
-
-            if ( $hlp[19] eq '-nan' || $hlp[24] eq '-nan' || $hlp[29] eq '-nan' ) {
-                WARN("$hlp[0] $station: NEU displacements are NAN");
-            }
-
-            push @N, $hlp[19];
-            push @E, $hlp[24];
-            push @U, $hlp[29];
-        }
-        elsif ( ( $ln =~ /\bAMB\b/ ) && ( $ln !~ /RESET/ ) ) {
-
-            # 2015-08... AMB lIF G04 253.0000 -8.9924 +- 1.7825 el = 22.03 epo = 86
-            $lki = $hlp[2];
-            $sat = $hlp[3];
-            $sys = substr ( $sat, 0, 1 );
-            $amb = $hlp[4] + $hlp[5];
-            push @{ $AMB{$lki}{$sys}{$sat}{EPOCH} },  $epochSec;
-            push @{ $AMB{$lki}{$sys}{$sat}{DATA} },   $amb;
-            push @{ $AMB{$lki}{$sys}{$sat}{NUMEPO} }, $hlp[13];
-            push @{ $ELE{$sys}{$sat}{EPOCH} }, $epochSec;
-            push @{ $ELE{$sys}{$sat}{DATA} },  $hlp[10];
-        }
-        elsif ( $ln =~ /\bRES\b/ && $ln !~ /Neglected/ ) {
-
-            # 2015-08... RES lIF G30  -0.0076
-            $sat = $hlp[3];
-            $lki = $hlp[2];
-            $sys = substr ( $sat, 0, 1 );
-
-            #print "$epo $lki $sys $sat $res\n";
-            push @{ $RES{$lki}{$sys}{$sat}{EPOCH} }, $epochSec;
-            push @{ $RES{$lki}{$sys}{$sat}{DATA} },  $hlp[4];
-        }
-        elsif ( ( $ln =~ /\bION\b/ ) && ( $ln !~ /RESET/ ) ) {
-
-            # 2018-12-01_20:37:58.000 ION      G02     0.0000    -0.3277 +-   2.4663
-            $sat = $hlp[2];
-            $sys = substr ( $sat, 0, 1 );
-            push @{ $ION{$sys}{$sat}{EPOCH} }, $epochSec;
-            push @{ $ION{$sys}{$sat}{DATA} },  $hlp[4];
-        }
-        elsif ( ( $ln =~ /\bBIA\b/ ) && ( $ln !~ /RESET/ ) ) {
-
-            # 2020-12-09_00:55:19.000 BIA  c1  G       0.0000    +2.5149 +-   9.6543
-            $lki = $hlp[2];
-            $sys = $hlp[3];
-            push @{ $BIA{$lki}{$sys}{EPOCH} }, $epochSec;
-            push @{ $BIA{$lki}{$sys}{DATA} },  $hlp[4] + $hlp[5];
-        }
-        elsif ( $ln =~ /\bSATNUM\b/ ) {     # 2015-09... SATNUM G  8
-            push ( @{ $SATNUM{ $hlp[2] } }, $hlp[3] );
-        }
-        elsif ( $ln =~ /\bTRP\b/ ) {        # 2015-08... TRP  2.3803 +0.1009 +- 0.0324
-            push ( @TRP, $hlp[2] + $hlp[3] );
-        }
-        elsif ( $ln =~ /\bREC_CLK\b/) {
-            # 2024-10-20_03:57:30.000 RECCLK  G       0.0000    -1.7861 +-   0.5268
-            $sys = $hlp[2];
-            push @{ $RECCLK{$sys}{EPOCH} }, $epochSec;
-            push @{ $RECCLK{$sys}{DATA} },  $hlp[3] + $hlp[4];
-        }
-    }    # -----  next line  -----
-
-    $logMode && filePosition( $file, tell ($fh) );    # Remember pos for next read
-    close $fh;
-
-    my $nof_epochs = scalar @EPOCH;
-    DEBUG(   "$station: epochs:$nof_epochs, North displac.: "
-           . scalar @N
-           . ", East displac.: "
-           . scalar @E
-           . ", Up displac.: "
-           . scalar @U
-           . ", TRP:"
-           . scalar @TRP
-           );
-    if ( $nof_epochs != scalar @N )                              { LOGDIE "number of epochs and residuals not equal\n" }
-    if ( $nof_epochs != scalar @TRP )                            { LOGDIE "number of epochs and TRP not equal\n" }
-
-
-    if ( !$station ) { WARN "could not grep stationname from file: $file\n" }
-
-    my %data = (
-                 EPOCH   => \@EPOCH,
-                 N       => \@N,
-                 E       => \@E,
-                 U       => \@U,
-                 SATNUM  => \%SATNUM,
-                 TRP     => \@TRP,
-                 RECCLK  => \%RECCLK,
-                 RES     => \%RES,
-                 AMB     => \%AMB,
-                 ELE     => \%ELE,
-                 ION     => \%ION,
-                 BIA     => \%BIA,
-    );
-
-    return ( $station, \%data, 0 );
+	my $file       = shift;
+	my $sampling   = shift // 1;
+	my $goBackSecs = shift // 0;
+	my $logMode    = shift // 0;
+
+	if ($logMode) { $goBackSecs = 0 }
+
+	my $startSec;
+	if ($goBackSecs) {
+		$startSec = time() - $goBackSecs;
+	}
+	my $epo;
+	my $old_epochSec = 0;
+	my $epochSec     = 0;
+	my $epochDiff    = 0;
+	my ( @hlp, @N, @E, @U, @ISFIX, @NUMFIX, @TRP );
+	my ( @EPOCH, );
+	my ( %SATNUM, %RECCLK, %AMB, %RES, %ELE, %ION, %BIA );
+	my ( $station, $lki, $sys, $sat, $amb );
+	open( my $fh, "<", $file ) || LOGDIE "Could not open file $file: $!\n";
+
+	# Goto last position from last read
+	#my $fPos = filePosition($file);
+	#TRACE "Current file pos: $fPos";
+	$logMode && seek( $fh, filePosition($file), 0 );
+
+	#$logMode && seek ( $fh, $fPos, 0 );
+	my $ln = "";
+	while (<$fh>) {
+		chomp( $ln = $_ );
+
+		if ( $ln =~ /\bof Epoch\b/ ) {
+
+			# PPP of Epoch 2015-08-27_14:00:15.000
+			if ( $ln =~
+				/PPP of Epoch (\d{4}-\d{2}-\d{2}_\d{2}:\d{2}:\d{2})\.\d+/ )
+			{
+				$epo = $1;    #print "$epo\n";
+			}
+			else { ERROR "strange line: \"$ln\""; next }
+
+			my $tp = Time::Piece->strptime( $epo, '%Y-%m-%d_%H:%M:%S' );
+			$epochSec  = $tp->epoch();
+			$epochDiff = $epochSec - $old_epochSec;
+			next;
+		}
+
+		next if ( !$epo );
+		next if ( defined $startSec && $epochSec < $startSec );
+		next if ( $epochDiff && $epochDiff < $sampling );
+
+		@hlp = split( /\s+/, $ln );
+		my $numFix = 0;
+		my $isFix;
+		my $strFix = "fix";
+		if ( $ln =~ /\bdN\b/ ) {
+			push( @EPOCH, $epochSec );    # besser $epo ?
+			$old_epochSec = $epochSec;
+
+#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 %
+			$station = $hlp[1];
+
+			if (   $hlp[19] eq '-nan'
+				|| $hlp[24] eq '-nan'
+				|| $hlp[29] eq '-nan' )
+			{
+				WARN("$hlp[0] $station: NEU displacements are NAN");
+			}
+
+			push @N, $hlp[19];
+			push @E, $hlp[24];
+			push @U, $hlp[29];
+
+			if ( $hlp[32] eq $strFix ) {
+				$isFix  = 1;
+				$numFix = int( $hlp[33] );
+			}
+			else {
+				$isFix  = 0;
+				$numFix = 0;
+			}
+			push @ISFIX,  $isFix;
+			push @NUMFIX, $numFix;
+		}
+		elsif ( ( $ln =~ /\bAMB\b/ ) && ( $ln !~ /RESET/ ) ) {
+
+		 # 2015-08... AMB lIF G04 253.0000 -8.9924 +- 1.7825 el = 22.03 epo = 86
+			$lki = $hlp[2];
+			$sat = $hlp[3];
+			$sys = substr( $sat, 0, 1 );
+			$amb = $hlp[4] + $hlp[5];
+			push @{ $AMB{$lki}{$sys}{$sat}{EPOCH} },  $epochSec;
+			push @{ $AMB{$lki}{$sys}{$sat}{DATA} },   $amb;
+			push @{ $AMB{$lki}{$sys}{$sat}{NUMEPO} }, $hlp[13];
+			push @{ $ELE{$sys}{$sat}{EPOCH} }, $epochSec;
+			push @{ $ELE{$sys}{$sat}{DATA} },  $hlp[10];
+		}
+		elsif ( $ln =~ /\bRES\b/ && $ln !~ /Neglected/ ) {
+
+			# 2015-08... RES lIF G30  -0.0076
+			$sat = $hlp[3];
+			$lki = $hlp[2];
+			$sys = substr( $sat, 0, 1 );
+
+			#print "$epo $lki $sys $sat $res\n";
+			push @{ $RES{$lki}{$sys}{$sat}{EPOCH} }, $epochSec;
+			push @{ $RES{$lki}{$sys}{$sat}{DATA} },  $hlp[4];
+		}
+		elsif ( ( $ln =~ /\bION\b/ ) && ( $ln !~ /RESET/ ) ) {
+
+		# 2018-12-01_20:37:58.000 ION      G02     0.0000    -0.3277 +-   2.4663
+			$sat = $hlp[2];
+			$sys = substr( $sat, 0, 1 );
+			push @{ $ION{$sys}{$sat}{EPOCH} }, $epochSec;
+			push @{ $ION{$sys}{$sat}{DATA} },  $hlp[4];
+		}
+		elsif ( ( $ln =~ /\bBIA\b/ ) && ( $ln !~ /RESET/ ) ) {
+
+		# 2020-12-09_00:55:19.000 BIA  c1  G       0.0000    +2.5149 +-   9.6543
+			$lki = $hlp[2];
+			$sys = $hlp[3];
+			push @{ $BIA{$lki}{$sys}{EPOCH} }, $epochSec;
+			push @{ $BIA{$lki}{$sys}{DATA} },  $hlp[4] + $hlp[5];
+		}
+		elsif ( $ln =~ /\bSATNUM\b/ ) {    # 2015-09... SATNUM G  8
+			push( @{ $SATNUM{ $hlp[2] } }, $hlp[3] );
+		}
+		elsif ( $ln =~ /\bTRP\b/ ) {  # 2015-08... TRP  2.3803 +0.1009 +- 0.0324
+			push( @TRP, $hlp[2] + $hlp[3] );
+		}
+		elsif ( $ln =~ /\bREC_CLK\b/ ) {
+
+		 # 2024-10-20_03:57:30.000 RECCLK  G       0.0000    -1.7861 +-   0.5268
+			$sys = $hlp[2];
+			push @{ $RECCLK{$sys}{EPOCH} }, $epochSec;
+			push @{ $RECCLK{$sys}{DATA} },  $hlp[3] + $hlp[4];
+		}
+	}    # -----  next line  -----
+
+	$logMode && filePosition( $file, tell($fh) );   # Remember pos for next read
+	close $fh;
+
+	my $nof_epochs = scalar @EPOCH;
+	DEBUG(  "$station: epochs:$nof_epochs, North displac.: "
+		  . scalar @N
+		  . ", East displac.: "
+		  . scalar @E
+		  . ", Up displac.: "
+		  . scalar @U
+		  . ", isfix: "
+		  . scalar @ISFIX
+		  . ", numfix: "
+		  . scalar @NUMFIX
+		  . ", TRP:"
+		  . scalar @TRP );
+	if ( $nof_epochs != scalar @N ) {
+		LOGDIE "number of epochs and residuals not equal\n";
+	}
+	if ( $nof_epochs != scalar @TRP ) {
+		LOGDIE "number of epochs and TRP not equal\n";
+	}
+
+	if ( !$station ) { WARN "could not grep stationname from file: $file\n" }
+
+	my %data = (
+		EPOCH  => \@EPOCH,
+		N      => \@N,
+		E      => \@E,
+		U      => \@U,
+		ISFIX  => \@ISFIX,
+		NUMFIX => \@NUMFIX,
+		TRP    => \@TRP,
+		SATNUM => \%SATNUM,
+		RECCLK => \%RECCLK,
+		RES    => \%RES,
+		AMB    => \%AMB,
+		ELE    => \%ELE,
+		ION    => \%ION,
+		BIA    => \%BIA,
+	);
+
+	return ( $station, \%data, 0 );
 }
 
@@ -647,131 +702,142 @@
 # =============================================================================
 sub BncStillWorks {
-    my ($bncConfFile) = @_;
-
-    my $timep = Time::Piece->new;
-
-    # for safety if it is exatly at 00:00, add 30 sec
-    my $min_tmp = $timep->strftime("%M");
-    if ( $min_tmp =~ /00|15|30|45/ && $timep->strftime("%S") < 15 ) {
-        $timep += 30;
-        sleep 30;
-    }
-    my $yyyy = $timep->year;
-    my $yy   = $timep->yy;
-    my $doy  = sprintf "%03d", $timep->yday + 1;
-    my $hh   = $timep->strftime("%H");
-    my $h    = uc ( chr ( 65 + $hh ) );
-    my $min  = $timep->min;
-    my $startmin;
-    if    ( $min < 15 )  { $startmin = "00" }
-    elsif ( $min < 30 )  { $startmin = "15" }
-    elsif ( $min < 45 )  { $startmin = "30" }
-    elsif ( $min <= 59 ) { $startmin = "45" }
-    my $bncConf        = parseConf($bncConfFile);
-    my $bncLogFileStub = $bncConf->{'General'}->{'logFile'};
-
-    # BNC log file
-    # ------------
-    my $bncLogFile = "${bncLogFileStub}_" . $timep->strftime("%y%m%d");    # -> bnc.log_160425
-    unless ( -s $bncLogFile ) {
-        WARN("BNC logfile \"$bncLogFile\" is empty or does not exist");
-        return 0;
-    }
-
-    # RINEX Obs Generation
-    # --------------------
-    if ( $bncConf->{'General'}->{'rnxPath'} ) {
-        my $rnxPath = $bncConf->{'General'}->{'rnxPath'};
-        $rnxPath =~ s/\/$//;
-
-        # Write Rnx3 files (i.e. long Rnx3 filenames) 2: on ('rnxV3filenames' is deprecated since 2.12.8!!!)
-        my $writeRnxV3 = $bncConf->{'General'}->{'rnxV3'};
-        my $rnxIntr    = $bncConf->{'General'}->{'rnxIntr'};
-        my $fileMask;
-
-        if ($writeRnxV3) {
-            if ( $rnxIntr eq "1 hour" ) {
-                $fileMask = "*_S_${yyyy}${doy}${hh}??_01H_30S_?O.rnx";
-            }
-            elsif ( $rnxIntr eq "15 min" ) {
-                $fileMask = "*_S_${yyyy}${doy}${hh}${startmin}_15M_01S_?O.rnx";
-            }
-            else {    # daily?
-                $fileMask = "*_S_${yyyy}${doy}????_01D_30S_?O.rnx";    # HRAG00ZAF_S_20191220000_01D_30S_MO.rnx
-            }
-        }
-        else {                                                         # Rnx2
-            if ( $rnxIntr eq "1 hour" ) {
-                $fileMask = "????${doy}${h}.${yy}O";
-            }
-            elsif ( $rnxIntr eq "15 min" ) {
-                $fileMask = "????${doy}${h}${startmin}.${yy}O";
-            }
-            else {                                                     # daily?
-                $fileMask = "????${doy}*.${yy}O";
-            }
-        }
-
-        my @rnxFiles = glob "$rnxPath/$fileMask";
-        if ( scalar @rnxFiles < 1 ) {
-            ERROR("BNC does not create RINEX Obs files. (Filemask: \"$fileMask\" Path: $rnxPath)");
-
-            #return 0;
-        }
-    }
-
-    # RINEX Ephemerides Generation
-    # ----------------------------
-    if ( $bncConf->{'General'}->{'ephPath'} ) {
-        my $rnxPath = $bncConf->{'General'}->{'ephPath'};
-        $rnxPath =~ s/\/$//;
-        my $writeRnxV3 = $bncConf->{'General'}->{'ephV3'};
-        my $rnxIntr    = $bncConf->{'General'}->{'ephIntr'};
-        my $fileMask;
-
-        if ($writeRnxV3) {
-            if ( $rnxIntr eq "1 hour" ) {
-                $fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}00_01H_?N.rnx";
-            }
-            elsif ( $rnxIntr eq "15 min" ) {
-                $fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}${startmin}_15M_?N.rnx"; # BRDC00WRD_S_20191220900_15M_MN.rnx
-            }
-            else {                                                                  # daily?
-                $fileMask = $fileMask = "BRD?00WRD_S_${yyyy}${doy}0000_01D_?N.rnx";
-            }
-        }
-        else {                                                                      # Rnx2
-            $fileMask = "BRD?${doy}*.${yy}N";
-        }
-
-        my @rnxFiles = glob "$rnxPath/$fileMask";
-        if ( scalar @rnxFiles < 1 ) {
-            ERROR("BNC does not create RINEX Nav files. (Filemask: \"$fileMask\" Path: $rnxPath)");
-
-            #return 0;
-        }
-    }
-
-    # Check jobs making PPP
-    # ---------------------
-    if ( $bncConf->{'PPP'}->{'corrMount'} && $bncConf->{'PPP'}->{'staTable'} ) {
-        my $timeOfLastCoo = `grep "NEU:" $bncLogFile | tail -1 | cut -d ' ' -f1,2`;
-        chomp $timeOfLastCoo;
-        if ( !$timeOfLastCoo ) {
-            ERROR "BNC does not compute coordinates";
-            return 0;
-        }
-
-        my $tp    = Time::Piece->strptime( $timeOfLastCoo, '%y-%m-%d %H:%M:%S' );
-        my $now   = Time::Piece->new;
-        my $tdiff = $now - $tp;
-        if ( $tdiff > 1200 ) {
-            ERROR( "Last computed coordinates are " . $tdiff / 60 . " min old" );
-            return 0;
-        }
-    }
-
-    # BNC works
-    return 1;
+	my ($bncConfFile) = @_;
+
+	my $timep = Time::Piece->new;
+
+	# for safety if it is exatly at 00:00, add 30 sec
+	my $min_tmp = $timep->strftime("%M");
+	if ( $min_tmp =~ /00|15|30|45/ && $timep->strftime("%S") < 15 ) {
+		$timep += 30;
+		sleep 30;
+	}
+	my $yyyy = $timep->year;
+	my $yy   = $timep->yy;
+	my $doy  = sprintf "%03d", $timep->yday + 1;
+	my $hh   = $timep->strftime("%H");
+	my $h    = uc( chr( 65 + $hh ) );
+	my $min  = $timep->min;
+	my $startmin;
+	if    ( $min < 15 )  { $startmin = "00" }
+	elsif ( $min < 30 )  { $startmin = "15" }
+	elsif ( $min < 45 )  { $startmin = "30" }
+	elsif ( $min <= 59 ) { $startmin = "45" }
+	my $bncConf        = parseConf($bncConfFile);
+	my $bncLogFileStub = $bncConf->{'General'}->{'logFile'};
+
+	# BNC log file
+	# ------------
+	my $bncLogFile =
+	  "${bncLogFileStub}_" . $timep->strftime("%y%m%d");    # -> bnc.log_160425
+	unless ( -s $bncLogFile ) {
+		WARN("BNC logfile \"$bncLogFile\" is empty or does not exist");
+		return 0;
+	}
+
+	# RINEX Obs Generation
+	# --------------------
+	if ( $bncConf->{'General'}->{'rnxPath'} ) {
+		my $rnxPath = $bncConf->{'General'}->{'rnxPath'};
+		$rnxPath =~ s/\/$//;
+
+# Write Rnx3 files (i.e. long Rnx3 filenames) 2: on ('rnxV3filenames' is deprecated since 2.12.8!!!)
+		my $writeRnxV3 = $bncConf->{'General'}->{'rnxV3'};
+		my $rnxIntr    = $bncConf->{'General'}->{'rnxIntr'};
+		my $fileMask;
+
+		if ($writeRnxV3) {
+			if ( $rnxIntr eq "1 hour" ) {
+				$fileMask = "*_S_${yyyy}${doy}${hh}??_01H_30S_?O.rnx";
+			}
+			elsif ( $rnxIntr eq "15 min" ) {
+				$fileMask = "*_S_${yyyy}${doy}${hh}${startmin}_15M_01S_?O.rnx";
+			}
+			else {    # daily?
+				$fileMask = "*_S_${yyyy}${doy}????_01D_30S_?O.rnx"
+				  ;    # HRAG00ZAF_S_20191220000_01D_30S_MO.rnx
+			}
+		}
+		else {         # Rnx2
+			if ( $rnxIntr eq "1 hour" ) {
+				$fileMask = "????${doy}${h}.${yy}O";
+			}
+			elsif ( $rnxIntr eq "15 min" ) {
+				$fileMask = "????${doy}${h}${startmin}.${yy}O";
+			}
+			else {     # daily?
+				$fileMask = "????${doy}*.${yy}O";
+			}
+		}
+
+		my @rnxFiles = glob "$rnxPath/$fileMask";
+		if ( scalar @rnxFiles < 1 ) {
+			ERROR(
+"BNC does not create RINEX Obs files. (Filemask: \"$fileMask\" Path: $rnxPath)"
+			);
+
+			#return 0;
+		}
+	}
+
+	# RINEX Ephemerides Generation
+	# ----------------------------
+	if ( $bncConf->{'General'}->{'ephPath'} ) {
+		my $rnxPath = $bncConf->{'General'}->{'ephPath'};
+		$rnxPath =~ s/\/$//;
+		my $writeRnxV3 = $bncConf->{'General'}->{'ephV3'};
+		my $rnxIntr    = $bncConf->{'General'}->{'ephIntr'};
+		my $fileMask;
+
+		if ($writeRnxV3) {
+			if ( $rnxIntr eq "1 hour" ) {
+				$fileMask = "BRD?00WRD_S_${yyyy}${doy}${hh}00_01H_?N.rnx";
+			}
+			elsif ( $rnxIntr eq "15 min" ) {
+				$fileMask =
+				  "BRD?00WRD_S_${yyyy}${doy}${hh}${startmin}_15M_?N.rnx"
+				  ;    # BRDC00WRD_S_20191220900_15M_MN.rnx
+			}
+			else {     # daily?
+				$fileMask = $fileMask =
+				  "BRD?00WRD_S_${yyyy}${doy}0000_01D_?N.rnx";
+			}
+		}
+		else {         # Rnx2
+			$fileMask = "BRD?${doy}*.${yy}N";
+		}
+
+		my @rnxFiles = glob "$rnxPath/$fileMask";
+		if ( scalar @rnxFiles < 1 ) {
+			ERROR(
+"BNC does not create RINEX Nav files. (Filemask: \"$fileMask\" Path: $rnxPath)"
+			);
+
+			#return 0;
+		}
+	}
+
+	# Check jobs making PPP
+	# ---------------------
+	if ( $bncConf->{'PPP'}->{'corrMount'} && $bncConf->{'PPP'}->{'staTable'} ) {
+		my $timeOfLastCoo =
+		  `grep "NEU:" $bncLogFile | tail -1 | cut -d ' ' -f1,2`;
+		chomp $timeOfLastCoo;
+		if ( !$timeOfLastCoo ) {
+			ERROR "BNC does not compute coordinates";
+			return 0;
+		}
+
+		my $tp  = Time::Piece->strptime( $timeOfLastCoo, '%y-%m-%d %H:%M:%S' );
+		my $now = Time::Piece->new;
+		my $tdiff = $now - $tp;
+		if ( $tdiff > 1200 ) {
+			ERROR(
+				"Last computed coordinates are " . $tdiff / 60 . " min old" );
+			return 0;
+		}
+	}
+
+	# BNC works
+	return 1;
 }
 
Index: trunk/BNC/scripts/pppPlot.pl
===================================================================
--- trunk/BNC/scripts/pppPlot.pl	(revision 10795)
+++ trunk/BNC/scripts/pppPlot.pl	(revision 10798)
@@ -25,6 +25,6 @@
 
 BEGIN {
-    use FindBin qw($Bin);
-    use lib "$Bin";
+	use FindBin qw($Bin);
+	use lib "$Bin";
 }
 
@@ -44,18 +44,17 @@
 
 use constant {
-               mm   => 25.4 / 72,
-               inch => 1 / 72,
-               pt   => 1,
-};    # There are 72 postscript points in an inch and there are 25.4 millimeters in an inch.
-
+	mm   => 25.4 / 72,
+	inch => 1 / 72,
+	pt   => 1,
+}; # There are 72 postscript points in an inch and there are 25.4 millimeters in an inch.
 
 # Logging
 Log::Log4perl->easy_init(
-    {
-
-        #file   => "plotPPP.log",
-        layout => '%d [%c l%L] %p: %m%n',
-        level  => $TRACE
-    }
+	{
+
+		#file   => "plotPPP.log",
+		layout => '%d [%c l%L] %p: %m%n',
+		level  => $TRACE
+	}
 );
 
@@ -68,16 +67,18 @@
 
 GetOptions(
-            'help'        => \$help,
-            'plotTypes=s' => \@plotTypes,
-            'logFiles=s'  => \@logFiles,
-            'sampling=s'  => \$sampling,
+	'help'        => \$help,
+	'plotTypes=s' => \@plotTypes,
+	'logFiles=s'  => \@logFiles,
+	'sampling=s'  => \$sampling,
 );
 
 HELP_MESSAGE() if $help;
 @plotTypes = qw(NEU) unless (@plotTypes);
-@plotTypes = map {uc} split ( /[, ]/, join ( ',', @plotTypes ) );
-@logFiles  = split ( /[, ]/, join ( ',', @logFiles ) );
+@plotTypes = map { uc } split( /[, ]/, join( ',', @plotTypes ) );
+@logFiles  = split( /[, ]/, join( ',', @logFiles ) );
 unless (@logFiles) { ERROR "logfiles missing"; HELP_MESSAGE() }
-DEBUG("\n       plotTpes: @plotTypes\n       logfiles: @logFiles\n       sampling:  $sampling");
+DEBUG(
+"\n       plotTpes: @plotTypes\n       logfiles: @logFiles\n       sampling:  $sampling"
+);
 
 # -----------------------------------------------------------------------------
@@ -92,507 +93,573 @@
 # Loop over logfiles
 foreach my $file (@logFiles) {
-    DEBUG "Parse logfile $file";
-
-    # -----------------------------------------------------------------------------
-    # Create pdf for plot results
-    # -----------------------------------------------------------------------------
-    my ( $inputFilename, $inputDir, $inputSuffix ) = fileparse( $file, '\..*' );
-    my $pdf_name = sprintf ( "%s.pdf", $inputFilename );
-    my $pdf      = PDF::API2->new( -file => "$inputDir$pdf_name" );
-    my $font1    = $pdf->corefont('Helvetica-Bold');
-
-    # -----------------------------------------------------------------------------
-    # Read logfile
-    # -----------------------------------------------------------------------------
-    my ( $station, $file ) = Bnc::parsePPPLogfile( $file, $sampling );
-    my $EPOCH       = $file->{'EPOCH'};
-    my %RECCLK        = %{ $file->{'RECCLK'} };
-    my %AMB            = %{ $file->{'AMB'} };
-    my %RES            = %{ $file->{'RES'} };
-    my %ELE            = %{ $file->{'ELE'} };
-    my %ION            = %{ $file->{'ION'} };
-    my %BIA            = %{ $file->{'BIA'} };
-
-    # -----------------------------------------------------------------------------
-    # RMS computation
-    # -----------------------------------------------------------------------------
-    my ( $mean, $prms, $median, $min, $max, $adev, $rms_n, $rms_e, $rms_u, $rms_trp );
-    my ( $n, $e, $u, $trp, $str_rms_n, $str_rms_e, $str_rms_u, $str_rms_trp );
-    $n = pdl( $file->{'N'} );
-    ( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats($n);
-    $e = pdl( $file->{'E'} );
-    ( $mean, $prms, $median, $min, $max, $adev, $rms_e ) = stats($e);
-    $u = pdl( $file->{'U'} );
-    ( $mean, $prms, $median, $min, $max, $adev, $rms_u ) = stats($u);
-    $trp = pdl( $file->{'TRP'} );
-    ( $mean, $prms, $median, $min, $max, $adev, $rms_trp ) = stats($trp);
-    $str_rms_n   = sprintf ( " %.2f ", $rms_n );
-    $str_rms_e   = sprintf ( " %.2f ", $rms_e );
-    $str_rms_u   = sprintf ( " %.2f ", $rms_u );
-    $str_rms_trp = sprintf ( " %.2f ", $rms_trp );
-    DEBUG("RMS: North: $str_rms_n, East: $str_rms_e, Up: $str_rms_u, TRP: $str_rms_trp");
-
-    # -----------------------------------------------------------------------------
-    # Plot several data sets
-    # -----------------------------------------------------------------------------
-    my $dataset;
-    ######### NEU #####################
-    DEBUG "Plot NEU";
-    $page = $pdf->page();
-    $page->mediabox('A4');
-    $headline      = sprintf ( "PPP results for station %s", $station );
-    $headline_text = $page->text;
-    $headline_text->font( $font1, 11 / pt );
-    $headline_text->translate( 15 / mm, 280 / mm );
-    $headline_text->text($headline);
-    $y = $y0;
-    my $pngNameNEU  = sprintf ( "%s_NEU.png", $station );
-    my $chartNEU = newChart($station);
-    $chartNEU->set( output => $pngNameNEU);
-    $chartNEU->set( ylabel => "Displacements [m]", yrange => [ " -0.5 ", " 0.5 " ] );
-
-    #y2label => "Number of Satellites [-]", y2range => [" 0 ", " 20 "], y2tics => 'on',
-
-    my $dataN = Chart::Gnuplot::DataSet->new(
-                                              xdata   => $EPOCH,
-                                              ydata   => $file->{'N'},
-                                              title   => "Displacements N, RMS + -$str_rms_n m",
-                                              timefmt => '%s',
-                                              style   => "linespoints",
-    );
-    my $dataE = Chart::Gnuplot::DataSet->new(
-                                              xdata   => $EPOCH,
-                                              ydata   => $file->{'E'},
-                                              title   => "Displacements E, RMS + -$str_rms_e m",
-                                              timefmt => '%s',
-                                              style   => "linespoints",
-    );
-    my $dataU = Chart::Gnuplot::DataSet->new(
-                                              xdata   => $EPOCH,
-                                              ydata   => $file->{'U'},
-                                              title   => "Displacements U, RMS + -$str_rms_u m",
-                                              timefmt => '%s',
-                                              style   => "linespoints",
-    );
-    my @datasets = ( $dataN, $dataE, $dataU );
-    $chartNEU->plot2d(@datasets);
-
-    $png = $page->gfx();
-    LOGDIE("could not find image file: $!\n") unless -e $pngNameNEU;
-    $png->image( $pdf->image_png($pngNameNEU), $x, $y, $width, $height );    #print "y= : $y \n"
-
-    ######### TRP #####################
-    if ( grep ( $_ eq "ALL", @plotTypes ) ) {
-        DEBUG "Plot TRP";
-        my $pngNameTRP  = sprintf ( "%s_TRP.png", $station );
-        my $chartTRP = newChart($station);
-        $chartTRP->set( output => $pngNameTRP);
-        $chartTRP->set( ylabel => "Tropospheric Delay [m]", yrange => [ " 1.0 ", " 3.0 " ] );
-
-        my $dataTRP = Chart::Gnuplot::DataSet->new(
-                                                    xdata   => $EPOCH,
-                                                    ydata   => $file->{'TRP'},
-                                                    title   => "Tropospheric Delay, RMS + -$str_rms_trp m",
-                                                    timefmt => '%s',
-                                                    style   => "points",
-        );
-        $chartTRP->plot2d($dataTRP);
-        $y = $y - $dy;
-
-        if ( $y < 30 / mm ) {
-            $page = $pdf->page();
-            $page->mediabox('A4');
-            $y = $y0;
-        }
-        $png = $page->gfx();
-        LOGDIE("could not find image file: $!\n") unless -e $pngNameTRP;
-        $png->image( $pdf->image_png($pngNameTRP), $x, $y, $width, $height );
-
-        ######### RECCLK #####################
-        DEBUG "Plot Receiver Clocks";
-        $page = $pdf->page();
-        $page->mediabox('A4');
-        $y             = $y0 + $dy;
-        $headline      = sprintf ( "Receiver Clocks for station %s", $station );
-        $headline_text = $page->text;
-        $headline_text->font( $font1, 11 / pt );
-        $headline_text->translate( 15 / mm, 280 / mm );
-        $headline_text->text($headline);
-
-        my $chartRECCLK = newChart($station);
-        $chartRECCLK->set( legend => { position => "outside right" } );
-        my @datasets = ();                                                # init datasets
-        my $pngNameRECCLK  = sprintf ( "%s_RECCLK.png", $station);
-            $chartRECCLK->set( output => $pngNameRECCLK);
-            $chartRECCLK->set( ylabel => "Receiver Clocks [m]" );
-            # SYSTEM
-            foreach my $key_sys ( sort keys %RECCLK ) {
-
-                $dataset = Chart::Gnuplot::DataSet->new(
-                    xdata   => \@{ $RECCLK{$key_sys}{EPOCH} },         # array of epochs
-                    ydata   => \@{ $RECCLK{$key_sys}{DATA} },          # array of elevations of one satellite
-                    title   => "$key_sys",
-                    timefmt => '%s',
-
-                    #style   => "points",
-                    style => "points",
-                );
-                push ( @datasets, $dataset );
-            }
-            $chartRECCLK->plot2d(@datasets);
-
-            # system ("display $pngName&");
-            $y = $y - $dy;
-            if ( $y < 30 / mm ) {
-                $page = $pdf->page();
-                $page->mediabox('A4');
-                $y = $y0;
-            }
-            $png = $page->gfx();
-            die ("could not find image file: $!") unless -e $pngNameRECCLK;
-            $png->image( $pdf->image_png($pngNameRECCLK), $x, $y, $width, $height );
-
-        ######### ELE #####################
-        DEBUG "Plot Elevations";
-        $page = $pdf->page();
-        $page->mediabox('A4');
-        $y             = $y0 + $dy;
-        $headline      = sprintf ( "Satellite Elevations for station %s", $station );
-        $headline_text = $page->text;
-        $headline_text->font( $font1, 11 / pt );
-        $headline_text->translate( 15 / mm, 280 / mm );
-        $headline_text->text($headline);
-
-        my $chartELE = newChart($station);
-        $chartELE->set( legend => { position => "outside right" } );
-
-        # SYSTEM #print Dumper \%ELE;
-        foreach my $key_sys ( sort keys %ELE ) {
-
-            # print "$key_sys \n";# print Dumper $ELE{$key_sys};
-            my @datasets = ();                                                # init datasets
-            my $pngNameELE  = sprintf ( "%s_ELE_%s.png", $station, $key_sys );
-            $chartELE->set( output => $pngNameELE);
-            $chartELE->set( ylabel => "Elevation [°]", yrange => [ " 0.0 ", " 90.0 " ] );
-
-            # SATELLITE
-            foreach my $key_sat ( sort keys %{ $ELE{$key_sys} } ) {
-
-                # print "$key_sat = $ELE{$key_sys}{$key_sat} \n";
-                $dataset = Chart::Gnuplot::DataSet->new(
-                    xdata   => \@{ $ELE{$key_sys}{$key_sat}{EPOCH} },         # array of epochs
-                    ydata   => \@{ $ELE{$key_sys}{$key_sat}{DATA} },          # array of elevations of one satellite
-                    title   => "$key_sat",
-                    timefmt => '%s',
-
-                    #style   => "points",
-                    style => "points",
-                );
-                push ( @datasets, $dataset );
-            }
-            $chartELE->plot2d(@datasets);
-
-            # system ("display $pngName&");
-            $y = $y - $dy;
-            if ( $y < 30 / mm ) {
-                $page = $pdf->page();
-                $page->mediabox('A4');
-                $y = $y0;
-            }
-            $png = $page->gfx();
-            die ("could not find image file: $!") unless -e $pngNameELE;
-            $png->image( $pdf->image_png($pngNameELE), $x, $y, $width, $height );
-        }
-
-        ######### AMB #####################
-        DEBUG "Plot Ambiguities";
-        $page = $pdf->page();
-        $page->mediabox('A4');
-        $y             = $y0 + $dy;
-        $headline      = sprintf ( "Ambiguities for station %s", $station );
-        $headline_text = $page->text;
-        $headline_text->font( $font1, 11 / pt );
-        $headline_text->translate( 15 / mm, 280 / mm );
-        $headline_text->text($headline);
-
-        # AMBIGUITY_TYPE #print Dumper \%AMB;
-        foreach my $key_ambType (%AMB) {    #print "$key_ambType \n";
-            foreach my $key_sys ( sort keys %{ $AMB{$key_ambType} } ) {
-
-                #print "$key_sys \n"; print Dumper $AMB{$key_ambType};
-                my ( @datasets_amb, @datasets_epo );    # init datasets
-                my $pngNameAMB = sprintf ( "%s_AMB_%s_%s.png", $station, $key_ambType, $key_sys );
-                my $pngNameEPO = sprintf ( "%s_EPO_%s_%s.png", $station, $key_ambType, $key_sys );
-                my $chartAMB = Chart::Gnuplot->new(
-                    output   => $pngNameAMB,
-                    terminal => 'png',
-                    title    => $station,
-                    ylabel   => "Ambiguities $key_ambType [m]",
-
-                    # yrange => [" 0.0 ", " 90.0 "],
-                    xlabel   => "Time [h]",
-                    timeaxis => 'x',
-                    xtics    => { labelfmt => '%H:%M', rotate => '-270', },
-                    legend   => { position => "outside right", },
-                    grid     => 'on',
-                );
-                my $chartEPO = Chart::Gnuplot->new(
-                    output   => $pngNameEPO,
-                    terminal => 'png',
-                    title    => $station,
-                    ylabel   => "Number of Epochs $key_ambType [-]",
-
-                    # yrange => [" 0.0 ", " 90.0 "],
-                    xlabel   => "Time [h]",
-                    timeaxis => 'x',
-                    xtics    => { labelfmt => '%H:%M', rotate => '-270', },
-                    legend   => { position => "outside right", },
-                    grid     => 'on',
-                );
-
-                # SATELLITE
-                foreach my $key_sat ( sort keys %{ $AMB{$key_ambType}{$key_sys} } ) {
-
-                    #print "$key_sat = $AMB{$key_ambType}{$key_sys}{$key_sat} \n";
-                    # ambiguities
-                    my $dataset_amb = Chart::Gnuplot::DataSet->new(
-                        xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH},  # array of epochs
-                        ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{DATA},   # array of ambiguities of one satellite
-                        title => "$key_sat",
-                        timefmt => '%s',
-                        style   => "points",
-
-                        #style   => "points",
-                    );
-                    push ( @datasets_amb, $dataset_amb );
-
-                    # number of epochs used for ambiguity
-                    my $dataset_epo = Chart::Gnuplot::DataSet->new(
-                        xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH},  # array of epochs
-                        ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{NUMEPO}, # array of ambiguities of one satellite
-                        title => "$key_sat",
-                        timefmt => '%s',
-
-                        #style   => "points",
-                        style => "points",
-                    );
-                    push ( @datasets_epo, $dataset_epo );
-                }
-
-                # ambiguities
-                $chartAMB->plot2d(@datasets_amb);
-
-                # system ("display $pngName_amb&");
-                $y = $y - $dy;
-                if ( $y < 30 / mm ) {
-                    $page = $pdf->page();
-                    $page->mediabox('A4');
-                    $y = $y0;
-                }
-                $png = $page->gfx();
-                LOGDIE("could not find image file: $!\n") unless -e $pngNameAMB;
-                $png->image( $pdf->image_png($pngNameAMB), $x, $y, $width, $height );
-
-                # number of epochs used for ambiguity
-                $chartEPO->plot2d(@datasets_epo);
-
-                # system ("display $pngName_epo&");
-                $y = $y - $dy;
-                if ( $y < 30 / mm ) {
-                    $page = $pdf->page();
-                    $page->mediabox('A4');
-                    $y = $y0;
-                }
-                $png = $page->gfx();
-                LOGDIE("could not find image file $pngNameEPO: $!\n") unless -e $pngNameEPO;
-                $png->image( $pdf->image_png($pngNameEPO), $x, $y, $width, $height );
-            }
-        }
-
-        ######### ION #####################
-        if ( grep ( $_ eq "ALL", @plotTypes ) ) {
-            DEBUG "Plot ION";
-            $page = $pdf->page();
-            $page->mediabox('A4');
-            $y             = $y0 + $dy;
-            $headline      = sprintf ( "Ionosphere Delay for station %s", $station );
-            $headline_text = $page->text;
-            $headline_text->font( $font1, 11 / pt );
-            $headline_text->translate( 15 / mm, 280 / mm );
-            $headline_text->text($headline);
-
-            my $chartION = newChart($station);
-            $chartION->set( ylabel => "Ionophere Delay [m]" );
-            $chartION->set( legend => { position => "outside right" } );
-
-            # SYSTEM
-            foreach my $ksys ( sort keys %ION ) {    #print "$key_sys \n"; #print Dumper $ION{$key_sys};
-                my @datasets;                        # init datasets
-                my $pngNameION = sprintf ( "%s_ION_%s.png", $station, $ksys );
-                $chartION->set( output => $pngNameION);
-
-                # SATELLITE
-                foreach my $sat ( sort keys %{ $ION{$ksys} } ) {    #print "$key_sat = $ION{$key_sys}{$key_sat} \n";
-                    my $dataset = Chart::Gnuplot::DataSet->new(
-                        xdata   => $ION{$ksys}{$sat}{EPOCH},        # array of epochs
-                        ydata   => $ION{$ksys}{$sat}{DATA},         # array of ionvations of one satellite
-                        title   => "$sat",
-                        timefmt => '%s',
-
-                        #style   => " points ",
-                        style => "points",
-                    );
-                    push ( @datasets, $dataset );
-                }
-
-                $chartION->plot2d(@datasets);                       #system ("display $pngName&");
-                $y = $y - $dy;
-                if ( $y < 30 / mm ) {
-                    $page = $pdf->page();
-                    $page->mediabox('A4');
-                    $y = $y0;
-                }
-                $png = $page->gfx();
-                die ("could not find image file: $!") unless -e $pngNameION;
-                $png->image( $pdf->image_png($pngNameION), $x, $y, $width, $height );
-            }
-        }
-
-        ######### BIAS #####################
-        if ( grep ( $_ eq "ALL", @plotTypes ) ) {
-            DEBUG "Plot BIAS";
-            $page = $pdf->page();
-            $page->mediabox('A4');
-            $y             = $y0 + $dy;
-            $headline      = sprintf ( "Receiver Biases for station %s", $station );
-            $headline_text = $page->text;
-            $headline_text->font( $font1, 11 / pt );
-            $headline_text->translate( 15 / mm, 280 / mm );
-            $headline_text->text($headline);
-
-            my $chartBIAS = newChart($station);
-            $chartBIAS->set( legend => { position => "outside right" } );
-
-            # BIAS_TYPE   #print Dumper \%BIA;
-            foreach my $key_biasType ( sort keys %BIA ) {    #print "key_biasType: $key_biasType \n";
-                foreach my $key_sys ( sort keys %{ $BIA{$key_biasType} } ) {
-
-                    #print "key_sys: $key_sys \n"; #print Dumper $BIA{$key_biasType};
-                    my @datasets;                            # init datasets
-                    my $pngNameBIA = sprintf ( "%s_BIAS_%s_%s.png", $station, $key_biasType, $key_sys );
-                    $chartBIAS->set( output => $pngNameBIA);
-                    $chartBIAS->set( ylabel => "Receiver Bias $key_biasType [m]" );
-
-                    my $dataset =
-                      Chart::Gnuplot::DataSet->new(
-                                                    xdata   => $BIA{$key_biasType}{$key_sys}{EPOCH},
-                                                    ydata   => $BIA{$key_biasType}{$key_sys}{DATA},
-                                                    title   => "$key_sys",
-                                                    timefmt => '%s',
-                                                    style   => "points",
-                      );
-                    push ( @datasets, $dataset );
-
-                    $chartBIAS->plot2d(@datasets);
-                    $y = $y - $dy;
-                    if ( $y < 30 / mm ) {
-                        $page = $pdf->page();
-                        $page->mediabox('A4');
-                        $y = $y0;
-                    }
-                    $png = $page->gfx();
-                    die ("could not find image file: $!") unless -e $pngNameBIA;
-                    $png->image( $pdf->image_png($pngNameBIA), $x, $y, $width, $height );
-                }
-            }
-        }
-
-        ######### RES #####################
-        DEBUG "Plot Residuals";
-        $page = $pdf->page();
-        $page->mediabox('A4');
-        $y             = $y0 + $dy;
-        $headline      = sprintf ( "Residuals for station %s", $station );
-        $headline_text = $page->text;
-        $headline_text->font( $font1, 11 / pt );
-        $headline_text->translate( 15 / mm, 280 / mm );
-        $headline_text->text($headline);
-
-        my $chartRES = newChart($station);
-        $chartRES->set( legend => { position => "outside right" } );
-
-        # RESIDUAL_TYPE   #print Dumper \%RES;
-        foreach my $key_resType ( sort keys %RES ) {    #print "key_resType: $key_resType \n";
-                                                        #SYSTEM
-            foreach my $key_sys ( sort keys %{ $RES{$key_resType} } ) {
-
-                #print "key_sys: $key_sys \n"; #print Dumper $RES{$key_resType};
-                my @datasets;
-                my $pngNameRES = sprintf ( "%s_RES_%s_%s.png", $station, $key_resType, $key_sys );
-                $chartRES->set( output => $pngNameRES);
-                $chartRES->set( ylabel => "Residuals $key_resType [m]" );
-
-                if ( $key_resType =~ /^c/ ) {
-                    $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] );
-                }
-                elsif ( $key_resType =~ /^l/ ) {
-                    $chartRES->set( yrange => [ " -0.06 ", " 0.06 " ] );
-                }
-
-                elsif ( $key_resType =~ /^GIM/ ) {
-                    $chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] );
-                }
-
-                # SATELLITE
-                foreach my $key_sat ( sort keys %{ $RES{$key_resType}{$key_sys} } ) {
-
-                    #print "$key_sat = $RES{$key_resType}{$key_sys}{$key_sat} \n";
-                    $dataset = Chart::Gnuplot::DataSet->new(
-                        xdata   => $RES{$key_resType}{$key_sys}{$key_sat}{EPOCH},  # array of epochs
-                        ydata   => $RES{$key_resType}{$key_sys}{$key_sat}{DATA},   # array of residuals of one satellite
-                        title   => "$key_sat",
-                        timefmt => '%s',
-                        style => "points",
-                    );
-                    push ( @datasets, $dataset );
-                }
-                $chartRES->plot2d(@datasets);
-                $y = $y - $dy;
-                if ( $y < 30 / mm ) {
-                    $page = $pdf->page();
-                    $page->mediabox('A4');
-                    $y = $y0;
-                }
-                $png = $page->gfx();
-                LOGDIE("could not find image file: $!\n") unless -e $pngNameRES;
-                $png->image( $pdf->image_png($pngNameRES), $x, $y, $width, $height );
-            }
-        }
-    }    # end if ALL @plotTypes
-
-    $pdf->save();
-    $pdf->end();
-
-    system ("rm *.png");
-    if (Common::amInteractiv ) {
-      system ("evince $inputDir/$pdf_name");
-    }
+	DEBUG "Parse logfile $file";
+
+ # -----------------------------------------------------------------------------
+ # Create pdf for plot results
+ # -----------------------------------------------------------------------------
+	my ( $inputFilename, $inputDir, $inputSuffix ) = fileparse( $file, '\..*' );
+	my $pdf_name = sprintf( "%s.pdf", $inputFilename );
+	my $pdf      = PDF::API2->new( -file => "$inputDir$pdf_name" );
+	my $font1    = $pdf->corefont('Helvetica-Bold');
+
+ # -----------------------------------------------------------------------------
+ # Read logfile
+ # -----------------------------------------------------------------------------
+	my ( $station, $file ) = Bnc::parsePPPLogfile( $file, $sampling );
+	my $EPOCH  = $file->{'EPOCH'};
+	my $N      = $file->{'N'};
+	my $E      = $file->{'E'};
+	my $U      = $file->{'U'};
+	my $ISFIX  = $file->{'ISFIX'};
+	my $NUMFIX = $file->{'NUMFIX'};
+	my %RECCLK = %{ $file->{'RECCLK'} };
+	my %AMB    = %{ $file->{'AMB'} };
+	my %RES    = %{ $file->{'RES'} };
+	my %ELE    = %{ $file->{'ELE'} };
+	my %ION    = %{ $file->{'ION'} };
+	my %BIA    = %{ $file->{'BIA'} };
+
+ # -----------------------------------------------------------------------------
+ # RMS computation
+ # -----------------------------------------------------------------------------
+	my (
+		$mean, $prms,  $median, $min,   $max,
+		$adev, $rms_n, $rms_e,  $rms_u, $rms_trp
+	);
+	my ( $n, $e, $u, $trp, $str_rms_n, $str_rms_e, $str_rms_u, $str_rms_trp );
+	$n = pdl( $file->{'N'} );
+	( $mean, $prms, $median, $min, $max, $adev, $rms_n ) = stats($n);
+	$e = pdl( $file->{'E'} );
+	( $mean, $prms, $median, $min, $max, $adev, $rms_e ) = stats($e);
+	$u = pdl( $file->{'U'} );
+	( $mean, $prms, $median, $min, $max, $adev, $rms_u ) = stats($u);
+	$trp = pdl( $file->{'TRP'} );
+	( $mean, $prms, $median, $min, $max, $adev, $rms_trp ) = stats($trp);
+	$str_rms_n   = sprintf( " %.2f ", $rms_n );
+	$str_rms_e   = sprintf( " %.2f ", $rms_e );
+	$str_rms_u   = sprintf( " %.2f ", $rms_u );
+	$str_rms_trp = sprintf( " %.2f ", $rms_trp );
+	DEBUG("RMS: North: $str_rms_n, East: $str_rms_e, Up: $str_rms_u, TRP: $str_rms_trp");
+
+ # -----------------------------------------------------------------------------
+ # Plot several data sets
+ # -----------------------------------------------------------------------------
+	my $dataset;
+	$page = $pdf->page();
+	$page->mediabox('A4');
+	$headline      = sprintf( "PPP results for station %s", $station );
+	$headline_text = $page->text;
+	$headline_text->font( $font1, 11 / pt );
+	$headline_text->translate( 15 / mm, 280 / mm );
+	$headline_text->text($headline);
+	$y = $y0;
+
+	######### NEU #####################
+	DEBUG "Plot NEU";
+	my $pngNameNEU = sprintf( "%s_NEU.png", $station );
+	my $chartNEU   = newChart($station);
+	$chartNEU->set(
+		output => $pngNameNEU,
+		ylabel => "Displacements [m]",
+		yrange => [ " -0.5 ", " 0.5 " ],
+	);
+	my $dataN = Chart::Gnuplot::DataSet->new(
+		xdata   => $EPOCH,
+		ydata   => $N,
+		title   => "Displacements N, RMS + -$str_rms_n m",
+		timefmt => '%s',
+		style   => "dots",
+	);
+	my $dataE = Chart::Gnuplot::DataSet->new(
+		xdata   => $EPOCH,
+		ydata   => $E,
+		title   => "Displacements E, RMS + -$str_rms_e m",
+		timefmt => '%s',
+		style   => "dots",
+	);
+	my $dataU = Chart::Gnuplot::DataSet->new(
+		xdata   => $EPOCH,
+		ydata   => $U,
+		title   => "Displacements U, RMS + -$str_rms_u m",
+		timefmt => '%s',
+		style   => "dots",
+	);
+
+	my @datasets = ( $dataN, $dataE, $dataU );
+	$chartNEU->plot2d(@datasets);
+
+	$png = $page->gfx();
+	LOGDIE("could not find image file: $!\n") unless -e $pngNameNEU;
+	$png->image( $pdf->image_png($pngNameNEU), $x, $y, $width, $height );
+
+	######### FIX #####################
+	if ( grep ( $_ eq "ALL", @plotTypes ) ) {
+		DEBUG "Plot FIX";
+		my $pngNameFIX = sprintf( "%s_FIX.png", $station );
+		my $chartFIX   = newChart($station);
+		$chartFIX->set(
+			output => $pngNameFIX,
+			ylabel => "Fixed [%]",
+			yrange => [ "0", "100" ],
+			ytics  => 20,
+		);
+
+		my $dataNUMFIX = Chart::Gnuplot::DataSet->new(
+			xdata   => $EPOCH,
+			ydata   => $NUMFIX,
+			timefmt => '%s',
+			style   => "impulse",
+			color   => "green",
+		);
+
+		$chartFIX->plot2d($dataNUMFIX);
+		$y = $y - $dy;
+		if ( $y < 30 / mm ) {
+			$page = $pdf->page();
+			$page->mediabox('A4');
+			$y = $y0;
+		}
+		$png = $page->gfx();
+		LOGDIE("could not find image file: $!\n") unless -e $pngNameFIX;
+		$png->image( $pdf->image_png($pngNameFIX), $x, $y, $width, $height );
+	}
+	######### TRP #####################
+	if ( grep ( $_ eq "ALL", @plotTypes ) ) {
+		DEBUG "Plot TRP";
+		my $pngNameTRP = sprintf( "%s_TRP.png", $station );
+		my $chartTRP   = newChart($station);
+		$chartTRP->set( output => $pngNameTRP );
+		$chartTRP->set(
+			ylabel => "Tropospheric Delay [m]",
+			yrange => [ " 1.0 ", " 3.0 " ]
+		);
+		my $dataTRP = Chart::Gnuplot::DataSet->new(
+			xdata   => $EPOCH,
+			ydata   => $file->{'TRP'},
+			title   => "Tropospheric Delay, RMS + -$str_rms_trp m",
+			timefmt => '%s',
+			style   => "dots",
+		);
+		$chartTRP->plot2d($dataTRP);
+		$y = $y - $dy;
+
+		if ( $y < 30 / mm ) {
+			$page = $pdf->page();
+			$page->mediabox('A4');
+			$y = $y0;
+		}
+		$png = $page->gfx();
+		LOGDIE("could not find image file: $!\n") unless -e $pngNameTRP;
+		$png->image( $pdf->image_png($pngNameTRP), $x, $y, $width, $height );
+
+		######### RECCLK #####################
+		DEBUG "Plot Receiver Clocks";
+		$page = $pdf->page();
+		$page->mediabox('A4');
+		$y             = $y0 + $dy;
+		$headline      = sprintf( "Receiver Clocks for station %s", $station );
+		$headline_text = $page->text;
+		$headline_text->font( $font1, 11 / pt );
+		$headline_text->translate( 15 / mm, 280 / mm );
+		$headline_text->text($headline);
+
+		my $chartRECCLK = newChart($station);
+		$chartRECCLK->set( legend => { position => "outside right" } );
+		my @datasets      = ();                                  # init datasets
+		my $pngNameRECCLK = sprintf( "%s_RECCLK.png", $station );
+		$chartRECCLK->set( output => $pngNameRECCLK );
+		$chartRECCLK->set( ylabel => "Receiver Clocks [m]" );
+
+		# SYSTEM
+		foreach my $key_sys ( sort keys %RECCLK ) {
+
+			$dataset = Chart::Gnuplot::DataSet->new(
+				xdata => \@{ $RECCLK{$key_sys}{EPOCH} },    # array of epochs
+				ydata => \@{ $RECCLK{$key_sys}{DATA} }
+				,    # array of elevations of one satellite
+				title   => "$key_sys",
+				timefmt => '%s',
+				style   => "dots",
+			);
+			push( @datasets, $dataset );
+		}
+		$chartRECCLK->plot2d(@datasets);
+
+		# system ("display $pngName&");
+		$y = $y - $dy;
+		if ( $y < 30 / mm ) {
+			$page = $pdf->page();
+			$page->mediabox('A4');
+			$y = $y0;
+		}
+		$png = $page->gfx();
+		die("could not find image file: $!") unless -e $pngNameRECCLK;
+		$png->image( $pdf->image_png($pngNameRECCLK), $x, $y, $width, $height );
+
+		######### ELE #####################
+		DEBUG "Plot Elevations";
+		$page = $pdf->page();
+		$page->mediabox('A4');
+		$y        = $y0 + $dy;
+		$headline = sprintf( "Satellite Elevations for station %s", $station );
+		$headline_text = $page->text;
+		$headline_text->font( $font1, 11 / pt );
+		$headline_text->translate( 15 / mm, 280 / mm );
+		$headline_text->text($headline);
+
+		my $chartELE = newChart($station);
+		$chartELE->set( legend => { position => "outside right" } );
+
+		# SYSTEM #print Dumper \%ELE;
+		foreach my $key_sys ( sort keys %ELE ) {
+
+			# print "$key_sys \n";# print Dumper $ELE{$key_sys};
+			my @datasets = ();    # init datasets
+			my $pngNameELE = sprintf( "%s_ELE_%s.png", $station, $key_sys );
+			$chartELE->set( output => $pngNameELE );
+			$chartELE->set(
+				ylabel => "Elevation [°]",
+				yrange => [ " 0.0 ", " 90.0 " ]
+			);
+
+			# SATELLITE
+			foreach my $key_sat ( sort keys %{ $ELE{$key_sys} } ) {
+
+				# print "$key_sat = $ELE{$key_sys}{$key_sat} \n";
+				$dataset = Chart::Gnuplot::DataSet->new(
+					xdata => \@{ $ELE{$key_sys}{$key_sat}{EPOCH} }
+					,    # array of epochs
+					ydata => \@{ $ELE{$key_sys}{$key_sat}{DATA} }
+					,    # array of elevations of one satellite
+					title   => "$key_sat",
+					timefmt => '%s',
+					style   => "dots",
+				);
+				push( @datasets, $dataset );
+			}
+			$chartELE->plot2d(@datasets);
+
+			# system ("display $pngName&");
+			$y = $y - $dy;
+			if ( $y < 30 / mm ) {
+				$page = $pdf->page();
+				$page->mediabox('A4');
+				$y = $y0;
+			}
+			$png = $page->gfx();
+			die("could not find image file: $!") unless -e $pngNameELE;
+			$png->image( $pdf->image_png($pngNameELE), $x, $y, $width,
+				$height );
+		}
+
+		######### AMB #####################
+		DEBUG "Plot Ambiguities";
+		$page = $pdf->page();
+		$page->mediabox('A4');
+		$y             = $y0 + $dy;
+		$headline      = sprintf( "Ambiguities for station %s", $station );
+		$headline_text = $page->text;
+		$headline_text->font( $font1, 11 / pt );
+		$headline_text->translate( 15 / mm, 280 / mm );
+		$headline_text->text($headline);
+
+		# AMBIGUITY_TYPE #print Dumper \%AMB;
+		foreach my $key_ambType (%AMB) {    #print "$key_ambType \n";
+			foreach my $key_sys ( sort keys %{ $AMB{$key_ambType} } ) {
+
+				#print "$key_sys \n"; print Dumper $AMB{$key_ambType};
+				my ( @datasets_amb, @datasets_epo );    # init datasets
+				my $pngNameAMB = sprintf( "%s_AMB_%s_%s.png",
+					$station, $key_ambType, $key_sys );
+				my $pngNameEPO = sprintf( "%s_EPO_%s_%s.png",
+					$station, $key_ambType, $key_sys );
+				my $chartAMB = Chart::Gnuplot->new(
+					output   => $pngNameAMB,
+					terminal => 'png',
+					title    => $station,
+					ylabel   => "Ambiguities $key_ambType [m]",
+
+					# yrange => [" 0.0 ", " 90.0 "],
+					xlabel   => "Time [h]",
+					timeaxis => 'x',
+					xtics    => { labelfmt => '%H:%M', rotate => '-270', },
+					legend   => { position => "outside right", },
+					grid     => 'on',
+				);
+				my $chartEPO = Chart::Gnuplot->new(
+					output   => $pngNameEPO,
+					terminal => 'png',
+					title    => $station,
+					ylabel   => "Number of Epochs $key_ambType [-]",
+
+					# yrange => [" 0.0 ", " 90.0 "],
+					xlabel   => "Time [h]",
+					timeaxis => 'x',
+					xtics    => { labelfmt => '%H:%M', rotate => '-270', },
+					legend   => { position => "outside right", },
+					grid     => 'on',
+				);
+
+				# SATELLITE
+				foreach
+				  my $key_sat ( sort keys %{ $AMB{$key_ambType}{$key_sys} } )
+				{
+
+				  #print "$key_sat = $AMB{$key_ambType}{$key_sys}{$key_sat} \n";
+				  # ambiguities
+					my $dataset_amb = Chart::Gnuplot::DataSet->new(
+						xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH}
+						,    # array of epochs
+						ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{DATA}
+						,    # array of ambiguities of one satellite
+						title   => "$key_sat",
+						timefmt => '%s',
+						style   => "dots",
+					);
+					push( @datasets_amb, $dataset_amb );
+
+					# number of epochs used for ambiguity
+					my $dataset_epo = Chart::Gnuplot::DataSet->new(
+						xdata => $AMB{$key_ambType}{$key_sys}{$key_sat}{EPOCH}
+						,    # array of epochs
+						ydata => $AMB{$key_ambType}{$key_sys}{$key_sat}{NUMEPO}
+						,    # array of ambiguities of one satellite
+						title   => "$key_sat",
+						timefmt => '%s',
+						style   => "dots",
+					);
+					push( @datasets_epo, $dataset_epo );
+				}
+
+				# ambiguities
+				$chartAMB->plot2d(@datasets_amb);
+
+				# system ("display $pngName_amb&");
+				$y = $y - $dy;
+				if ( $y < 30 / mm ) {
+					$page = $pdf->page();
+					$page->mediabox('A4');
+					$y = $y0;
+				}
+				$png = $page->gfx();
+				LOGDIE("could not find image file: $!\n") unless -e $pngNameAMB;
+				$png->image( $pdf->image_png($pngNameAMB),
+					$x, $y, $width, $height );
+
+				# number of epochs used for ambiguity
+				$chartEPO->plot2d(@datasets_epo);
+
+				# system ("display $pngName_epo&");
+				$y = $y - $dy;
+				if ( $y < 30 / mm ) {
+					$page = $pdf->page();
+					$page->mediabox('A4');
+					$y = $y0;
+				}
+				$png = $page->gfx();
+				LOGDIE("could not find image file $pngNameEPO: $!\n")
+				  unless -e $pngNameEPO;
+				$png->image( $pdf->image_png($pngNameEPO),
+					$x, $y, $width, $height );
+			}
+		}
+
+		######### ION #####################
+		if ( grep ( $_ eq "ALL", @plotTypes ) ) {
+			DEBUG "Plot ION";
+			$page = $pdf->page();
+			$page->mediabox('A4');
+			$y        = $y0 + $dy;
+			$headline = sprintf( "Ionosphere Delay for station %s", $station );
+			$headline_text = $page->text;
+			$headline_text->font( $font1, 11 / pt );
+			$headline_text->translate( 15 / mm, 280 / mm );
+			$headline_text->text($headline);
+
+			my $chartION = newChart($station);
+			$chartION->set( ylabel => "Ionophere Delay [m]" );
+			$chartION->set( legend => { position => "outside right" } );
+
+			# SYSTEM
+			foreach my $ksys ( sort keys %ION )
+			{    #print "$key_sys \n"; #print Dumper $ION{$key_sys};
+				my @datasets;    # init datasets
+				my $pngNameION = sprintf( "%s_ION_%s.png", $station, $ksys );
+				$chartION->set( output => $pngNameION );
+
+				# SATELLITE
+				foreach my $sat ( sort keys %{ $ION{$ksys} } )
+				{    #print "$key_sat = $ION{$key_sys}{$key_sat} \n";
+					my $dataset = Chart::Gnuplot::DataSet->new(
+						xdata => $ION{$ksys}{$sat}{EPOCH},    # array of epochs
+						ydata => $ION{$ksys}{$sat}{DATA}
+						,    # array of ionvations of one satellite
+						title   => "$sat",
+						timefmt => '%s',
+						style   => "dots",
+					);
+					push( @datasets, $dataset );
+				}
+
+				$chartION->plot2d(@datasets);    #system ("display $pngName&");
+				$y = $y - $dy;
+				if ( $y < 30 / mm ) {
+					$page = $pdf->page();
+					$page->mediabox('A4');
+					$y = $y0;
+				}
+				$png = $page->gfx();
+				die("could not find image file: $!") unless -e $pngNameION;
+				$png->image( $pdf->image_png($pngNameION),
+					$x, $y, $width, $height );
+			}
+		}
+
+		######### BIAS #####################
+		if ( grep ( $_ eq "ALL", @plotTypes ) ) {
+			DEBUG "Plot BIAS";
+			$page = $pdf->page();
+			$page->mediabox('A4');
+			$y        = $y0 + $dy;
+			$headline = sprintf( "Receiver Biases for station %s", $station );
+			$headline_text = $page->text;
+			$headline_text->font( $font1, 11 / pt );
+			$headline_text->translate( 15 / mm, 280 / mm );
+			$headline_text->text($headline);
+
+			my $chartBIAS = newChart($station);
+			$chartBIAS->set( legend => { position => "outside right" } );
+
+			# BIAS_TYPE   #print Dumper \%BIA;
+			foreach my $key_biasType ( sort keys %BIA )
+			{    #print "key_biasType: $key_biasType \n";
+				foreach my $key_sys ( sort keys %{ $BIA{$key_biasType} } ) {
+
+			   #print "key_sys: $key_sys \n"; #print Dumper $BIA{$key_biasType};
+					my @datasets;    # init datasets
+					my $pngNameBIA = sprintf( "%s_BIAS_%s_%s.png",
+						$station, $key_biasType, $key_sys );
+					$chartBIAS->set( output => $pngNameBIA );
+					$chartBIAS->set(
+						ylabel => "Receiver Bias $key_biasType [m]" );
+
+					my $dataset = Chart::Gnuplot::DataSet->new(
+						xdata   => $BIA{$key_biasType}{$key_sys}{EPOCH},
+						ydata   => $BIA{$key_biasType}{$key_sys}{DATA},
+						title   => "$key_sys",
+						timefmt => '%s',
+						style   => "dots",
+					);
+					push( @datasets, $dataset );
+
+					$chartBIAS->plot2d(@datasets);
+					$y = $y - $dy;
+					if ( $y < 30 / mm ) {
+						$page = $pdf->page();
+						$page->mediabox('A4');
+						$y = $y0;
+					}
+					$png = $page->gfx();
+					die("could not find image file: $!") unless -e $pngNameBIA;
+					$png->image( $pdf->image_png($pngNameBIA),
+						$x, $y, $width, $height );
+				}
+			}
+		}
+
+		######### RES #####################
+		DEBUG "Plot Residuals";
+		$page = $pdf->page();
+		$page->mediabox('A4');
+		$y             = $y0 + $dy;
+		$headline      = sprintf( "Residuals for station %s", $station );
+		$headline_text = $page->text;
+		$headline_text->font( $font1, 11 / pt );
+		$headline_text->translate( 15 / mm, 280 / mm );
+		$headline_text->text($headline);
+
+		my $chartRES = newChart($station);
+		$chartRES->set( legend => { position => "outside right" } );
+
+		# RESIDUAL_TYPE   #print Dumper \%RES;
+		foreach my $key_resType ( sort keys %RES )
+		{    #print "key_resType: $key_resType \n";
+				#SYSTEM
+			foreach my $key_sys ( sort keys %{ $RES{$key_resType} } ) {
+
+				#print "key_sys: $key_sys \n"; #print Dumper $RES{$key_resType};
+				my @datasets;
+				my $pngNameRES = sprintf( "%s_RES_%s_%s.png",
+					$station, $key_resType, $key_sys );
+				$chartRES->set( output => $pngNameRES );
+				$chartRES->set( ylabel => "Residuals $key_resType [m]" );
+
+				if ( $key_resType =~ /^c/ ) {
+					$chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] );
+				}
+				elsif ( $key_resType =~ /^l/ ) {
+					$chartRES->set( yrange => [ " -0.06 ", " 0.06 " ] );
+				}
+
+				elsif ( $key_resType =~ /^GIM/ ) {
+					$chartRES->set( yrange => [ " -6.0 ", " 6.0 " ] );
+				}
+
+				# SATELLITE
+				foreach
+				  my $key_sat ( sort keys %{ $RES{$key_resType}{$key_sys} } )
+				{
+
+				  #print "$key_sat = $RES{$key_resType}{$key_sys}{$key_sat} \n";
+					$dataset = Chart::Gnuplot::DataSet->new(
+						xdata => $RES{$key_resType}{$key_sys}{$key_sat}{EPOCH}
+						,    # array of epochs
+						ydata => $RES{$key_resType}{$key_sys}{$key_sat}{DATA}
+						,    # array of residuals of one satellite
+						title   => "$key_sat",
+						timefmt => '%s',
+						style   => "dots",
+					);
+					push( @datasets, $dataset );
+				}
+				$chartRES->plot2d(@datasets);
+				$y = $y - $dy;
+				if ( $y < 30 / mm ) {
+					$page = $pdf->page();
+					$page->mediabox('A4');
+					$y = $y0;
+				}
+				$png = $page->gfx();
+				LOGDIE("could not find image file: $!\n") unless -e $pngNameRES;
+				$png->image( $pdf->image_png($pngNameRES),
+					$x, $y, $width, $height );
+			}
+		}
+	}    # end if ALL @plotTypes
+
+	$pdf->save();
+	$pdf->end();
+
+	system("rm *.png");
+	if (Common::amInteractiv) {
+		system("evince $inputDir/$pdf_name");
+	}
 }    # -----  next logfile  -----
 
 # newChart returns a default chart.
 sub newChart {
-    my $title = shift;
-    return Chart::Gnuplot->new(
-                                terminal => 'png',
-                                title    => $title,
-                                xlabel   => "Time [h]",
-                                timeaxis => 'x',
-                                xtics    => { labelfmt => '%H:%M', rotate => '-270' },
-                                grid     => 'on',
-    );
+	my $title = shift;
+	return Chart::Gnuplot->new(
+		terminal => 'png',
+		title    => $title,
+		xlabel   => "Time [h]",
+		timeaxis => 'x',
+		xtics    => { labelfmt => '%H:%M', rotate => '-270' },
+		grid     => 'on',
+	);
 }
 
 sub HELP_MESSAGE {
-    print <<EOI_HILFE;
+	print <<EOI_HILFE;
 $prog - plot BNC's PPP results using gnuplot
 
@@ -611,4 +678,4 @@
 2021 andrea.stuerze\@bkg.bund.de
 EOI_HILFE
-    exit;
+	exit;
 }
