@@ -601,6 +601,23 @@ def __new__(
601
601
602
602
aggregate_options ["copy" ] = False
603
603
604
+ # ------------------------------------------------------------
605
+ # Parse the 'fmt' keyword parameter
606
+ # ------------------------------------------------------------
607
+ if fmt :
608
+ if isinstance (fmt , str ):
609
+ fmt = (fmt ,)
610
+
611
+ fmt = set (fmt )
612
+ else :
613
+ fmt = set (("netCDF" , "CDL" , "UM" ))
614
+
615
+ # ------------------------------------------------------------
616
+ # Parse the 'um' keyword parameter
617
+ # ------------------------------------------------------------
618
+ if not um :
619
+ um = {}
620
+
604
621
# Count the number of fields (in all files) and the number of
605
622
# files
606
623
field_counter = - 1
@@ -646,49 +663,97 @@ def __new__(
646
663
647
664
files2 = files3
648
665
666
+ # How each file was read, as netCDF, or UM, etc.
667
+ ftypes = set ()
668
+
649
669
for filename in files2 :
650
670
if info :
651
671
logger .info (f"File: { filename } " ) # pragma: no cover
652
672
653
- # --------------------------------------------------------
673
+ # ----------------------------------------------------
654
674
# Read the file
655
- # --------------------------------------------------------
656
- ftypes = [None ]
657
- file_contents = cls ._read_a_file (
658
- filename ,
659
- ftypes = ftypes ,
660
- external = external ,
661
- ignore_read_error = ignore_read_error ,
662
- verbose = verbose ,
663
- warnings = warnings ,
664
- aggregate = aggregate ,
665
- aggregate_options = aggregate_options ,
666
- fmt = fmt ,
667
- um = um ,
668
- extra = extra ,
669
- height_at_top_of_model = height_at_top_of_model ,
670
- dask_chunks = dask_chunks ,
671
- store_hdf5_chunks = store_hdf5_chunks ,
672
- mask = mask ,
673
- unpack = unpack ,
674
- warn_valid = warn_valid ,
675
- select = select ,
676
- domain = domain ,
677
- cfa = cfa ,
678
- cfa_write = cfa_write ,
679
- to_memory = to_memory ,
680
- netcdf_backend = netcdf_backend ,
681
- storage_options = storage_options ,
682
- cache = cache ,
683
- squeeze = squeeze ,
684
- unsqueeze = unsqueeze ,
685
- )
675
+ # ----------------------------------------------------
676
+ fmts = fmt .copy ()
677
+ file_format_errors = []
678
+
679
+ if fmts .intersection (("netCDF" , "CDL" )):
680
+ try :
681
+ file_contents = super ().__new__ (
682
+ cls ,
683
+ filename ,
684
+ external = external ,
685
+ extra = extra ,
686
+ verbose = verbose ,
687
+ warnings = warnings ,
688
+ mask = mask ,
689
+ unpack = unpack ,
690
+ warn_valid = warn_valid ,
691
+ domain = domain ,
692
+ storage_options = storage_options ,
693
+ netcdf_backend = netcdf_backend ,
694
+ dask_chunks = dask_chunks ,
695
+ store_hdf5_chunks = store_hdf5_chunks ,
696
+ cache = cache ,
697
+ cfa = cfa ,
698
+ cfa_write = cfa_write ,
699
+ to_memory = to_memory ,
700
+ squeeze = squeeze ,
701
+ unsqueeze = unsqueeze ,
702
+ fmt = fmt ,
703
+ ignore_unknown_format = ignore_read_error ,
704
+ )
705
+ except UnknownFileFormatError as error :
706
+ fmts .difference_update (("netCDF" , "CDL" ))
707
+ file_format_errors .append (error )
708
+ else :
709
+ file_format_errors = ()
710
+ if file_contents or not ignore_read_error :
711
+ # Zero or more fields/domains were
712
+ # successfully read
713
+ fmts = set ()
714
+ ftype = "netCDF"
715
+
716
+ if fmts .intersection (("UM" ,)):
717
+ try :
718
+ file_contents = cls .um .read (
719
+ filename ,
720
+ um_version = um .get ("version" ),
721
+ verbose = verbose ,
722
+ set_standard_name = False ,
723
+ height_at_top_of_model = height_at_top_of_model ,
724
+ fmt = um .get ("fmt" ),
725
+ word_size = um .get ("word_size" ),
726
+ endian = um .get ("endian" ),
727
+ select = select ,
728
+ squeeze = squeeze ,
729
+ unsqueeze = unsqueeze ,
730
+ domain = domain ,
731
+ )
732
+ except UnknownFileFormatError as error :
733
+ fmts .difference_update (("UM" ,))
734
+ file_format_errors .append (error )
735
+ else :
736
+ file_format_errors = ()
737
+ if file_contents or not ignore_read_error :
738
+ fmts = set ()
739
+ ftype = "UM"
740
+
741
+ if file_format_errors :
742
+ error = "\n " .join (map (str , file_format_errors ))
743
+ raise UnknownFileFormatError (f"\n { error } " )
744
+
745
+ if domain :
746
+ file_contents = DomainList (file_contents )
747
+
748
+ file_contents = FieldList (file_contents )
749
+
750
+ ftypes .add (ftype )
686
751
687
752
# --------------------------------------------------------
688
753
# Select matching fields (only from netCDF files at
689
754
# this stage - we'll do UM fields later)
690
755
# --------------------------------------------------------
691
- if select and ftypes [ - 1 ] == "netCDF" :
756
+ if select and ftype == "netCDF" :
692
757
file_contents = file_contents .select_by_identity (* select )
693
758
694
759
# --------------------------------------------------------
@@ -712,6 +777,11 @@ def __new__(
712
777
if aggregate and len (out ) > 1 :
713
778
org_len = len (out ) # pragma: no cover
714
779
780
+ if "UM" in ftypes :
781
+ # Set defaults specific to UM fields
782
+ if "strict_units" not in aggregate_options :
783
+ aggregate_options ["relaxed_units" ] = True
784
+
715
785
out = cf_aggregate (out , ** aggregate_options )
716
786
717
787
n = len (out ) # pragma: no cover
@@ -756,200 +826,3 @@ def __new__(
756
826
def _plural (n ): # pragma: no cover
757
827
"""Return a suffix which reflects a word's plural."""
758
828
return "s" if n != 1 else "" # pragma: no cover
759
-
760
- @classmethod
761
- @_manage_log_level_via_verbosity
762
- def _read_a_file (
763
- cls ,
764
- filename ,
765
- ftypes = None ,
766
- aggregate = True ,
767
- aggregate_options = None ,
768
- ignore_read_error = False ,
769
- verbose = None ,
770
- warnings = False ,
771
- external = None ,
772
- fmt = None ,
773
- um = None ,
774
- extra = None ,
775
- height_at_top_of_model = None ,
776
- mask = True ,
777
- unpack = True ,
778
- warn_valid = False ,
779
- dask_chunks = "storage-aligned" ,
780
- store_hdf5_chunks = True ,
781
- select = None ,
782
- domain = False ,
783
- cfa = None ,
784
- cfa_write = None ,
785
- to_memory = None ,
786
- netcdf_backend = None ,
787
- storage_options = None ,
788
- cache = True ,
789
- squeeze = False ,
790
- unsqueeze = False ,
791
- ):
792
- """Read the contents of a single file into a field list.
793
-
794
- :Parameters:
795
-
796
- filename: `str`
797
- See `cf.read` for details.
798
-
799
- ftypes: `str` TODOCFA
800
- The file format to interpret the file. Recognised formats are
801
- ``'netCDF'``, ``'CDL'``, ``'UM'`` and ``'PP'``.
802
-
803
- aggregate_options: `dict`, optional
804
- See `cf.read` for details.
805
-
806
- ignore_read_error: `bool`, optional
807
- See `cf.read` for details.
808
-
809
- mask: `bool`, optional
810
- See `cf.read` for details.
811
-
812
- unpack: `bool`, optional
813
- See `cf.read` for details.
814
-
815
- verbose: `int` or `str` or `None`, optional
816
- See `cf.read` for details.
817
-
818
- select: optional
819
- For `read. Ignored for a netCDF file.
820
-
821
- domain: `bool`, optional
822
- See `cf.read` for details.
823
-
824
- cfa: `dict`, optional
825
- See `cf.read` for details.
826
-
827
- .. versionadded:: 3.15.0
828
-
829
- storage_options: `dict` or `None`, optional
830
- See `cf.read` for details.
831
-
832
- .. versionadded:: NEXTVERSION
833
-
834
- netcdf_backend: `str` or `None`, optional
835
- See `cf.read` for details.
836
-
837
- .. versionadded:: NEXTVERSION
838
-
839
- cache: `bool`, optional
840
- See `cf.read` for details.
841
-
842
- .. versionadded:: NEXTVERSION
843
-
844
- squeeze: `bool`, optional
845
- Whether or not to remove all size 1 axes from field
846
- construct data arrays. See `cf.read` for details.
847
-
848
- .. versionadded:: NEXTVERSION
849
-
850
- unsqueeze: `bool`, optional
851
- Whether or not to ensure that all size 1 axes are
852
- spanned by field construct data arrays. See
853
- `cf.read` for details.
854
-
855
- .. versionadded:: NEXTVERSION
856
-
857
- :Returns:
858
-
859
- `FieldList` or `DomainList`
860
- The field or domain constructs in the dataset.
861
-
862
- """
863
- if fmt :
864
- if isinstance (fmt , str ):
865
- fmt = (fmt ,)
866
-
867
- fmt = set (fmt )
868
- else :
869
- fmt = set (("netCDF" , "CDL" , "UM" ))
870
-
871
- file_format_errors = []
872
-
873
- out = None
874
- if fmt .intersection (("netCDF" , "CDL" )):
875
- try :
876
- out = super ().__new__ (
877
- cls ,
878
- filename ,
879
- external = external ,
880
- extra = extra ,
881
- verbose = verbose ,
882
- warnings = warnings ,
883
- mask = mask ,
884
- unpack = unpack ,
885
- warn_valid = warn_valid ,
886
- domain = domain ,
887
- storage_options = storage_options ,
888
- netcdf_backend = netcdf_backend ,
889
- dask_chunks = dask_chunks ,
890
- store_hdf5_chunks = store_hdf5_chunks ,
891
- cache = cache ,
892
- cfa = cfa ,
893
- cfa_write = cfa_write ,
894
- to_memory = to_memory ,
895
- squeeze = squeeze ,
896
- unsqueeze = unsqueeze ,
897
- fmt = fmt ,
898
- ignore_unknown_format = ignore_read_error ,
899
- )
900
- except UnknownFileFormatError as error :
901
- fmt .difference_update (("netCDF" , "CDL" ))
902
- if fmt :
903
- file_format_errors .append (error )
904
- else :
905
- raise
906
- else :
907
- if out or not ignore_read_error :
908
- # Zero or more fields/domains were successfully read
909
- fmt = set ()
910
- file_format_errors = ()
911
- ftypes .append ("netCDF" )
912
-
913
- if fmt .intersection (("UM" ,)):
914
- if not um :
915
- um = {}
916
-
917
- try :
918
- out = cls .um .read (
919
- filename ,
920
- um_version = um .get ("version" ),
921
- verbose = verbose ,
922
- set_standard_name = False ,
923
- height_at_top_of_model = height_at_top_of_model ,
924
- fmt = um .get ("fmt" ),
925
- word_size = um .get ("word_size" ),
926
- endian = um .get ("endian" ),
927
- select = select ,
928
- squeeze = squeeze ,
929
- unsqueeze = unsqueeze ,
930
- domain = domain ,
931
- )
932
- except UnknownFileFormatError as error :
933
- fmt .difference_update (("UM" ,))
934
- file_format_errors .append (error )
935
- else :
936
- if out or not ignore_read_error :
937
- file_format_errors = ()
938
- ftypes .append ("UM" )
939
-
940
- # UM fields are aggregated intrafile prior to
941
- # interfile aggregation
942
- if aggregate :
943
- # Set defaults specific to UM fields
944
- if "strict_units" not in aggregate_options :
945
- aggregate_options ["relaxed_units" ] = True
946
-
947
- if file_format_errors :
948
- file_format_errors = "\n " .join (map (str , file_format_errors ))
949
- raise UnknownFileFormatError (f"\n { file_format_errors } " )
950
-
951
- # Return the fields/domains
952
- if domain :
953
- return DomainList (out )
954
-
955
- return FieldList (out )
0 commit comments