NCAS-CMS / cf-python

A CF-compliant Earth Science data analysis library
http://ncas-cms.github.io/cf-python
MIT License
119 stars 19 forks source link

Provide numbered view of a `FieldList` #790

Open sadielbartholomew opened 2 months ago

sadielbartholomew commented 2 months ago

A user has requested that we provide a representation of a FieldList that includes numbering of the fields. I can see that this would be really useful, because when you want to pick a specific one out you might well (especially if unaware of our filtering or reduction methods), in the absence of such numbers, count up from the first and/or back from the last to get the give field you want to pick out and particularly when it contains a lot of fields this can involve a lot of counting and possibly inaccuracy.

For instance, imagine you want the field <CF Field: long_name=O3 MASS MIXING RATIO AFTER TIMESTEP(ncdim%obs(13150)) 1> from this:

>>> f
[<CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 <CF Field: altitude(ncdim%obs(155419)) m>,
 <CF Field: altitude(ncdim%obs(155419)) m>,
 <CF Field: altitude(ncdim%obs(155419)) m>,
 <CF Field: latitude(ncdim%obs(155419)) degree_north>,
 <CF Field: latitude(ncdim%obs(13150)) degrees north>,
 <CF Field: latitude(ncdim%obs(155419)) degree_north>,
 <CF Field: latitude(ncdim%obs(155419)) degree_north>,
 <CF Field: longitude(ncdim%obs(155419)) degree_east>,
 <CF Field: longitude(ncdim%obs(13150)) unknown>,
 <CF Field: longitude(ncdim%obs(155419)) degree_east>,
 <CF Field: longitude(ncdim%obs(155419)) degree_east>,
 <CF Field: long_name=O3 MASS MIXING RATIO AFTER TIMESTEP(ncdim%obs(13150)) 1>,
 <CF Field: long_name=O3 MASS MIXING RATIO AFTER TIMESTEP(ncdim%obs(155419)) 1>,
 <CF Field: long_name=O3 MASS MIXING RATIO ON PRESS LEVS(ncdim%obs(155419)) 1>,
 <CF Field: long_name=CO MASS MIX RATIO ON PRESS LEVS(ncdim%obs(155419)) 1>,
 <CF Field: region(ncdim%obs(155419)) 1>,
 <CF Field: region(ncdim%obs(13150)) unknown>,
 <CF Field: region(ncdim%obs(155419)) 1>,
 <CF Field: region(ncdim%obs(155419)) 1>,
 <CF Field: time(ncdim%obs(155419)) days since 1900-01-01 standard>,
 <CF Field: time(ncdim%obs(13150)) days since 1900-01-01 standard>,
 <CF Field: time(ncdim%obs(155419)) days since 1900-01-01 standard>,
 <CF Field: time(ncdim%obs(155419)) days since 1900-01-01 standard>]

I suggest we have the repr as above and have the str representation which includes the numbered view like this or similar:

>>> print(f)
0| [<CF Field: air_pressure(ncdim%obs(155419)) hPa>,
1|  <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
2|  <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
3|  <CF Field: altitude(ncdim%obs(155419)) m>,
...

(Suggesting a line-numbering type view format for the numbering to make it clear it is not a dictionary with index keys.). Or we can include a keyword to str() that can be passed to print(), but I doubt that would get much use unless really well-advertised.

Probably easiest to implement along with #772, which also suggests improvement upon the representation of a FieldList.

sadielbartholomew commented 2 months ago

I've changed my mind about the actual way to show this, now I think something more like this is better, to highlight how to pick out each field, and with the CF FieldList first line to introduce it all:

>>> print(f)
<CF FieldList: 
[f[0]: <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 f[1]: <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 f[2]: <CF Field: air_pressure(ncdim%obs(155419)) hPa>,
 f[3]: <CF Field: altitude(ncdim%obs(155419)) m>,
...
...