ublox-gps-data-processing/notes/combine_rinex.sh

141 lines
4.2 KiB
Bash
Executable file

#!/bin/bash
# combine_rinex.sh - Combine RINEX observation files (supports both 2.x and 3.x)
if [ $# -lt 2 ]; then
echo "Usage: $0 output.obs input_files..."
echo "Example: $0 combined.obs msin*.25o"
echo "Example: $0 combined.obs msin3240.25o msin3250.25o msin3260.25o"
exit 1
fi
output="$1"
shift
# Sort files chronologically (RINEX naming is sortable)
files=$(printf '%s\n' "$@" | sort)
if [ -z "$files" ]; then
echo "Error: No input files specified"
exit 1
fi
# Get first file
first_file=$(echo "$files" | head -1)
# Verify all files exist
echo "Verifying input files..."
for file in $files; do
if [ ! -f "$file" ]; then
echo "Error: File not found: $file"
exit 1
fi
done
file_count=$(echo "$files" | wc -w)
echo "Found $file_count files to combine"
echo ""
# Get header from first file
header_lines=$(grep -n "END OF HEADER" "$first_file" | cut -d: -f1)
if [ -z "$header_lines" ]; then
echo "Error: No RINEX header found in $first_file"
exit 1
fi
# Detect RINEX version from first line
rinex_version=$(head -1 "$first_file" | awk '{print substr($1,1,1)}')
if [ "$rinex_version" = "3" ]; then
echo "Detected: RINEX 3.x format"
epoch_pattern="^>"
elif [ "$rinex_version" = "2" ]; then
echo "Detected: RINEX 2.x format"
epoch_pattern="^ [0-9][0-9] [ 0-9][0-9] [ 0-9][0-9]"
else
echo "Warning: Could not detect RINEX version, assuming 2.x"
epoch_pattern="^ [0-9][0-9] [ 0-9][0-9] [ 0-9][0-9]"
fi
echo ""
# Copy header from first file
head -n $header_lines "$first_file" > "$output"
echo "✓ Added header from $first_file"
# Append data from all files (skip their headers)
total_lines=0
for file in $files; do
data_start=$(($(grep -n "END OF HEADER" "$file" | cut -d: -f1) + 1))
data_lines=$(tail -n +$data_start "$file" | wc -l)
tail -n +$data_start "$file" >> "$output"
total_lines=$((total_lines + data_lines))
echo "✓ Added data from $file ($data_lines lines)"
done
echo ""
# Count epochs based on detected version
if [ "$rinex_version" = "3" ]; then
epochs=$(grep -c "^>" "$output" 2>/dev/null || echo "0")
else
epochs=$(grep -c "^ [0-9][0-9] [ 0-9][0-9] [ 0-9][0-9]" "$output" 2>/dev/null || echo "0")
fi
# Get file size
file_size=$(ls -lh "$output" | awk '{print $5}')
echo "========================================="
echo "✓ Combined file created: $output"
echo " RINEX Version: $rinex_version.x"
echo " Size: $file_size"
echo " Files combined: $file_count"
echo " Total data lines: $total_lines"
echo " Total epochs: $epochs"
echo "========================================="
# Verify reasonable results
if [ $epochs -eq 0 ]; then
echo ""
echo "⚠ WARNING: No epochs detected!"
echo " This may indicate a problem with the combined file."
echo " Checking first few lines of output..."
echo ""
head -40 "$output"
exit 1
fi
# Show time range if epochs found
if [ $epochs -gt 0 ]; then
echo ""
echo "Time range:"
if [ "$rinex_version" = "3" ]; then
# RINEX 3.x format: > YYYY MM DD HH MM SS.SSSSSSS
first_epoch=$(grep "^>" "$output" | head -1)
last_epoch=$(grep "^>" "$output" | tail -1)
first_time=$(echo "$first_epoch" | awk '{printf "%s-%02d-%02d %02d:%02d:%06.3f", $2, $3, $4, $5, $6, $7}')
last_time=$(echo "$last_epoch" | awk '{printf "%s-%02d-%02d %02d:%02d:%06.3f", $2, $3, $4, $5, $6, $7}')
else
# RINEX 2.x format: YY MM DD HH MM SS.SSSSSSS
first_epoch=$(grep "^ [0-9][0-9] [ 0-9][0-9] [ 0-9][0-9]" "$output" | head -1)
last_epoch=$(grep "^ [0-9][0-9] [ 0-9][0-9] [ 0-9][0-9]" "$output" | tail -1)
first_time=$(echo "$first_epoch" | awk '{printf "20%02d-%02d-%02d %02d:%02d:%011.7f", $1, $2, $3, $4, $5, $6}')
last_time=$(echo "$last_epoch" | awk '{printf "20%02d-%02d-%02d %02d:%02d:%011.7f", $1, $2, $3, $4, $5, $6}')
fi
echo " First: $first_time"
echo " Last: $last_time"
fi
# Verify single header (no corruption)
header_count=$(grep -c "END OF HEADER" "$output")
if [ $header_count -ne 1 ]; then
echo ""
echo "⚠ WARNING: Found $header_count headers (expected 1)"
echo " The file may be corrupted!"
exit 1
fi
echo ""
echo "✓ File validation passed"