Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporating the CFA convention for aggregated datasets into CF #508

Open
davidhassell opened this issue Feb 7, 2024 · 13 comments · May be fixed by #534
Open

Incorporating the CFA convention for aggregated datasets into CF #508

davidhassell opened this issue Feb 7, 2024 · 13 comments · May be fixed by #534
Labels
CF1.12? We might conclude this issue in time for CF1.12 enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format

Comments

@davidhassell
Copy link
Contributor

Incorporating the CFA convention for aggregated datasets into CF

Moderator

To be decided

Moderator Status Review [last updated: 2024-02-07]

  • New issue created on 2024-02-07

Requirement Summary

This is a proposal to incorporate the CFA conventions into CF.

CFA (Climate and Forecast Aggregation) is a convention for recording aggregations of data, without copying their data.

The CFA conventions were discussed at the 2021 and 2023 annual CF workshops, the latter discussion resulting in an agreement to propose their incorporation into CF.

By an “aggregation” we mean a single dataset which has been formed by combining several datasets stored in any number of files. In the CFA convention, an aggregation is recorded by variables with a special function, called “aggregation variables”, in a single netCDF file called an “aggregation file”. The aggregation variables contain no data but instead record instructions on both how to find the data in their original files, and how to combine the data into an aggregated data array. An aggregation variable will almost always take up a negligible amount of disk space compared with the space taken up by the data that belongs to it, because each constituent piece, called a “fragment”, of the aggregated data array is represented solely by file and netCDF variable names and a few indices that describe where its data should be placed relative to the other fragments (see examples 1 and 2).

Example 1: For a timeseries of surface air temperature from 1861 to 2100 that is archived across 24 files, each spanning 10 years, it is useful to view this as if it were a single netCDF dataset spanning 240 years.
CFA_1

CFA has been developed since 2012 and is now a stable and versioned convention that has been fully implemented by cf-python for both aggregation file creation and reading.

Note that this proposal does not cover how to decide whether or not the data arrays of two existing variables could or should be aggregated into a single larger array. That is a software implementation decision. For instance, cf-python has an algorithm for this purpose (We think that the cf-python aggregation rules are complete and consistent because they are entirely based on the CF data model.)

Storing aggregations of existing datasets is useful for data analysis and archive curation. Data analysis benefits from being able to view an aggregation as a single entity and from avoiding the computational expense of creating aggregations on-the-fly; and aggregation files can act as metadata-rich archive indices that consume a very small amount of disk space.

The CFA conventions only affect the representation of a variable’s data, and thus they work alongside all CF metadata, i.e. the CFA conventions do not duplicate, extend, nor re-define any of the metadata elements defined by the CF conventions.

An aggregation file may, and often will, contain both aggregation variables and normal CF-netCDF variables i.e. those with data arrays. All kinds of CF-netCDF variables (e.g. data variables, coordinate variables, cell measures) can be aggregated using the CFA conventions. For instance an aggregated data variable (whose actual data are in other files) may have normal CF-netCDF coordinate variables (whose data are in the aggregation file).

Another approach to file aggregation without copying data is NcML Aggregation, which has been extensively used. CFA is similar in intent to NcML but is more general and efficient, because it

  • keeps the CF metadata in the same place as the aggregation instructions;
  • allows aggregations over any number of dimensions in any array positions;
  • places no restrictions on netCDF elements that are not standardised by CF (such as variable names);
  • uses the binary netCDF format to speed up read times for large aggregations.

Technical Proposal Summary

