module nf95_find_coord_m implicit none contains subroutine nf95_find_coord(ncid, name, dimid, varid, std_name) ! This procedure returns the name, dimension id or variable id of ! the NetCDF coordinate with standard name "std_name", if such a ! coordinate exists. The standard name is only used to know what ! to search, it is not used for the search itself. The search ! itself is done via a string match on the attribute "units". So ! the NetCDF variable one looks for does not need to have the ! attribute "std_name". use netcdf, only: NF90_MAX_NAME, NF90_NOERR use nf95_get_att_m, only: nf95_get_att use nf95_inq_varid_m, only: nf95_inq_varid use nf95_inquire_dimension_m, only: nf95_inquire_dimension use nf95_inquire_m, only: nf95_inquire use nf95_inquire_variable_m, only: nf95_inquire_variable integer, intent(in):: ncid character(len=*), intent(out), optional:: name ! blanks if not found ! The actual character argument should normally have the length ! "NF95_MAX_NAME". integer, intent(out), optional:: dimid ! 0 if not found integer, intent(out), optional:: varid ! 0 if not found character(len=*), intent(in):: std_name ! standard name : "plev", "latitude", "longitude" or "time" ! Variables local to the procedure: character(len=13), allocatable:: units(:) logical exact ! "units" must be matched exactly integer ncerr, nDimensions, dimid_local, varid_local character(len=NF90_MAX_NAME) name_local integer, allocatable:: dimids(:) character(len=80) values logical found !---------------------------------------------- select case (std_name) case("longitude") allocate(units(1)) units(1)="degrees_east" exact=.true. case("latitude") allocate(units(1)) units(1)="degrees_north" exact=.true. case("time") allocate(units(1)) units(1)=" since" exact=.false. case("plev") allocate(units(4)) units = ["Pa ", "hPa ", "millibar ", & "mbar "] exact = .true. case default print *, "nf95_find_coord: bad value of std_name" print *, "std_name = ", std_name stop 1 end select call nf95_inquire(ncid, nDimensions) dimid_local = 0 found = .false. ! Loop on dimensions: do while (.not. found .and. dimid_local < nDimensions) dimid_local = dimid_local + 1 call nf95_inquire_dimension(ncid, dimid_local, name_local) call nf95_inq_varid(ncid, name_local, varid_local, ncerr) if (ncerr == NF90_NOERR) then call nf95_inquire_variable(ncid, varid_local, dimids=dimids) if (size(dimids) == 1) then if (dimids(1) == dimid_local) then ! We have found a coordinate call nf95_get_att(ncid, varid_local, "units", values, ncerr) if (ncerr == NF90_NOERR)then if (exact) then found = any(values == units) else found = index(values, trim(units(1))) /= 0 end if end if end if end if end if end do if (found) then if (present(name)) name = name_local if (present(dimid)) dimid = dimid_local if (present(varid)) varid = varid_local else if (present(name)) name = "" if (present(dimid)) dimid = 0 if (present(varid)) varid = 0 end if end subroutine nf95_find_coord end module nf95_find_coord_m