1- # (C) British Crown Copyright 2016 - 2017 , Met Office
1+ # (C) British Crown Copyright 2016 - 2018 , Met Office
22#
33# This file is part of Iris.
44#
4040import threading
4141import os .path
4242
43+ import numpy as np
44+
4345# Be minimal about what we import from iris, to avoid circular imports.
4446# Below, other parts of iris.fileformats are accessed via deferred imports.
4547import iris
4648from iris .coords import DimCoord
4749from iris .cube import CubeList
4850from iris .exceptions import TranslationError
49-
51+ from iris .fileformats .um ._fast_load_structured_fields import \
52+ BasicFieldCollation , group_structured_fields
5053
5154# Strings to identify the PP and FF file format handler specs.
5255_FF_SPEC_NAME = 'UM Fieldsfile'
5356_PP_SPEC_NAME = 'UM Post Processing file'
5457
5558
59+ class FieldCollation (BasicFieldCollation ):
60+ # This class specialises the BasicFieldCollation by adding the file-index
61+ # and file-path concepts.
62+ # This preserves the more abstract scope of the original 'FieldCollation'
63+ # class, now renamed 'BasicFieldCollation'.
64+
65+ def __init__ (self , fields , filepath ):
66+ """
67+ Args:
68+
69+ * fields (iterable of :class:`iris.fileformats.pp.PPField`):
70+ The fields in the collation.
71+
72+ * filepath (string):
73+ The path of the file the collation is loaded from.
74+
75+ """
76+ super (FieldCollation , self ).__init__ (fields )
77+ self ._load_filepath = filepath
78+
79+ @property
80+ def data_filepath (self ):
81+ return self ._load_filepath
82+
83+ @property
84+ def data_field_indices (self ):
85+ """
86+ Field indices of the contained PPFields in the input file.
87+
88+ This records the original file location of the individual data fields
89+ contained, within the input datafile.
90+
91+ Returns:
92+ An integer array of shape `self.vector_dims_shape`.
93+
94+ """
95+ # Get shape : N.B. this calculates (and caches) the structure.
96+ vector_dims_shape = self .vector_dims_shape
97+ # Get index-in-file of each contained field.
98+ indices = np .array ([field ._index_in_structured_load_file
99+ for field in self ._fields ],
100+ dtype = np .int64 )
101+ return indices .reshape (vector_dims_shape )
102+
103+
56104def _basic_load_function (filename , pp_filter = None , ** kwargs ):
57105 # The low-level 'fields from filename' loader.
58106 #
@@ -71,8 +119,6 @@ def _basic_load_function(filename, pp_filter=None, **kwargs):
71119 # Therefore, the actual loader will pass this as the 'pp_filter' keyword,
72120 # when it is present.
73121 # Additional load keywords are 'passed on' to the lower-level function.
74- from iris .fileformats .um ._fast_load_structured_fields import \
75- group_structured_fields
76122
77123 # Helper function to select the correct fields loader call.
78124 def _select_raw_fields_loader (fname ):
@@ -98,10 +144,20 @@ def _select_raw_fields_loader(fname):
98144 return loader
99145
100146 loader = _select_raw_fields_loader (filename )
101- fields = iter (field
102- for field in loader (filename , ** kwargs )
103- if pp_filter is None or pp_filter (field ))
104- return group_structured_fields (fields )
147+
148+ def iter_fields_decorated_with_load_indices (fields_iter ):
149+ for i_field , field in enumerate (fields_iter ):
150+ field ._index_in_structured_load_file = i_field
151+ yield field
152+
153+ fields = iter_fields_decorated_with_load_indices (
154+ field
155+ for field in loader (filename , ** kwargs )
156+ if pp_filter is None or pp_filter (field ))
157+
158+ return group_structured_fields (fields ,
159+ collation_class = FieldCollation ,
160+ filepath = filename )
105161
106162
107163# Define the preferred order of candidate dimension coordinates, as used by
@@ -342,7 +398,9 @@ def structured_um_loading():
342398 which is normally the whole of one phenomenon from a single input file.
343399 In particular, the callback's "field" argument is a
344400 :class:`~iris.fileformats.um.FieldCollation`, from which "field.fields"
345- gives a *list* of PPFields from which that cube was built.
401+ gives a *list* of PPFields from which that cube was built, and the
402+ properties "field.load_filepath" and "field.load_file_indices"
403+ reference the original file locations of the cube data.
346404 The code required is therefore different from a 'normal' callback.
347405 For an example of this, see `this example in the Iris test code
348406 <https://github.com/SciTools/iris/
0 commit comments