The CFA conventions currently have their own document (https://github.com/NCAS-CMS/cfa-conventions/blob/main/source/cfa.md) which describes in detail how to create and interpret an "aggregation variable", i.e. a netCDF variable that does not contain a data array but instead has attributes that contain instructions on how to assemble the data array as an aggregation of data from other sources.

A Pull Request to incorporate CFA into CF has not been created yet. Before starting any work on translating the content of the CFA document into the CF conventions document, it is important to get the community’s consensus that this is a good idea, and about how the new content should be structured (e.g. a new section, a new appendix, both, or something else).

The main features of CFA are summarised in example 2, a CDL view of an aggregation of two 6-month datasets into a single 12-month variable (see the CFA document for details).

Example 2: An aggregation data variable whose aggregated data comprises two fragments. Each fragment spans half of the aggregated time dimension and the whole of the other three aggregated dimensions, and is stored in an external netCDF file in a variable called temp. The fragment URIs define the file locations. Both fragment files have the same format, so the format variable can be stored as a scalar variable.
CFA_diagram_CF

Benefits

Aggregations persisted to disk allow users and software libraries to access pre-created aggregations with no complicated and time-consuming processing.

Status Quo

Not being able to persist fully generalised aggregations to disk means that every user/software library has to be able to create their own aggregations every time the data files are accessed. This is a complicated and time-consuming task.

Associated pull request

None yet (see above).

CFA authors

CFA has been developed by David Hassell, Jonathan Gregory, Neil Massey, Bryan Lawrence, and Sadie Bartholomew.

Contributors to CFA discussions at the CF workshops

Chris Barker, Ethan Davies, Roland Schweitzer, Karl Taylor, Charlie Zender, and Klaus Zimmermann (please let us know if we have accidentally missed you off this list).

@davidhassell davidhassell added the enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format label Feb 7, 2024
@larsbarring
Copy link
Contributor

David,
This will be an excellent and very useful addition to the CF Conventions! I have not yet wrapped my head around the technical details. There is one thing I do not quite understand, first you write:

The aggregation variables contain no data but instead record instructions on both how to find the data in their original files, and how to combine the data into an aggregated data array

And below the Figure 1 you write:

Note that this proposal does not cover how to decide whether or not the data arrays of two existing variables could or should be aggregated into a single larger array.

Probably I am missing something here, but to me this seems contradictory? Anyway, that is a detail, and I think the more important questions are the one you raise in the Technical Proposal Summary:

... incorporate CFA into CF ... that this is a good idea, ...

To me this is no doubt a good idea, which already has a strong community backing.

... how the new content should be structured (e.g. a new section, a new appendix, both, or something else).

Perhaps an outline somewhere in the main text: end of Chapter 2 regarding aggregation files and their relation to the fragment files, somewhere in Chapter 3 regarding aggregation variables? And then an exhaustive description in an Appendix?

This, brings me a more general thought that I have been thinking about for some time:
I think that the CF Conventions document is getting increasingly long and complex/difficult to get an overview of. The Table of Content takes 8 full screens (5 pdf pages), then 5 screens of Tables of tables/figures/examples (3 pdf pages). I have no idea how to improve upon this, but it becomes more and more of a concern as we add new features to the Conventions. However, this is not something to discuss and solve here in this enhancement proposal, but I wanted to bring it up here anywaay.

@davidhassell
Copy link
Contributor Author

davidhassell commented Apr 9, 2024

Thank you for you comments, Lars, and sorry that it has taken me some time to respond.

Even though you are the only person to have commented here (and in support), this proposal has been scrutinised carefully at two CF workshops, with a group decision being reached in 2023 to work towards incorporating CFA into CF. I'm therefore minded to move to writing the PR, now that Lars has made a good suggestion of how and where the content could go into the existing CF conventions. This shouldn't take too long, because it will largely be a "cut and paste" job from the existing CFA description, which was deliberately written in a CF-ish style in anticipation of this :).

The aggregation variables contain no data but instead record instructions on both how to find the data in their original files, and how to combine the data into an aggregated data array
...
Note that this proposal does not cover how to decide whether or not the data arrays of two existing variables could or should be aggregated into a single larger array.

Good point. The first statement applies to the reading of the data, and the second to the writing of the data. The CFA conventions do not give any guidance on the decision of how fragment files can be combined prior to creating an aggregation variable, rather once you have an aggregation in mind, they provide a framework in which you can encode it in such a way that other people can decode it.

If I give you two datasets (A and B) then the CFA conventions won't give you any help in working out if A and B can be sensibly combined into a single larger dataset (C). There are various ways in which you could work this out yourself - you could inspect the metadata and apply an aggregation algorithm (e.g. this one, or by visual inspection), or base it on files names (e.g. I know that model outputs from March.nc and April.nc are safe to combine into a 2-month dataset), etc.

