Is it possible to query a netCDF file using lat,long,time for it's values

Jan 20, 2011 at 7:29 PM
Edited Jan 20, 2011 at 7:31 PM

Hi all and thanks for your work.

Is it possible to query a netCDF file using lat,long,time for it's values?

  • is there any sample on how to open the netCDF file and do exactly this ?
  • Can i use the viewer as a control from withing my application to view the netCDF file?
Developer
Jan 21, 2011 at 9:10 AM
Edited Jan 21, 2011 at 10:14 AM

Hi,

As far as I understand you need to get data from, say, 3d-variable "air" depending on dimensions "lat,lon,time" for given values of lat, lon and time instead of their indices? I. e.

double val = air[55.7, 33.5, new DateTime(2010,1,1))];

instead of

double val = air[20,20,100];

?

 

Unfortunately, there is no specific syntax for this in the SDS API now, but we have plans to enable this in a future version of the library. Nevertheless it is possible to resolve the issue using SDS now by code similar to the following:

using Microsoft.Research.Science.Data;
using Microsoft.Research.Science.Data.Imperative;
// Add references to the assemblies Microsoft.Research.Science.Data.Imperative and Microsoft.Research.Science.Data

        static void GetDataByValue()
        {
            using (DataSet ds = DataSet.Open("sampleData.nc"))
            {
                float[] lats = ds.GetData<float[]>("lat"); // latitudes grid
                float[] lons = ds.GetData<float[]>("lon"); // longitues 
                double[] times = ds.GetData<double[]>("time"); // times

                int i = IndexOf(lats, 55.7f); // looking for indices corresponding the values
                int j = IndexOf(lons, 33.5f);
                int k = IndexOf(times, 100.0);

                double val = ds.GetData<double>("air", i, j, k); // get air value for given grid values
            }
        }

        private static int IndexOf<T>(T[] orderedAscendArray, T value)
        {
            int i = Array.BinarySearch(orderedAscendArray, value);
            if (i < 0)
            {
                i = ~i;
                if (i >= orderedAscendArray.Length) i = orderedAscendArray.Length - 1;
            }
            return i;
        }

 

Jan 22, 2011 at 2:11 PM

Dvoits thanks a lot for your responce.

Well i tryed this and i can read the variables in the netCDF file  but when i want to get the value i get an exeption which i dont know what it means. 


"Cannot unambiguously identify a variable in the data set"

 

 Dim params() As Integer = New Integer() {i, j, k}

 Try                

'val = ds.GetData(Of Double)(Var, params)                

val = ds.GetData(Of Object)(Var, i, j, k)            

Catch ex As Exception                

val = -100            

End Try

 

I actually want to query the values by lat,long and time and possibly display a netCDF file like the pictures below ( this is a teprature netCDF file of Europe) :

I am using the dynamicdatadisplay executable from MS Research (http://dynamicdatadisplay.codeplex.com/)

I am wondering if i could use this along with SDS to display it in my application.



 

Coordinator
Jan 22, 2011 at 6:25 PM
Edited Jan 22, 2011 at 6:26 PM

Hello!

The message "Cannot unambiguously identify a variable in the data set" is a little bit confusing, because has one of two meanings:

1) There is no variable with specified name in the data set

2) There are more than one variable with specified name in the data set.

Probably you are passing name of variable than does not exists in data set. Please note that DataSetViewer tool shows long or display names of variables if they are specified in attributes. For example, on the screenshows above displayed name of variable is "Daily maximum..." and real variable name is tasmax (shown in Hints textbox). You need to use variable name "tasmax" when working with NC file using SDS.

And about your second question. You may use DataSetViewer as a control to show contents of SDS. Please look at samples and tutorials in the source code published on this site. Also there is a good example of using DataSetViewer as a control in Getting Started document.

DataSetViewer control uses DynamicDataDisplay library internally. But version included in SDS package is different from version published on dynamicdatadisplay.codeplex.com. It has more features, paletter support and colormap renderer as an examples.

 

Feb 7, 2011 at 11:06 AM

Well this is a little weird because i am getting from the sds tool the following info

 

 



sds meta ENSEMBLES_SMHIRCA30_A1B_ECHAM5-r3_MM_50km_201101-210001_tasma.nc          

 

Name =    institution = SMHI    

Conventions = CF-1.0        

source = RCA3.0    

project_id = ENSEMBLES 

 experiment_id = 200713    

realization = 1

  creation_date = 2009-12-09 07:08:35

comment = RCA3.0 Europe 50-km ECHAM5-A1B-3 L24    

VisualHints = tasmax(rlat,rlon) Style:Colormap

 


 

 

'[9] tasmax of type Single (time:1069) (height:1) (rlat:45) (rlon:85)        

'[8] time_bnds of type Double (time:1069) (bnds:2)        

'[7] time of type Double (time:1069)        

'[6] height of type Single (height:1)        

'[5] lat of type Single (rlat:45) (rlon:85)      

'[4] rlat of type Single (rlat:45)      

'[3] lon of type Single (rlat:45) (rlon:85)      

'[2] rlon of type Single (rlon:85)      

'[1] rotated_pole of type SByte

 

 


 

 

sds meta ENSEMBLES_SMHIRCA30_A1B_ECHAM5-r3_MM_50km_201101-210001_tasma.nc

tasmax[9] tasmax of type Single (time:1069) (height:1) (rlat:45) (rlon:85)                

Name = tasmax      

standard_name = air_temperature          

long_name = Daily maximum 2-m temperature              

units = K        

cell_methods = time: maximum        

coordinates = lon lat        

grid_mapping = rotated_pole        

 _FillValue = 1E+30        

VisualHints = tasmax(rlat,rlon) Style:Colormap

 

 


 

 

I was able to get values using 

 

     Dim var1 As Microsoft.Research.Science.Data.DataAccessVariable(Of Single) = ds.Variables("tasmax")

' looking for indices corresp1onding the values                

   Dim iLat As Integer = IndexOf(lats, latitudeVal)

    Dim iLon As Integer = IndexOf(lons, longtitudeVal)

    Dim iTime As Integer = IndexOf(times, timeVal)

    Dim iHeight As Integer = IndexOf(heights, heightVal)

    Dim params() As Integer = New Integer() {iTime, iHeight, iLat, iLon}

    Val = var1.Item(params)

'Val = ds.GetData(Of Object)(params) <= this returned the error

 

Now i am able to take the values i want to know if it is possible to slice somehow the variable tasmax by the other two variables time and height so that i can get tasmax only by (rlat,rlon) 

I have a DataSetViewerControl in my form but when  i assign the  DataSetViewerControl.dataset = ds  then the tasmax option is disabled.

Any ideas ?

Thanks Again for your support.