Skip to content

Commit d6f09fd

Browse files
committed
Added dataset config keys for subdaily and collection concept id, fixed iso-8601 datetime bug
1 parent ca510d2 commit d6f09fd

2 files changed

Lines changed: 47 additions & 13 deletions

File tree

bignbit/generate_image_metadata.py

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import uuid
88
import xml.etree.ElementTree as ET
99
from datetime import datetime, timedelta
10-
from typing import Dict, List, Optional
10+
from typing import Dict, List
1111

1212
from cumulus_logger import CumulusLogger
1313
from cumulus_process import Process
@@ -63,15 +63,27 @@ def process(self) -> List[Dict]:
6363
static_data_day = int(static_data_day)
6464
else:
6565
static_data_day = None
66-
67-
file_metadata_list = generate_metadata(cma_file_list, granule_umm_json, pathlib.Path(f"{self.path}"), static_data_day)
66+
67+
subdaily = dataset_config.get('subdaily', False)
68+
69+
file_metadata_list = generate_metadata(
70+
cma_file_list, granule_umm_json,
71+
pathlib.Path(f"{self.path}"),
72+
static_data_day,
73+
subdaily
74+
)
6875
del self.input['granule_umm_json']
6976
del self.input['big']
7077
self.input['big'] = file_metadata_list
7178
return self.input
7279

7380

74-
def generate_metadata(cma_file_list: List[Dict], granule_umm_json: Dict, temp_dir: pathlib.Path, static_data_day: Optional[int] = None) -> List[Dict]:
81+
def generate_metadata(
82+
cma_file_list: List[Dict],
83+
granule_umm_json: Dict,
84+
temp_dir: pathlib.Path,
85+
static_data_day: int | None = None,
86+
subdaily: bool = False) -> List[Dict]:
7587
"""
7688
For each file in the list, create an ImageMetadata-v1.2 xml file and upload it to s3 in the same
7789
bucket and path as the image file.
@@ -89,6 +101,8 @@ def generate_metadata(cma_file_list: List[Dict], granule_umm_json: Dict, temp_di
89101
static_data_day
90102
Optionally, the DatasetConfiguration can override the date metadata in the
91103
granule umm-json
104+
subdaily
105+
boolean flag if product is subdaily (if True, add DataDateTime to metadata)
92106
93107
Returns
94108
-------
@@ -133,7 +147,7 @@ def generate_metadata(cma_file_list: List[Dict], granule_umm_json: Dict, temp_di
133147

134148
# If this is a browse image, generate image metadata for it and upload it to s3
135149
if granule_type == 'browse':
136-
image_metadata_xml = create_metadata_xml(begin, mid, end, dataday, partial_id)
150+
image_metadata_xml = create_metadata_xml(begin, mid, end, dataday, subdaily, partial_id)
137151
temp_xml_path = write_image_metadata_xml(image_metadata_xml, temp_dir)
138152
image_metadata_xml_metadata = get_file_metadata_for_image_metadta_xml(temp_xml_path, cnm_file_meta)
139153
s3_uri = upload_image_metadata_xml(image_metadata_xml_metadata, temp_xml_path)
@@ -267,7 +281,7 @@ def transform_files_to_cnm_product_files(cma_file_meta: Dict, file_type: str, su
267281
return cnm_file_meta
268282

269283

270-
def extract_granule_dates(granule_umm_json: dict, static_data_day: Optional[int] = None) -> tuple[str, str, str, str]:
284+
def extract_granule_dates(granule_umm_json: dict, static_data_day: int | None = None) -> tuple[str, str, str, str]:
271285
"""
272286
Parse the begin, midpoint, end, and dataday for this granule
273287
@@ -326,10 +340,21 @@ def parse_datetime(datetime_str: str) -> datetime:
326340
datetime
327341
a datetime object
328342
"""
329-
try:
330-
return datetime.strptime(datetime_str, "%Y-%m-%dT%H:%M:%S.%fZ")
331-
except ValueError:
332-
return datetime.strptime(datetime_str, "%Y-%m-%dT%H:%M:%SZ")
343+
formats = [
344+
"%Y-%m-%dT%H:%M:%S.%fZ", # 2023-01-01T12:30:45.123456Z
345+
"%Y-%m-%dT%H:%M:%SZ", # 2023-01-01T12:30:45Z
346+
"%Y-%m-%dT%H:%M:%S.%f%z", # 2023-01-01T12:30:45.123456+00:00
347+
"%Y-%m-%dT%H:%M:%S%z", # 2023-01-01T12:30:45+00:00
348+
]
349+
350+
for fmt in formats:
351+
try:
352+
return datetime.strptime(datetime_str, fmt)
353+
except ValueError:
354+
continue
355+
356+
# If none of the formats worked
357+
raise ValueError(f"Unable to parse datetime string: {datetime_str}")
333358

334359

335360
def parse_doy(year: int, doy: int) -> str:
@@ -354,7 +379,7 @@ def parse_doy(year: int, doy: int) -> str:
354379

355380

356381
def create_metadata_xml(beginning_time: str, middle_time: str, ending_time: str, dataday: str,
357-
partial_id: str = None) -> ET.ElementTree:
382+
subdaily: bool = False, partial_id: str | None = None) -> ET.ElementTree:
358383
"""
359384
Create an ImageMetadata-v1.2 XML Element tree
360385
@@ -368,6 +393,8 @@ def create_metadata_xml(beginning_time: str, middle_time: str, ending_time: str,
368393
formatted datetime string for data end date time
369394
dataday
370395
string if format %Y%j for day of year the data represents
396+
subdaily
397+
boolean flag if product is subdaily (if True, add DataDateTime to metadata)
371398
partial_id
372399
partial id associated with data
373400
@@ -384,7 +411,10 @@ def create_metadata_xml(beginning_time: str, middle_time: str, ending_time: str,
384411
ET.SubElement(imagery_metadata, "DataStartDateTime").text = beginning_time
385412
ET.SubElement(imagery_metadata, "DataMidDateTime").text = middle_time
386413
ET.SubElement(imagery_metadata, "DataEndDateTime").text = ending_time
387-
ET.SubElement(imagery_metadata, "DataDay").text = dataday
414+
if subdaily:
415+
ET.SubElement(imagery_metadata, "DataDateTime").text = beginning_time
416+
else:
417+
ET.SubElement(imagery_metadata, "DataDay").text = dataday
388418
if partial_id:
389419
ET.SubElement(imagery_metadata, "PartialId").text = partial_id
390420

bignbit/get_collection_concept_id.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ def process(self) -> dict:
3333
collection_shortname = self.config['collection_shortname']
3434
cmr_provider = self.config['cmr_provider']
3535
cmr_environment = self.config['cmr_environment']
36-
collection_id = get_collection_concept_id(collection_shortname, cmr_provider, cmr_environment)
36+
dataset_config = self.input['datasetConfigurationForBIG']['config']
37+
# Use override for collection concept id from dataset config if provided
38+
collection_id = dataset_config.get('concept_id')
39+
if collection_id is None:
40+
collection_id = get_collection_concept_id(collection_shortname, cmr_provider, cmr_environment)
3741
self.input['collection_concept_id'] = collection_id
3842
return self.input
3943

0 commit comments

Comments
 (0)