Skip to content

Commit 0408c2f

Browse files
authored
Remove deprecated vXXX handling for scienceFiles (#332)
* add major and minor versions to generate from inputs * remove legacy version * remove all deprecated science version formats vxxx * fix test formats
1 parent e6faf63 commit 0408c2f

7 files changed

Lines changed: 103 additions & 127 deletions

File tree

imap_data_access/file_validation.py

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -180,36 +180,35 @@ def version_regex() -> str:
180180
return Version.valid_imap_version_pattern
181181

182182
@staticmethod
183-
def is_valid_version(version: str) -> bool:
183+
def is_valid_version(
184+
version: str, pattern: str = valid_imap_version_pattern
185+
) -> bool:
184186
"""Check if the version string has a valid format 'vXXX' or 'vMMM.mmmm'.
185187
186188
Parameters
187189
----------
188190
version : str
189191
Version string to check.
192+
pattern : str, optional
193+
Regex pattern to use for validation. Defaults to
194+
valid_imap_version_pattern for version patterns vXXX or vMMM.mmmm.
190195
191196
Returns
192197
-------
193198
bool
194199
Whether the version string is valid or not.
195200
"""
196-
return bool(re.fullmatch(Version.valid_imap_version_pattern, version))
201+
return bool(re.fullmatch(pattern, version))
197202

198203
@staticmethod
199-
def is_valid_version_minor_only(version: str) -> bool:
200-
"""Check if the version string is in the valid minor-only format 'vXXX'.
204+
def is_valid_science_version(version: str) -> bool:
205+
"""Check if the version string has a valid format 'vMMM.mmmm'."""
206+
return Version.is_valid_version(version, Version.science_version_pattern)
201207

202-
Parameters
203-
----------
204-
version : str
205-
Version string to check.
206-
207-
Returns
208-
-------
209-
bool
210-
Whether the version string is valid or not.
211-
"""
212-
return bool(re.fullmatch(Version.minor_only_version_pattern, version))
208+
@staticmethod
209+
def is_valid_version_minor_only(version: str) -> bool:
210+
"""Check if the version string is in the valid minor-only format 'vXXX'."""
211+
return Version.is_valid_version(version, Version.minor_only_version_pattern)
213212

214213
@staticmethod
215214
def _validate_range(value: int, max_value: int) -> None:
@@ -234,6 +233,8 @@ class ImapFilePath:
234233
AncillaryFilePath, and SPICEFilePath.
235234
"""
236235

236+
VALID_VERSION_PATTERN: typing.ClassVar[str] = Version.minor_only_version_pattern
237+
237238
class InvalidImapFileError(Exception):
238239
"""Indicates a bad file type."""
239240

@@ -276,9 +277,9 @@ def is_valid_date(input_date: str) -> bool:
276277
except ValueError:
277278
return False
278279

279-
@staticmethod
280-
def is_valid_version(input_version: str) -> bool:
281-
"""Check input version string is in valid format 'vXXX' or 'latest'.
280+
@classmethod
281+
def is_valid_version(cls, input_version: str) -> bool:
282+
"""Check input version string is "latest" or the class's valid version pattern.
282283
283284
Parameters
284285
----------
@@ -290,8 +291,8 @@ def is_valid_version(input_version: str) -> bool:
290291
bool
291292
Whether input version is valid or not.
292293
"""
293-
return input_version == "latest" or Version.is_valid_version_minor_only(
294-
input_version
294+
return input_version == "latest" or Version.is_valid_version(
295+
input_version, cls.VALID_VERSION_PATTERN
295296
)
296297

297298
@abstractmethod
@@ -311,11 +312,10 @@ class ScienceFilePath(ImapFilePath):
311312
FILENAME_CONVENTION = (
312313
"<mission>_<instrument>_<datalevel>_<descriptor>_"
313314
"<startdate>(-<repointing>)_<version>.<extension>"
314-
" where version is vMMM.mmmm (legacy vXXX is deprecated but supported)"
315+
" where version is vMMM.mmmm (legacy vXXX is deprecated and no longer "
316+
"supported.)"
315317
)
316-
# TODO update this to be Version.science_version_pattern once files have been
317-
# renamed.
318-
VALID_VERSION_PATTERN: typing.ClassVar[str] = Version.valid_imap_version_pattern
318+
VALID_VERSION_PATTERN: typing.ClassVar[str] = Version.science_version_pattern
319319
VALID_EXTENSIONS: typing.ClassVar[set[str]] = {"cdf", "pkts"}
320320
_dir_prefix = "imap"
321321

@@ -347,7 +347,7 @@ def __init__(self, filename: str | Path):
347347
<cr>: This is an optional field describing the Carrington rotation.
348348
format: crXXXXX.
349349
<version>: This stores the data version for this product, format: vMMM.mmmm.
350-
Legacy vXXX is accepted for backward compatibility but deprecated.
350+
vXXX format is deprecated and will raise an error.
351351
352352
Parameters
353353
----------
@@ -371,7 +371,6 @@ def __init__(self, filename: str | Path):
371371
self.start_date = split_filename["start_date"]
372372
self.repointing = split_filename["repointing"]
373373
self.cr = split_filename["cr"]
374-
self.version = split_filename["version"]
375374
self.major_version = split_filename["major_version"]
376375
self.minor_version = split_filename["minor_version"]
377376
self.extension = split_filename["extension"]
@@ -387,7 +386,8 @@ def generate_from_inputs(
387386
data_level: str,
388387
descriptor: str,
389388
start_time: str,
390-
version: str,
389+
major_version: int | None,
390+
minor_version: int,
391391
extension: str = "cdf",
392392
repointing: int | str | None = None,
393393
cr: int | None = None,
@@ -411,8 +411,11 @@ def generate_from_inputs(
411411
The data level for the filename
412412
start_time: str
413413
The start time for the filename
414-
version : str
415-
The version of the data
414+
major_version : int | None
415+
The major version of the data. If None, the version will be constructed
416+
using the minor version in the legacy vXXX format.
417+
minor_version : int
418+
The minor version of the data
416419
extension : str, optional
417420
The extension type of the file. Default is "cdf"
418421
For l0 files, the extension is always "pkts"
@@ -443,9 +446,10 @@ def generate_from_inputs(
443446
)
444447
if cr:
445448
time_field += f"-cr{cr:05d}"
449+
version_str = str(Version(major_version, minor_version))
446450
filename = (
447451
f"imap_{instrument}_{data_level}_{descriptor}_{time_field}_"
448-
f"{version}.{extension}"
452+
f"{version_str}.{extension}"
449453
)
450454
return cls(filename)
451455

@@ -471,8 +475,9 @@ def validate_filename(self) -> str:
471475
self.data_level,
472476
self.descriptor,
473477
self.start_date,
474-
self.version,
475478
self.extension,
479+
self.major_version,
480+
self.minor_version,
476481
]
477482
):
478483
error_message = (
@@ -496,11 +501,6 @@ def validate_filename(self) -> str:
496501
)
497502
if not self.is_valid_date(self.start_date):
498503
error_message += "Invalid start date format. Please use YYYYMMDD format. \n"
499-
if not ScienceFilePath.is_valid_version(self.version):
500-
error_message += (
501-
"Invalid version format. Please use vMMM.mmmm format"
502-
" (vXXX format is deprecated but supported for compatibility).\n"
503-
)
504504
if self.repointing and not isinstance(self.repointing, int):
505505
error_message += "The repointing number should be an integer.\n"
506506

@@ -537,7 +537,8 @@ def extract_filename_components(filename: str | Path) -> dict:
537537
"""Extract all components from filename. Does not validate instrument or level.
538538
539539
Will return a dictionary with the following keys:
540-
{ instrument, datalevel, descriptor, startdate, enddate, version, extension, cr,
540+
{ instrument, datalevel, descriptor, startdate, enddate, major_version,
541+
minor_version, extension, cr,
541542
repointing }
542543
543544
If a match is not found, a ValueError will be raised.
@@ -594,7 +595,7 @@ def extract_filename_components(filename: str | Path) -> dict:
594595
del components["interval_type"]
595596

596597
# Get major and minor versions
597-
version = Version.from_version(components["version"])
598+
version = Version.from_version(components.pop("version"))
598599
components["major_version"] = version.major
599600
components["minor_version"] = version.minor
600601

@@ -650,15 +651,6 @@ def is_valid_cr(input_cr: str) -> bool:
650651
"""
651652
return re.fullmatch(r"cr\d{5}", str(input_cr))
652653

653-
@staticmethod
654-
def is_valid_version(input_version: str) -> bool:
655-
"""Check input version string is valid for science files.
656-
657-
A valid science version is ``vMMM.mmmm`` or legacy ``vXXX``. The special value
658-
``latest`` is also accepted for query-style inputs.
659-
"""
660-
return input_version == "latest" or Version.is_valid_version(input_version)
661-
662654

663655
# Transform the suffix to the directory structure we are using
664656
# Commented out mappings are not being used on IMAP

imap_data_access/io.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def download(file_path: Union[Path, str]) -> Path:
125125

126126

127127
# Too many branches (16 >12)
128-
# ruff: noqa: PLR0912, PLR0915
128+
# ruff: noqa: PLR0912
129129
def _validate_query_parameters(**kwargs) -> None:
130130
"""Validate all parameters used in the query function.
131131
@@ -201,14 +201,6 @@ def _validate_query_parameters(**kwargs) -> None:
201201
" where <num> is a 5 digit integer."
202202
) from err
203203

204-
# Check version make sure to include 'latest'
205-
if table == "science":
206-
if version is not None and not file_validation.ScienceFilePath.is_valid_version(
207-
version
208-
):
209-
raise ValueError(
210-
"Not a valid version, use format 'vMMM.mmmm' or 'vXXX' (deprecated)."
211-
)
212204
elif version is not None and not file_validation.ImapFilePath.is_valid_version(
213205
version
214206
):

imap_data_access/webpoda.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ def _get_latest_version_file_path(
560560
descriptor="raw",
561561
start_time=start_time.strftime("%Y%m%d"),
562562
repointing=repointing,
563-
version=latest_version,
563+
major_version=0,
564+
minor_version=max_minor_version,
564565
)
565566
return science_file.construct_path()

0 commit comments

Comments
 (0)