Skip to content
Snippets Groups Projects
Commit acd4dad3 authored by Yuan Gao's avatar Yuan Gao
Browse files

update the relationship json

parent 0660dafb
No related branches found
No related tags found
No related merge requests found
/* Main styles for Satellite Latency Viewer */
body {
font-family: 'Source Sans Pro', sans-serif;
background-color: #f8f9fa;
color: #333;
/* Status indicators */
.status-exists {
color: green;
font-weight: bold;
}
/* Header Section */
.header-section {
background: #003366;
color: white;
padding: 1.5rem 0;
border-radius: 0 0 6px 6px;
margin-bottom: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.app-title {
font-family: 'Merriweather', serif;
font-weight: 700;
font-size: 2rem;
text-align: center;
margin-bottom: 0.5rem;
letter-spacing: 0.5px;
.status-missing {
color: red;
font-weight: bold;
}
.date-navigation {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.4rem 1rem;
background-color: rgba(255,255,255,0.15);
border-radius: 4px;
margin: 0.8rem auto;
max-width: 400px;
border: 1px solid rgba(255,255,255,0.2);
/* Ingest sources filter styling */
#ingest-checkboxes {
max-height: 200px;
overflow-y: auto;
}
.date-navigation button {
background: transparent;
border: none;
color: white;
font-size: 1rem;
.form-check-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 250px;
cursor: pointer;
transition: all 0.2s ease;
padding: 0.2rem 0.8rem;
}
.date-navigation button:hover {
background-color: rgba(255,255,255,0.2);
border-radius: 4px;
}
#currentDateDisplay {
font-size: 1.1rem;
font-weight: 500;
}
/* Control Panel */
.control-panel {
background: white;
border-radius: 6px;
padding: 1.25rem;
margin-bottom: 1.5rem;
box-shadow: 0 1px 6px rgba(0,0,0,0.05);
border: 1px solid #dee2e6;
}
.form-label {
/* Range selector buttons styling */
.plotly .rangeselector button {
font-weight: 600;
color: #003366;
margin-bottom: 0.4rem;
}
.form-select {
border: 1px solid #ced4da;
border-radius: 4px;
padding: 0.5rem;
transition: all 0.2s ease;
background-color: #f8f9fa;
}
.form-select:focus {
border-color: #003366;
box-shadow: 0 0 0 0.2rem rgba(0, 51, 102, 0.25);
}
/* Debug Toggle */
.debug-toggle {
border-radius: 4px;
font-size: 0.85rem;
padding: 0.3rem 0.8rem;
background-color: #f1f5f9;
color: #003366;
border: 1px solid #d0d7de;
transition: all 0.2s ease;
}
.debug-toggle:hover {
background-color: #e3e8ed;
border-color: #b6bfc9;
}
/* Debug Info Panel */
.debug-info {
background-color: #f8f9fa;
border: 1px solid #ddd;
border-radius: 6px;
padding: 15px;
margin-top: 20px;
font-family: monospace;
display: none;
box-shadow: inset 0 0 3px rgba(0,0,0,0.1);
}
/* Loading and Error Indicators */
.loading {
display: none;
text-align: center;
padding: 20px;
}
.error-message {
color: #dc3545;
text-align: center;
padding: 15px;
display: none;
border-radius: 6px;
background-color: rgba(220, 53, 69, 0.1);
margin: 1rem 0;
}
/* Time Range Selector */
.time-range-selector {
margin-bottom: 15px;
display: flex;
gap: 10px;
}
.time-btn {
padding: 6px 15px;
background-color: #e9ecef;
color: #495057;
background: white;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.2s ease;
padding: 3px 8px;
margin-right: 5px;
}
.time-btn:hover {
background-color: #d1d7dc;
}
.time-btn.active {
background-color: #003366;
.plotly .rangeselector button.active {
color: white;
border-color: #003366;
background: #0d6efd;
border-color: #0d6efd;
}
/* Chart Section */
.chart-wrapper {
background: white;
border-radius: 6px;
padding: 20px 15px;
margin-bottom: 1.5rem;
box-shadow: 0 1px 6px rgba(0,0,0,0.05);
border: 1px solid #dee2e6;
position: relative;
/* Satellite info display */
.satellite-info {
margin-bottom: 0.5rem;
}
.chart-title {
font-family: 'Merriweather', serif;
font-size: 1.5rem;
/* Loading and error indicators */
#loading {
text-align: center;
margin-bottom: 15px;
color: #002855;
font-weight: 600;
padding: 2rem;
}
.chart-container {
height: 450px;
width: 100%;
overflow: hidden;
#errorMessage {
margin-top: 1rem;
margin-bottom: 1rem;
}
/* Data Table */
.table-responsive {
background: white;
border-radius: 6px;
#errorMessage pre {
max-height: 300px;
overflow-y: auto;
background-color: #f8f9fa;
padding: 1rem;
box-shadow: 0 1px 6px rgba(0,0,0,0.05);
border: 1px solid #dee2e6;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.app-title {
font-size: 1.5rem;
}
.date-navigation {
max-width: 300px;
}
.chart-title {
font-size: 1.2rem;
}
.chart-container {
height: 350px;
}
.time-btn {
padding: 5px 10px;
font-size: 0.8rem;
}
border-radius: 0.3rem;
}
\ No newline at end of file
......@@ -2,14 +2,14 @@
"""
End-to-end script to generate a satellite relationships JSON file.
This script:
1. Automatically pulls data for the previous day using sat_latency_interface
1. Automatically pulls data for the previous 7 days using sat_latency_interface
2. Processes the data to extract relationship information
3. Generates the satellite_relationships.json file with consolidated IDs
4. Handles satellite ID variations (e.g., G16/g16, DMSP-17/dmsp17, etc.)
Example usage:
python generate_satellite_relationships.py -o satellite_relationships.json
python generate_satellite_relationships.py -d 2025-02-27 -o satellite_relationships.json
python generate_satellite_relationships.py -d 2025-02-27 -n 7 -o satellite_relationships.json
"""
import os
......@@ -70,24 +70,45 @@ def get_canonical_id(satellite_id):
"""Get canonical ID for a satellite ID variant"""
return SATELLITE_ID_MAPPINGS.get(satellite_id, satellite_id)
def get_previous_day():
"""Get previous day's date in YYYY-MM-DD format"""
yesterday = datetime.now() - timedelta(days=1)
return yesterday.strftime('%Y-%m-%d')
def get_date_range(end_date_str=None, num_days=7):
"""
Get date range for the previous num_days from the end_date.
Args:
end_date_str: End date string in YYYY-MM-DD format, or None for yesterday
num_days: Number of days to go back
Returns:
list: List of date strings in YYYY-MM-DD format
"""
# Use yesterday as the end date if not provided
if not end_date_str:
end_date = datetime.now() - timedelta(days=1)
else:
end_date = datetime.strptime(end_date_str, '%Y-%m-%d')
# Generate list of dates
date_list = []
for i in range(num_days):
date = end_date - timedelta(days=i)
date_list.append(date.strftime('%Y-%m-%d'))
return date_list
def run_sat_latency_query(date_str):
def run_sat_latency_query(start_date_str, end_date_str):
"""
Run sat_latency_interface command to get data for the specified date.
Run sat_latency_interface command to get data for the specified date range.
Args:
date_str: Date string in YYYY-MM-DD format
start_date_str: Start date string in YYYY-MM-DD format
end_date_str: End date string in YYYY-MM-DD format
Returns:
list: Data returned by sat_latency_interface or None if error
"""
# Build start and end time strings
start_time = f"{date_str}T00:00:00"
end_time = f"{date_str}T23:59:59"
start_time = f"{start_date_str}T00:00:00"
end_time = f"{end_date_str}T23:59:59"
# Build the command
base_cmd = "module load miniconda/3.6-base && source activate ~/.mdrexler_conda && sat_latency_interface"
......@@ -245,27 +266,31 @@ def extract_relationships_from_data(data):
return result
def generate_satellite_relationships(date_str=None):
def generate_satellite_relationships(end_date_str=None, num_days=7):
"""
Generate satellite relationships JSON by querying data for the specified date.
Generate satellite relationships JSON by querying data for the specified date range.
Args:
date_str: Date string in YYYY-MM-DD format, or None for previous day
end_date_str: End date string in YYYY-MM-DD format, or None for yesterday
num_days: Number of days to go back
Returns:
dict: Structured relationship information
"""
# Use previous day if no date provided
if not date_str:
date_str = get_previous_day()
# Get the date range
date_range = get_date_range(end_date_str, num_days)
# Use the earliest and latest dates for the query
start_date = date_range[-1] # Last item (earliest date)
end_date = date_range[0] # First item (latest date)
logger.info(f"Generating satellite relationships for date: {date_str}")
logger.info(f"Generating satellite relationships for date range: {start_date} to {end_date}")
# Fetch data for the specified date
data = run_sat_latency_query(date_str)
# Fetch data for the specified date range
data = run_sat_latency_query(start_date, end_date)
if not data:
logger.error(f"Failed to get data for {date_str}")
logger.error(f"Failed to get data for range {start_date} to {end_date}")
return None
# Extract relationships from data
......@@ -275,6 +300,13 @@ def generate_satellite_relationships(date_str=None):
logger.error("Failed to extract relationships from data")
return None
# Add date range information to the output
result["date_range"] = {
"start_date": start_date,
"end_date": end_date,
"days": num_days
}
return result
def save_relationships_json(relationships, output_file):
......@@ -303,13 +335,14 @@ def save_relationships_json(relationships, output_file):
def main():
parser = argparse.ArgumentParser(description='Generate satellite relationships JSON.')
parser.add_argument('-d', '--date', help='Date to query (YYYY-MM-DD). Defaults to previous day')
parser.add_argument('-d', '--date', help='End date to query (YYYY-MM-DD). Defaults to yesterday')
parser.add_argument('-n', '--days', type=int, default=7, help='Number of days to analyze (default: 7)')
parser.add_argument('-o', '--output', default='satellite_relationships.json', help='Output JSON file path')
args = parser.parse_args()
# Generate relationships JSON
result = generate_satellite_relationships(args.date)
result = generate_satellite_relationships(args.date, args.days)
if not result:
logger.error("Failed to generate relationships JSON")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment