@@ -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
0 commit comments