Skip to content

Commit 3ecd63c

Browse files
committed
dev
1 parent 5a7da0f commit 3ecd63c

File tree

6 files changed

+99
-172
lines changed

6 files changed

+99
-172
lines changed

cf/read_write/read.py

Lines changed: 65 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -600,14 +600,6 @@ def __new__(
600600

601601
aggregate_options["copy"] = False
602602

603-
# Parse the extra parameter
604-
if extra is None:
605-
extra = ()
606-
elif isinstance(extra, str):
607-
extra = (extra,)
608-
609-
ftypes = set()
610-
611603
# Count the number of fields (in all files) and the number of
612604
# files
613605
field_counter = -1
@@ -657,39 +649,20 @@ def __new__(
657649
if info:
658650
logger.info(f"File: {filename}") # pragma: no cover
659651

660-
if um:
661-
ftype = "UM"
662-
else:
663-
try:
664-
ftype = cls.file_format(filename)
665-
except Exception as error:
666-
if not ignore_read_error:
667-
raise ValueError(error)
668-
669-
logger.warning(f"WARNING: {error}") # pragma: no cover
670-
continue
671-
672-
if domain and ftype == "UM":
673-
raise ValueError(
674-
f"Can't read PP/UM file {filename} into domain "
675-
"constructs"
676-
)
677-
678-
ftypes.add(ftype)
679-
680652
# --------------------------------------------------------
681653
# Read the file
682654
# --------------------------------------------------------
655+
ftypes = [None]
683656
file_contents = cls._read_a_file(
684657
filename,
685-
ftype=ftype,
658+
ftypes=ftypes,
686659
external=external,
687660
ignore_read_error=ignore_read_error,
688661
verbose=verbose,
689662
warnings=warnings,
690663
aggregate=aggregate,
691664
aggregate_options=aggregate_options,
692-
selected_fmt=fmt,
665+
fmt=fmt,
693666
um=um,
694667
extra=extra,
695668
height_at_top_of_model=height_at_top_of_model,
@@ -711,9 +684,10 @@ def __new__(
711684
)
712685

713686
# --------------------------------------------------------
714-
# Select matching fields (not from UM files, yet)
687+
# Select matching fields (only from netCDF files at
688+
# this stage - we'll do UM fields later)
715689
# --------------------------------------------------------
716-
if select and ftype != "UM":
690+
if select and ftypes[-1] == "netCDF":
717691
file_contents = file_contents.select_by_identity(*select)
718692

719693
# --------------------------------------------------------
@@ -787,14 +761,14 @@ def _plural(n): # pragma: no cover
787761
def _read_a_file(
788762
cls,
789763
filename,
790-
ftype=None,
764+
ftypes=None,
791765
aggregate=True,
792766
aggregate_options=None,
793767
ignore_read_error=False,
794768
verbose=None,
795769
warnings=False,
796770
external=None,
797-
selected_fmt=None,
771+
fmt=None,
798772
um=None,
799773
extra=None,
800774
height_at_top_of_model=None,
@@ -821,7 +795,7 @@ def _read_a_file(
821795
filename: `str`
822796
See `cf.read` for details.
823797
824-
ftype: `str`
798+
ftypes: `str` TODOCFA
825799
The file format to interpret the file. Recognised formats are
826800
``'netCDF'``, ``'CDL'``, ``'UM'`` and ``'PP'``.
827801
@@ -885,70 +859,22 @@ def _read_a_file(
885859
The field or domain constructs in the dataset.
886860
887861
"""
888-
if aggregate_options is None:
889-
aggregate_options = {}
890-
891-
# Find this file's type
892-
fmt = None
893-
word_size = None
894-
endian = None
895-
height_at_top_of_model = None
896-
umversion = 405
897-
898-
if um:
899-
fmt = um.get("fmt")
900-
word_size = um.get("word_size")
901-
endian = um.get("endian")
902-
umversion = um.get("version", umversion)
903-
height_at_top_of_model = um.get("height_at_top_of_model")
904-
905-
if fmt is not None:
906-
fmt = fmt.upper()
907-
908-
if umversion is not None:
909-
umversion = float(str(umversion).replace(".", "0", 1))
862+
if fmt:
863+
if isinstance(fmt, str):
864+
fmt = (fmt,)
910865

911-
# extra_read_vars = {
912-
# "fmt": selected_fmt,
913-
# "ignore_read_error": ignore_read_error,
914-
# }
866+
fmt = set(fmt)
915867

916-
# ----------------------------------------------------------------
917-
# Still here? Read the file into fields or domains.
918-
# ----------------------------------------------------------------
919-
# originally_cdl = ftype == "CDL"
920-
# if originally_cdl:
921-
# # Create a temporary netCDF file from input CDL
922-
# ftype = "netCDF"
923-
# cdl_filename = filename
924-
# filename = cls.netcdf.cdl_to_netcdf(filename)
925-
# extra_read_vars["fmt"] = "NETCDF"
926-
#
927-
# if not cls.netcdf.is_netcdf_file(filename):
928-
# error_msg = (
929-
# f"Can't determine format of file {filename} generated "
930-
# f"from CDL file {cdl_filename}"
931-
# )
932-
# if ignore_read_error:
933-
# logger.warning(error_msg) # pragma: no cover
934-
# return FieldList()
935-
# else:
936-
# raise IOError(error_msg)
937-
938-
if ftype in ("netCDF", "CDL"): # and extra_read_vars["fmt"] in (
939-
# None,
940-
# "NETCDF",
941-
# "CDL",
942-
# "CFA",
943-
# ):
868+
errors = []
869+
870+
try:
944871
out = super().__new__(
945872
cls,
946873
filename,
947874
external=external,
948875
extra=extra,
949876
verbose=verbose,
950877
warnings=warnings,
951-
# extra_read_vars=extra_read_vars,
952878
mask=mask,
953879
unpack=unpack,
954880
warn_valid=warn_valid,
@@ -963,79 +889,61 @@ def _read_a_file(
963889
to_memory=to_memory,
964890
squeeze=squeeze,
965891
unsqueeze=unsqueeze,
966-
)
967-
elif ftype == "UM": # and extra_read_vars["fmt"] in (None, "UM"):
968-
if domain:
969-
raise ValueError(
970-
"Can't set domain=True when reading UM or PP datasets"
971-
)
972-
973-
out = cls.um.read(
974-
filename,
975-
um_version=umversion,
976-
verbose=verbose,
977-
set_standard_name=False,
978-
height_at_top_of_model=height_at_top_of_model,
979892
fmt=fmt,
980-
word_size=word_size,
981-
endian=endian,
982-
select=select,
983-
squeeze=squeeze,
984-
unsqueeze=unsqueeze,
893+
ignore_unknown_format=ignore_read_error,
985894
)
895+
except RuntimeError as error:
896+
if fmt is None or fmt.intersection(("UM",)):
897+
# Set to None to indicate that we should try other
898+
# file formats
899+
errors.append(error)
900+
out = None
901+
else:
902+
raise
903+
else:
904+
if out or not ignore_read_error:
905+
ftypes.append("netCDF")
906+
else:
907+
# Set to None to indicate that we should try other
908+
# file formats
909+
out = None
986910

987-
# PP fields are aggregated intrafile prior to interfile
988-
# aggregation
989-
if aggregate:
990-
# For PP fields, the default is strict_units=False
991-
if "strict_units" not in aggregate_options:
992-
aggregate_options["relaxed_units"] = True
911+
if out is None:
912+
if not um:
913+
um = {}
993914

915+
try:
916+
out = cls.um.read(
917+
filename,
918+
um_version=um.get("version"),
919+
verbose=verbose,
920+
set_standard_name=False,
921+
height_at_top_of_model=height_at_top_of_model,
922+
fmt=um.get("fmt"),
923+
word_size=um.get("word_size"),
924+
endian=um.get("endian"),
925+
select=select,
926+
squeeze=squeeze,
927+
unsqueeze=unsqueeze,
928+
domain=domain,
929+
)
930+
except Exception as error:
931+
errors.append(error)
932+
errors = '\n'.join(map(str, errors))
933+
raise RuntimeError(f"\n{errors}")
934+
else:
935+
if out or not ignore_read_error:
936+
ftypes.append("UM")
937+
938+
# UM fields are aggregated intrafile prior to
939+
# interfile aggregation
940+
if aggregate:
941+
# Set defaults specific to UM fields
942+
if "strict_units" not in aggregate_options:
943+
aggregate_options["relaxed_units"] = True
944+
994945
# Return the fields/domains
995946
if domain:
996947
return DomainList(out)
997948

998949
return FieldList(out)
999-
1000-
@classmethod
1001-
def file_format(cls, filename):
1002-
"""Return the file format.
1003-
1004-
:Parameters:
1005-
1006-
filename: `str`
1007-
The file name.
1008-
1009-
:Returns:
1010-
1011-
`str`
1012-
The format type of the file. One of ``'netCDF'``, ``'UM'``
1013-
or ``'CDL'``.
1014-
1015-
**Examples**
1016-
1017-
>>> r.file_format(filename)
1018-
'netCDF'
1019-
1020-
"""
1021-
# ----------------------------------------------------------------
1022-
# NetCDF
1023-
# ----------------------------------------------------------------
1024-
fmt = cls.netcdf.file_format(filename)
1025-
if fmt:
1026-
return fmt
1027-
1028-
# ----------------------------------------------------------------
1029-
# PP or FF
1030-
# ----------------------------------------------------------------
1031-
if cls.um.is_um_file(filename):
1032-
return "UM"
1033-
1034-
# # ----------------------------------------------------------------
1035-
# # CDL
1036-
# # ----------------------------------------------------------------
1037-
# if cls.netcdf.is_cdl_file(filename):
1038-
# return "CDL"
1039-
1040-
# Still here?
1041-
raise IOError(f"Can't determine format of file {filename}")

cf/read_write/um/umread.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3379,7 +3379,7 @@ class UMRead(cfdm.read_write.IORead):
33793379
def read(
33803380
self,
33813381
filename,
3382-
um_version=405,
3382+
um_version=None,
33833383
aggregate=True,
33843384
endian=None,
33853385
word_size=None,
@@ -3391,6 +3391,7 @@ def read(
33913391
select=None,
33923392
squeeze=False,
33933393
unsqueeze=False,
3394+
domain=False,
33943395
):
33953396
"""Read fields from a PP file or UM fields file.
33963397
@@ -3484,6 +3485,12 @@ def read(
34843485
>>> f = read('*/file[0-9].pp', um_version=708)
34853486
34863487
"""
3488+
if domain:
3489+
raise ValueError(
3490+
"Can't read Domain constructs from UM or PP datasets "
3491+
"(only Field constructs)"
3492+
)
3493+
34873494
if not _stash2standard_name:
34883495
# --------------------------------------------------------
34893496
# Create the STASH code to standard_name conversion
@@ -3496,6 +3503,14 @@ def read(
34963503
else:
34973504
byte_ordering = None
34983505

3506+
if fmt is not None:
3507+
fmt = fmt.upper()
3508+
3509+
if um_version is None:
3510+
um_version = 405
3511+
else:
3512+
um_version = float(str(um_version).replace(".", "0", 1))
3513+
34993514
self.read_vars = {
35003515
"filename": filename,
35013516
"byte_ordering": byte_ordering,

cf/umread_lib/umfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def _detect_file_type(self):
133133
except Exception:
134134
self.close_fd()
135135
raise IOError(
136-
f"Could not interpret {self.path} as a PP or UM dataset"
136+
f"Can't open file {self.path} as a PP or UM dataset"
137137
)
138138

139139
d = c.file_type_obj_to_dict(file_type_obj)

docs/source/recipes/plot_17_recipe.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@
9191
if i == 0:
9292
set_title = "Perceptually uniform\ncolour maps"
9393
elif i == 1:
94-
set_title = (
95-
"NCL colour maps enhanced to \nhelp with colour blindness"
96-
)
94+
set_title = "NCL colour maps enhanced to \nhelp with colour blindness"
9795
elif i == 2:
9896
set_title = "Orography/bathymetry\ncolour maps"
9997
else:

0 commit comments

Comments
 (0)