Perhaps an outline somewhere in the main text: end of Chapter 2 regarding aggregation files and their relation to the fragment files, somewhere in Chapter 3 regarding aggregation variables? And then an exhaustive description in an Appendix?

I like the idea of a Chapter 2 outline. I might suggest content from Introduction, Terminology, Aggregation variables, and Aggregation instructions (without its subsections) for Chapter 2, and everything else - which is most of the existing CFA document - (Standardized aggregation instructions, Non-standardized terms, Fragment Storage and examples) for the appendix.

The Table of Content takes 8 full screens (5 pdf pages), then 5 screens of Tables of tables/figures/examples (3 pdf pages).

Just a thought - the TOC currently shows all subnsections - maybe it could be restricted to just one level of subsection, so for instance Chapter 7 would go from

[7. Data Representative of Cells](https://cfconventions.org/cf-conventions/cf-conventions.html#_data_representative_of_cells)
    [7.1. Cell Boundaries](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-boundaries)
    [7.2. Cell Measures](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-measures)
    [7.3. Cell Methods](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-methods)
        [7.3.1. Statistics for more than one axis](https://cfconventions.org/cf-conventions/cf-conventions.html#statistics-more-than-one-axis)
        [7.3.2. Recording the spacing of the original data and other information](https://cfconventions.org/cf-conventions/cf-conventions.html#recording-spacing-original-data)
        [7.3.3. Statistics applying to portions of cells](https://cfconventions.org/cf-conventions/cf-conventions.html#statistics-applying-portions)
        [7.3.4. Cell methods when there are no coordinates](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-methods-no-coordinates)
    [7.4. Climatological Statistics](https://cfconventions.org/cf-conventions/cf-conventions.html#climatological-statistics)
    [7.5. Geometries](https://cfconventions.org/cf-conventions/cf-conventions.html#geometries)

to

[7. Data Representative of Cells](https://cfconventions.org/cf-conventions/cf-conventions.html#_data_representative_of_cells)
    [7.1. Cell Boundaries](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-boundaries)
    [7.2. Cell Measures](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-measures)
    [7.3. Cell Methods](https://cfconventions.org/cf-conventions/cf-conventions.html#cell-methods)
    [7.4. Climatological Statistics](https://cfconventions.org/cf-conventions/cf-conventions.html#climatological-statistics)
    [7.5. Geometries](https://cfconventions.org/cf-conventions/cf-conventions.html#geometries)

That alone would remove 71 lines from the TOC! But as you say, any more on that should be discussed elsewhere, which I would welcome.

@taylor13
Copy link

taylor13 commented Apr 9, 2024

I think this is generally a good idea and have been meaning to go over the details.

A quick thought about the table of contents: Would it be easy in the web view to collapse the subsection hierarchy to 1 or 2 levels, then click on an upper level to display its subsections? That might give a newbie a more accessible overview. On the other hand, I usually just execute "find" for some key word I know is relevant to what I want to look up, and if that word becomes hidden (in a hidden low level subsection), then I may have a harder time navigating quickly to the relevant section. So I can see arguments for the current expanded table of contents.

@davidhassell
Copy link
Contributor Author

Hello,

We have finally prepared a pull request for incorporating aggregation into the CF conventions: #534

It touches on 9 files:

Chapter 1: Terminology
Chapter 2: Full description of aggregation variables
Appendix A: new aggregation attributes
Appendix L: Aggregation examples
Conformance: Requirements and recommendations
History: History
Bibliography: New URI reference
toc-extra: New examples
conventions: New authors

All the best,
David

@davidhassell davidhassell linked a pull request Aug 13, 2024 that will close this issue
4 tasks
@davidhassell
Copy link
Contributor Author

Hello,

I fully appreciate that this is a large pull request, but it would be very nice if someone who wasn't involved in its development could look it over. The PR already has the support of the original CFA authors (@JonathanGregory, @bnlawrence, @nmassey001, @sadielbartholomew and myself), but at least one "outside" perspective is necessary, I think. It would be great if this could get into CF-1.12, which means in practice that it would have to all agreed by (roughly) the end of October.

Any takers? We'd be much obliged :)

Many thanks,
David

@taylor13
Copy link

taylor13 commented Oct 16, 2024

H all,

I have now studied the proposal as given above and also read the CFA conventions documentation. What's the easiest way to review the pull request? When I look at the changes made to files, I can see the new text, but it isn't particularly easy to read. [I know I should know how to do this by now.]. NOTE ADDED AFTER THE FACT: I HAVE NOW BEGUN TO READ THE ACTUAL PULL REQUEST, WHICH DIFFERS SUBSTANTIALLY FROM THE PROPOSAL ABOVE, SO MOST OF THE FOLLOWING COMMENTS MAY BE IRRELEVANT. I'LL PROVIDE FEEDBACK ON THE ACTUAL PULL REQUEST IN THE NEXT DAY OR TWO.

Anyway, based on what I've read, I have a few comments and questions:

  1. This proposal provides a really useful enhancement of CF, and it seems to be very mature and tested in practice, so I strongly support it.
  2. It appears that some of the features in the CFA conventions document haven't made it into CF (but I might be wrong about that). For example, the option to specify units of a variable in the aggregation file that are a different from (but compatible with) the units in the fragment files seems like a nice feature. Is that included in this CF proposal?
  3. It's not clear to me how the "substitution" option helps us much. Is it assumed that each time you move the location of your fragment files, you would update the aggregation file (using this feature) to fix broken links that might be introduced?
  4. What value is represented by "_" in a ncdump listing? Is that an undefined value? If I'm writing data, and want to define aggregation_location=[6, 6, 73, _, 144, _], how do I assign the 4th and 6th element of the array?
  5. You use the term "address" and describe it as the "addresses of data in fragment files". Then you indicate the aggregation_address is "tos1", "tos2". Are "tos1" and "tos2" the names of variables containing the fragments being aggregated into a variable named "temp"? If so, could "address" be replaced with "name"?
  6. The aggregated_data attribute defines the names of the "location", "file", "format", and "address". I would find these 4 terms more aptly named "shapes", "files", "formats", and "names".
  7. In the example(s), I think I would find it less confusing if you came up with different variable names for the "location", "file", "format", and "address". I think I'd replace:
  • "aggregation_location" with "fragment_shapes"
  • "aggregation_file" with "fragment_files"
  • "aggregation_format" with "fragment_file_formats"
  • "aggregation_address" with "fragment_variable_names"

I understand that the data writer can name these however (s)he likes, but for the CF documentation, I think the above would be easier for users to understand (unless, of course, I've completely misrepresented what they are).

@davidhassell
Copy link
Contributor Author

Thanks, Karl - I very much appreciate your comments. I've seen your edit about reading the latest, and will hold off responding to everything until you have done so.

However, it could be useful to mention some of your comments now, and with reference to the PR text:

  1. It appears that some of the features in the CFA conventions document haven't made it into CF (but I might be wrong about that). For example, the option to specify units of a variable in the aggregation file that are a different from (but compatible with) the units in the fragment files seems like a nice feature. Is that included in this CF proposal?

I has indeed. In section 2.8.2 Fragment Interpretation it says that converting the fragment to its canonical form may involve "Transforming the fragment's data to have the aggregation variable's units (e.g. as required when aggregating time fragments whose units have different reference date/times)."

  1. It's not clear to me how the "substitution" option helps us much. Is it assumed that each time you move the location of your fragment files, you would update the aggregation file (using this feature) to fix broken links that might be introduced?

That's right - it's a convenience feature. Instead of having to update the file paths of 1 million fragment file names when teh files are moved, if the file names have been defined with a substitution (cf. environment variable) then you just have to update that one attribute to set the new location for the 1 million files. The new text in section 2.8.1 Aggregated Dimensions and Data aims to clarify this: "The use of substitutions can save space in the aggregation file; and in the event that the fragment locations need to be updated after the aggregation file has been created, it may be possible to achieve this by modifying the substitutions attribute rather than by changing the actual location fragment array variable values."

  1. What value is represented by "_" in a ncdump listing? Is that an undefined value? If I'm writing data, and want to define aggregation_location=[6, 6, 73, _, 144, _], how do I assign the 4th and 6th element of the array?

_ in CDL Is a placeholder for a missing or fill value. The "shape variable" definition in section 2.8.1 Aggregated Dimensions and Data hopefully describes that this value can only have_trailing_ missing values which account for the different number of fragments that span different dimensions.

  1. You use the term "address" and describe it as the "addresses of data in fragment files". Then you indicate the aggregation_address is "tos1", "tos2". Are "tos1" and "tos2" the names of variables containing the fragments being aggregated into a variable named "temp"? If so, could "address" be replaced with "name"?

If the intention were to only ever aggregation netCDF fragments, I may agree, but we'd like the conventions to allow the aggregation of non-CF datasets (2.8. Aggregation Variables: "Fragment datasets may be CF-compliant or have any other format, thereby allowing an aggregation variable to act as a CF-compliant view of non-CF datasets"). Not all datasets use a nice name to identify a variable in their contents (could be an integer file position, as is the case for Met Office PP format files, which at NCAS we are using as fragment files), so we landed on the term "address". Nothing particularly special about this term, though, so happy to consider any other.

@taylor13
Copy link

Hi David and all,

[My input below is, I hope, constructive, because I think that adoption of a CF-compliant approach to creating aggregated datasets will be very useful. Thanks for all your work on this. It's likely that something quite obvious has eluded me, in which case, please excuse by ignorance, but perhaps you could provide further explanation (or examples) that might enlighten me.]

I've spent some time studying the proposed pull request changes to the conventions document. I spent most of my time trying to figure out exactly how to interpret the fragment_shape array and thinking about how I might form an aggregated array from the fragment arrays, based on the (array size?) numbers it gives. I failed. Then, I thought about what alternative options there might be for providing mapping information in a concise form, which codes could use to combine fragments into a single aggregate. In the pdf file attached below, I've suggested an alternative to the pull request proposal and highlighted it in yellow. I think my approach is easier to explain to users and would facilitate the construction of aggregated variables. (It has similarities with conventional "pointer" approaches to accessing array data.) I know code has already been written based on the original proposal, so perhaps my alternative will not be popular. More likely, those of you who spent so much time coming up with the "fragment_shape" approach of describing how the fragments fit together will find an obvious problem with my suggestion. If so, perhaps all that is needed is a better explanation of your method.

In particular, as a first step, I would be interested in someone telling me what the "fragment_shape" is for the example I came up with. (See the few lines of red-highlighted text below the colorful graphic on the attached.) Perhaps that will enable me to finally "get" how this shape information can be used.

The following document contains a suggestion on how the approach might be modified and made simpler to explain to new users. Most of the "edit suggestions" contained in the file are unrelated to the new approach.
cf-conventions_aggregation_PR_KET.pdf

Thanks again for all the thought and work that has already gone into this.
Karl

@taylor13
Copy link

Just wanted to ask about a use case:

Suppose I want to aggregate a surface temperature field provided by multiple models, all on a common grid. There is no "model axis" in the files. Can I combine the fields defining a "model label" coordinate?

@JonathanGregory JonathanGregory added the CF1.12? We might conclude this issue in time for CF1.12 label Oct 20, 2024
@davidhassell
Copy link
Contributor Author

Karl asked:

Suppose I want to aggregate a surface temperature field provided by multiple models, all on a common grid. There is no "model axis" in the files. Can I combine the fields defining a "model label" coordinate?

Yes, provided that all of the models are on the same domain, of course. Here is a modification of the new Example L.1, with an extra "model" axis included:

dimensions:
  model = 4 ;               // New model axis
  time = 12 ;
  level = 1 ;
  latitude = 73 ;
  longitude = 144 ;
  // Fragment array dimensions
  f_model = 4 ;
  f_time = 1 ;
  f_level = 1 ;
  f_latitude = 1 ;
  f_longitude = 1 ;
  // Fragment shape dimensions
  j = 5 ;         // Equal to the number of aggregated dimensions
  i = 4 ;         // Equal to the size of the largest fragment array dimension
variables:
  // Aggregation data variable
  double temperature ;
    temperature:standard_name = "air_temperature" ;
    temperature:units = "K" ;
    temperature:cell_methods = "time: mean" ;
    temperature:coordinates = "model_label" ;
    temperature:aggregated_dimensions = "model time level latitude longitude" ;
    temperature:aggregated_data = "location: fragment_location
                                   address: fragment_address
                                   shape: fragment_shape" ;
  // Coordinate variables
  double time(time) ;
    time:standard_name = "time" ;
    time:units = "days since 2001-01-01" ;
  double level(level) ;
    level:standard_name = "height_above_mean_sea_level" ;
    level:units = "m" ;
  double latitude(latitude) ;
    latitude:standard_name = "latitude" ;
    latitude:units = "degrees_north" ;
  double longitude(longitude) ;
    longitude:standard_name = "longitude" ;
    longitude:units = "degrees_east" ;
  str model_label(model) ;               // New model label auxiliary coordinate
    model_name:long_name = "Name of model" ;
  // Fragment array variables
  string fragment_location(f_model, f_time, f_level, f_latitude, f_longitude) ;
  string fragment_address ;
  int fragment_shape(j, i) ;
data:
  temperature = _ ;
  time = 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ;
  level = ... ;
  latitude = ... ;
  longitude = ... ;
  model_name = "model1", "model1", "model3", "model4" ;
  fragment_location = "model1.nc", "model2.nc, "model3.nc", "model4.nc" ;
  fragment_address = "temperature" ;
  fragment_shape = 1, 1, 1, 1,
                   12, _, _, _, 
                   1, _, _, _, 
                   73, _, _, _, 
                   144, _, _, _ ;

We could include this example in the appendix.

@davidhassell
Copy link
Contributor Author

Hi Karl,

Just quickly jumping on your suggested structural change, before getting into your text suggestions and questions ... I'm intrigued by your new fragment_shape variable. I've always been annoyed that we have to pad it out with missing data, thereby wasting space (and making it more complicated to explain!).

I can't see any problems with your new approach by just thinking about it :) (I'd like to run it past my software implementation to be sure). I'm wondering if the super-general figure on page 12 of conventions_aggregation_PR_KET.pdf should be be restricted to the cases allowed by the current "fragment array" - i.e. where the all of the fragments are aligned in neat hyper-rows. This is because a) I doubt there's a use case for non-aligned fragments; b) I very much doubt that there's any software out there that can handle the fully general case whilst also applying "lazy loading" of the data, and we shouldn't encourage people to tackle this very thorny problem without need; and c) full generality could easily be allowed if a use case ever arose.

What does anyone else think?

@taylor13
Copy link

taylor13 commented Oct 22, 2024

Hi David,

That is very encouraging. I must admit I was unable to understand how your fragment_shape information got utilized. I didn't realize that the constraint was imposed that "all of the fragments are aligned in neat hyper-rows." (I'm not sure I still understand what that means exactly, but for now, that's o.k.)

There is an important constraint even for my "super-general" example: All fragments must be logically rectangular (in hyperspace), and together they must fill a logically-rectangular aggregated array. One can think of each fragment as a block and the blocks together are used to build a single aggregated block (without leaving any spaces).

I agree we could be more restrictive (for reasons you've listed above) if that really makes a difference to those writing code. Thinking in terms of fortran-style coding (which is my default thought process), I don't think it would be difficult to handle the general case, but then I'm not familiar with what you say is "lazy loading" of the data. Is that loading the data into a vector not preserving the multi-dimensional structure?

In any case, I think the primary advantage offered by the alternative approach is that it seems to me to be easier to explain. Let's see what others think.

A note on the examples and notation: New users might better follow what we're doing if we change the keyword (under aggregated_data) from "shape" to "map" since the values tell you how to map your fragments into the aggregated array. In the example, I named the "shape" variable "fragment_starts", but a better variable name might be "insert_at", since the fragment arrays get inserted in the aggregated array at the index values provided by the "insert_at" variable.

@taylor13
Copy link

While I'm thinking about it, the term "address" doesn't immediately bring to mind the name of a variable, but rather a location of the variable; would "identifier" be a better term? It doesn't specifically have to be a variable name, but could be, as you noted earlier, an integer or some other kind of identifier of the variable of interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CF1.12? We might conclude this issue in time for CF1.12 enhancement Proposals to add new capabilities, improve existing ones in the conventions, improve style or format
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants