Skip to content

Support for single string attributes in read#453

Merged
WardF merged 1 commit intoUnidata:mainfrom
graziano-giuliani:main
Sep 9, 2025
Merged

Support for single string attributes in read#453
WardF merged 1 commit intoUnidata:mainfrom
graziano-giuliani:main

Conversation

@graziano-giuliani
Copy link
Copy Markdown
Contributor

Partial modification to allow netCDF Fortran library able to read single string attributes from a netCDF4 CF-1.9 compliant using string type for attributes.
It overloads the nf90_get_att_text function returning a single string attribute (note the nlen == 1 in the patch) as if it is a character attributes.
What is not implemented are multidimensional strings, and the capability to write string attributes, because of the lack of string type in Fortran standard. This patch would allow reading netCDF files like the one created from the Copernicus cds-beta site for ECMWF ERA5 model. See reference to this in issue #181 "string attributes are not supported yet?"

…gle string attributes from a netCDF4 CF-1.9 compliant using string type for attributes. It overloads the nf90_get_att_text function returning single string (note nlen == 1) as if they are character attributes. What is not implemented are multidimensional strings, and the capability to write string attributes, because of the lack of string type in Fortran standard. This patch would allow reading netCDF files like the one created from the Copernicus cds-beta site for ECMWF ERA5 model. See reference to this in issue Unidata#181 "string attributes are not supported yet?"
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Oct 17, 2024

CLA assistant check
All committers have signed the CLA.

@WardF
Copy link
Copy Markdown
Member

WardF commented Oct 23, 2024

Thank you!

@edwardhartnett
Copy link
Copy Markdown
Contributor

Can you add a test or two as well?

@WardF WardF self-assigned this Oct 28, 2024
@WardF
Copy link
Copy Markdown
Member

WardF commented Nov 13, 2024

@graziano-giuliani Is there any chance you could help us by adding a test for this as well?

@WardF
Copy link
Copy Markdown
Member

WardF commented Jan 23, 2025

I'll see if I can add a test for this.

@gmao-cda
Copy link
Copy Markdown
Contributor

@WardF May I ask if there is a test for this new implementation? If not, can I contribute one?
I have encountered the same issue and I directly called netcdf-c lib from Fortran to overpass it (cd10kfsu/F90GIO#12 (comment)), and I have an existing file for testing.
It would be great that netcdf-fortran can do it directly as implemented in this PR.

File list:

  • example.cdl: CDL to create the test data
  • example.nc: test data generated by using ncgen -o example.nc example.cdl

The CDL example.cdl is

netcdf example {

  dimensions:
      Location = UNLIMITED ; // (0 currently)

  // global attributes:
      string :author = "fake_author" ;
      :agency = "fake_agency" ;

  group: MetaData {
    variables:
        float latitude(Location) ;
            string latitude:units = "degrees_north" ;
  }

  group: yobs {
    variables:
        float sst(Location) ;
            string sst:units = "C" ;
  }

  group: Hx {
    variables:
        float sst(Location) ;
            sst:units = "C" ;
  }
}

Essentially it creates NC_STRING and NC_CHAR attributes for global, and variables under different groups , so that the new build from this PR can be tested to see if these attributes are correctly read in.

I can try to build the NetCDF-Fortran lib from this PR, and write a code using this lib to check if updated nf90_get_att_text can read the attributes correctly.

@WardF
Copy link
Copy Markdown
Member

WardF commented Aug 21, 2025

Hello @gmao-cda; contributing a test would be greatly appreciated, as it would help us keep our CI up to date. I have had this on the back burner as something to do for a while, clearly, but if you were able to contribute that I should be able to get things up and running and merged ASAP. Thank you!

@WardF WardF requested review from Copilot and removed request for Copilot August 21, 2025 21:54

This comment was marked as outdated.

@gmao-cda
Copy link
Copy Markdown
Contributor

gmao-cda commented Aug 30, 2025

Hi @WardF, I have added a test in the PR #469. PR #469 shall be merged after PR #453
Please let me know if I need further revise it. Thanks!

@veenstrajelmer
Copy link
Copy Markdown

veenstrajelmer commented Oct 21, 2025

@WardF I noticed the related issue #181 that is still open. Should it be closed or does this PR not completely fix that issue?

Internally we are also running into this same issue with netcdf network files written with xarray (and engine="h5netcdf"), resulting in string-type attributes. I would love to see if we can update the netcdf-fortran library in our software, but for that it would be required that there is another release including this fix. Is that by any chance already planned?

@gmao-cda
Copy link
Copy Markdown
Contributor

gmao-cda commented Oct 21, 2025

(cc @WardF here)

@veenstrajelmer For the 1d string, it has been solved using the source codes from the latest branch main

Check this test to see how to read string: https://github.com/Unidata/netcdf-fortran/blob/main/nf03_test4/f90tst_att.F90

The corresponding test data is here: https://github.com/Unidata/netcdf-fortran/blob/main/nf03_test4/ref_att.nc
Its cdl is: https://github.com/Unidata/netcdf-fortran/blob/main/nf03_test4/ref_att.cdl

Let me know if it works for you. If you cannot change the netcdf-fortran version, I will provide you an alternative solution.

@veenstrajelmer
Copy link
Copy Markdown

Great, thanks for the reply. And are there any plans to release somewhere soon? I don't think I can push a non-released version into our pipelines, that won't be accepted.

if ( xtype == nf90_string .and. nlen == 1 ) then
c_ncid = ncid
c_varid = varid - 1
c_aname = name//char(0)
Copy link
Copy Markdown

@dupontf dupontf Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot guys for the addition! Just one comment: it works better for me if I add a trim function around name:

-        c_aname = name//char(0)
+        c_aname = trim(name)//char(0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trim removes trailing blanks. Trailing blanks are legal in attribute names, according to current netCDF specs, IIRC. Why would you want to do this?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, I may be wrong, but the fact that c_aname is defined using len_trim(name)+1), means that, if name is padded with blanks, the special character \0 would be out of bound and erasable by the next allocation...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dupontf In the netCDF "Classic Format" spec, I find this:

Names that have trailing space characters are also not permitted.

Therefore my earlier comment was mistaken, and I can not disagree with your suggestion to add trim. Internal blanks are allowed, just not leading or trailing ones. That is sensible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants