WSL/SLF GitLab Repository
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
snow-models
meteoio
Commits
43604e1d
Commit
43604e1d
authored
Apr 25, 2014
by
Thomas Egger
Browse files
NetCDFIO: completed implementation of reading meteo data
parent
cb07fccb
Changes
2
Hide whitespace changes
Inline
Side-by-side
meteoio/plugins/NetCDFIO.cc
View file @
43604e1d
...
...
@@ -35,10 +35,11 @@ namespace mio {
* - COORDPARAM: extra coordinates parameters (see Coords); [Input] and [Output] section
* - DEMFILE: The filename of the file containing the DEM; [Input] section
* - DEMVAR: The variable name of the DEM within the DEMFILE; [Input] section
* - METEOFILE: the NetCDF file which shall be used for the meteo parameter input/output; [Input] and [Output] section
* - GRID2DFILE: the NetCDF file which shall be used for gridded input/output; [Input] and [Output] section
*/
const
double
NetCDFIO
::
plugin_nodata
=
-
999.
;
//
plugin specific nodata value. It can also be read by the plugin (depending on what is appropriate)
const
double
NetCDFIO
::
plugin_nodata
=
-
999
9999
.
;
//
CNRM-GAME nodata value
const
std
::
string
NetCDFIO
::
lat_str
=
"lat"
;
const
std
::
string
NetCDFIO
::
lon_str
=
"lon"
;
const
std
::
string
NetCDFIO
::
z_str
=
"z"
;
...
...
@@ -50,20 +51,26 @@ const std::string NetCDFIO::cf_units = "units";
const
std
::
string
NetCDFIO
::
cf_days
=
"days since "
;
const
std
::
string
NetCDFIO
::
cf_seconds
=
"seconds since "
;
const
std
::
string
NetCDFIO
::
xx
_altitude
=
"ZS"
;
const
std
::
string
NetCDFIO
::
xx
_aspect
=
"aspect"
;
const
std
::
string
NetCDFIO
::
xx
_slope
=
"slope"
;
const
std
::
string
NetCDFIO
::
cnrm
_altitude
=
"ZS"
;
const
std
::
string
NetCDFIO
::
cnrm
_aspect
=
"aspect"
;
const
std
::
string
NetCDFIO
::
cnrm
_slope
=
"slope"
;
std
::
map
<
s
ize_t
,
string
>
NetCDFIO
::
paramname
;
std
::
map
<
s
td
::
string
,
size_t
>
NetCDFIO
::
paramname
;
const
bool
NetCDFIO
::
__init
=
NetCDFIO
::
initStaticData
();
bool
NetCDFIO
::
initStaticData
()
{
//Associate unsigned int value and a string representation of a meteo parameter
paramname
[
MeteoData
::
TA
]
=
"Tair"
;
paramname
[
MeteoData
::
RH
]
=
"HUMREL"
;
paramname
[
MeteoData
::
VW
]
=
"Wind"
;
paramname
[
MeteoData
::
DW
]
=
"Wind_DIR"
;
paramname
[
"Tair"
]
=
MeteoData
::
TA
;
// paramname["Qair"] = IOUtils::npos; // not a standard MeteoIO parameter
paramname
[
"HUMREL"
]
=
MeteoData
::
RH
;
paramname
[
"Wind"
]
=
MeteoData
::
VW
;
paramname
[
"Wind_DIR"
]
=
MeteoData
::
DW
;
paramname
[
"Rainf"
]
=
MeteoData
::
HNW
;
paramname
[
"Snowf"
]
=
IOUtils
::
npos
;
// not a standard MeteoIO parameter
paramname
[
"theorSW"
]
=
MeteoData
::
ISWR
;
paramname
[
"PSurf"
]
=
MeteoData
::
P
;
paramname
[
"LWdown"
]
=
MeteoData
::
ILWR
;
return
true
;
}
...
...
@@ -320,11 +327,11 @@ void NetCDFIO::readMetaData(const int& ncid, std::vector<StationData>& vecStatio
//HACK: could check dimension of all the vars, must be 'Number_of_points'
get_dimension
(
ncid
,
"Number_of_points"
,
dimid
,
dimlen
);
get_variable
(
ncid
,
NetCDFIO
::
xx
_altitude
,
vid_alt
);
get_variable
(
ncid
,
NetCDFIO
::
cnrm
_altitude
,
vid_alt
);
get_variable
(
ncid
,
IOUtils
::
strToUpper
(
NetCDFIO
::
lat_str
),
vid_lat
);
get_variable
(
ncid
,
IOUtils
::
strToUpper
(
NetCDFIO
::
lon_str
),
vid_lon
);
get_variable
(
ncid
,
NetCDFIO
::
xx
_aspect
,
vid_aspect
);
get_variable
(
ncid
,
NetCDFIO
::
xx
_slope
,
vid_slope
);
get_variable
(
ncid
,
NetCDFIO
::
cnrm
_aspect
,
vid_aspect
);
get_variable
(
ncid
,
NetCDFIO
::
cnrm
_slope
,
vid_slope
);
double
*
alt
=
new
double
[
dimlen
];
double
*
lat
=
new
double
[
dimlen
];
...
...
@@ -380,25 +387,26 @@ void NetCDFIO::readMeteoData(const Date& dateStart, const Date& dateEnd, std::ve
size_t
index_start
,
index_end
;
vector
<
Date
>
vec_date
;
get_indices
(
ncid
,
dateStart
,
dateEnd
,
index_start
,
index_end
,
vec_date
);
//get indices for dateStart and dateEnd
MeteoData
meteo_data
;
//the template MeteoData object
if
((
index_start
!=
IOUtils
::
npos
)
&&
(
index_end
!=
IOUtils
::
npos
))
{
map
<
s
ize_t
,
string
>
map_parameters
;
get_parameters
(
ncid
,
map_parameters
);
//get a list of parameters present
map
<
s
tring
,
size_t
>
map_parameters
;
get_parameters
(
ncid
,
map_parameters
,
meteo_data
);
//get a list of parameters present
readData
(
ncid
,
index_start
,
vec_date
,
map_parameters
,
vecMeteo
);
readData
(
ncid
,
index_start
,
vec_date
,
map_parameters
,
meteo_data
,
vecMeteo
);
}
}
close_file
(
filename
,
ncid
);
}
void
NetCDFIO
::
readData
(
const
int
&
ncid
,
const
size_t
&
index_start
,
const
std
::
vector
<
Date
>&
vec_date
,
const
std
::
map
<
size_t
,
std
::
string
>&
map_parameters
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
)
void
NetCDFIO
::
readData
(
const
int
&
ncid
,
const
size_t
&
index_start
,
const
std
::
vector
<
Date
>&
vec_date
,
const
std
::
map
<
std
::
string
,
size_t
>&
map_parameters
,
const
MeteoData
&
meteo_data
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
)
{
size_t
number_of_stations
=
vecMetaData
.
size
();
size_t
number_of_records
=
vec_date
.
size
();
//Allocate all the MeteoData objects
vector
<
MeteoData
>
tmp_vec
(
number_of_records
);
vector
<
MeteoData
>
tmp_vec
(
number_of_records
,
meteo_data
);
for
(
size_t
jj
=
0
;
jj
<
number_of_records
;
jj
++
)
tmp_vec
[
jj
].
date
=
vec_date
[
jj
];
//set correct date for every record
for
(
size_t
ii
=
0
;
ii
<
number_of_stations
;
ii
++
)
{
...
...
@@ -407,43 +415,97 @@ void NetCDFIO::readData(const int& ncid, const size_t& index_start, const std::v
}
//allocate enough linear space for each parameter
map
<
s
ize_t
,
double
*>
map_data
;
for
(
map
<
s
ize_t
,
string
>::
const_iterator
it
=
map_parameters
.
begin
();
it
!=
map_parameters
.
end
();
it
++
)
{
map
<
s
tring
,
double
*>
map_data
;
for
(
map
<
s
tring
,
size_t
>::
const_iterator
it
=
map_parameters
.
begin
();
it
!=
map_parameters
.
end
();
it
++
)
{
double
*
data
=
new
double
[
number_of_stations
*
number_of_records
];
map_data
[
it
->
first
]
=
data
;
const
string
&
varname
=
it
->
first
;
const
string
&
varname
=
it
->
second
;
map_data
[
varname
]
=
data
;
int
varid
;
get_variable
(
ncid
,
varname
,
varid
);
read_data_2D
(
ncid
,
varname
,
varid
,
index_start
,
number_of_records
,
number_of_stations
,
data
);
}
copy_data
(
map_data
,
number_of_stations
,
number_of_records
,
vecMeteo
);
copy_data
(
ncid
,
map_data
,
number_of_stations
,
number_of_records
,
vecMeteo
);
for
(
map
<
s
ize_t
,
double
*>::
const_iterator
it
=
map_data
.
begin
();
it
!=
map_data
.
end
();
it
++
)
{
for
(
map
<
s
tring
,
double
*>::
const_iterator
it
=
map_data
.
begin
();
it
!=
map_data
.
end
();
it
++
)
{
delete
[]
it
->
second
;
}
}
void
NetCDFIO
::
copy_data
(
const
std
::
map
<
size_t
,
double
*>
map_data
,
const
size_t
&
number_of_stations
,
const
size_t
&
number_of_records
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
)
void
NetCDFIO
::
copy_data
(
const
int
&
ncid
,
const
std
::
map
<
std
::
string
,
double
*>
map_data
,
const
size_t
&
number_of_stations
,
const
size_t
&
number_of_records
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
)
{
//adapt units, adapt nodata
for
(
size_t
ii
=
0
;
ii
<
number_of_stations
;
ii
++
)
{
for
(
map
<
string
,
double
*>::
const_iterator
it
=
map_data
.
begin
();
it
!=
map_data
.
end
();
it
++
)
{
const
string
&
varname
=
it
->
first
;
//find correct handling for each parameter
bool
simple_copy
=
false
,
mutiply_copy
=
false
,
snowf
=
false
;
double
multiplier
=
IOUtils
::
nodata
;
size_t
param
=
paramname
[
varname
];
//must exist, at this point we know it does
if
((
varname
==
"Snowf"
)
||
(
varname
==
"Rainf"
))
{
int
varid
;
get_variable
(
ncid
,
"FRC_TIME_STP"
,
varid
);
read_value
(
ncid
,
"FRC_TIME_STP"
,
varid
,
multiplier
);
if
(
multiplier
<=
0
)
throw
InvalidArgumentException
(
"The variable FRC_TIME_STP is invalid"
,
AT
);
}
if
(
param
==
IOUtils
::
npos
)
{
if
(
varname
==
"Snowf"
)
{
snowf
=
true
;
}
}
else
{
if
(
varname
==
"HUMREL"
)
{
mutiply_copy
=
true
;
multiplier
=
0.01
;
}
else
if
(
varname
==
"Rainf"
)
{
mutiply_copy
=
true
;
}
else
{
simple_copy
=
true
;
}
}
for
(
size_t
jj
=
0
;
jj
<
number_of_records
;
jj
++
)
{
for
(
map
<
size_t
,
double
*>::
const_iterator
it
=
map_data
.
begin
();
it
!=
map_data
.
end
();
it
++
)
{
vecMeteo
[
ii
][
jj
](
it
->
first
)
=
(
it
->
second
)[
jj
];
for
(
size_t
ii
=
0
;
ii
<
number_of_stations
;
ii
++
)
{
double
&
value
=
(
it
->
second
)[
jj
*
number_of_stations
+
ii
];
bool
nodata
=
false
;
if
(
value
==
plugin_nodata
)
{
nodata
=
true
;
value
=
IOUtils
::
nodata
;
}
if
(
simple_copy
)
{
vecMeteo
[
ii
][
jj
](
param
)
=
value
;
}
else
if
(
mutiply_copy
)
{
if
(
nodata
)
{
vecMeteo
[
ii
][
jj
](
param
)
=
value
;
}
else
{
vecMeteo
[
ii
][
jj
](
param
)
=
value
*
multiplier
;
}
}
else
if
(
snowf
)
{
double
&
hnw
=
vecMeteo
[
ii
][
jj
](
MeteoData
::
HNW
);
if
(
!
nodata
)
{
if
(
hnw
==
IOUtils
::
nodata
)
hnw
=
0.0
;
hnw
+=
value
*
multiplier
;
}
}
}
}
}
}
void
NetCDFIO
::
get_parameters
(
const
int
&
ncid
,
std
::
map
<
size_t
,
std
::
string
>&
map_parameters
)
void
NetCDFIO
::
get_parameters
(
const
int
&
ncid
,
std
::
map
<
std
::
string
,
size_t
>&
map_parameters
,
MeteoData
&
)
{
map
<
size_t
,
string
>::
iterator
it
;
for
(
it
=
paramname
.
begin
();
it
!=
paramname
.
end
();
it
++
)
{
if
(
check_variable
(
ncid
,
it
->
second
))
{
cout
<<
"Found parameter: "
<<
it
->
second
<<
endl
;
//TODO: Build template
for
(
map
<
string
,
size_t
>::
iterator
it
=
paramname
.
begin
();
it
!=
paramname
.
end
();
it
++
)
{
if
(
check_variable
(
ncid
,
it
->
first
))
{
//cout << "Found parameter: " << it->first << endl;
map_parameters
[
it
->
first
]
=
it
->
second
;
}
}
...
...
@@ -525,8 +587,8 @@ void NetCDFIO::get_indices(const int& ncid, const Date& dateStart, const Date& d
cout << (*it).toString() << endl;
}
*/
cout
<<
dateStart
.
toString
(
Date
::
ISO
)
<<
" - "
<<
dateEnd
.
toString
(
Date
::
ISO
)
<<
endl
;
cout
<<
"indexStart: "
<<
indexStart
<<
" indexEnd: "
<<
indexEnd
<<
endl
;
//
cout << dateStart.toString(Date::ISO) << " - " << dateEnd.toString(Date::ISO) << endl;
//
cout << "indexStart: " << indexStart << " indexEnd: " << indexEnd << endl;
delete
[]
time
;
}
...
...
@@ -966,6 +1028,16 @@ void NetCDFIO::read_data_2D(const int& ncid, const std::string& varname, const i
throw
IOException
(
"Could not retrieve data for variable '"
+
varname
+
"': "
+
nc_strerror
(
status
),
AT
);
}
void
NetCDFIO
::
read_value
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
double
&
data
)
{
size_t
index
[]
=
{
0
};
int
status
=
nc_get_var1_double
(
ncid
,
varid
,
index
,
&
data
);
if
(
status
!=
NC_NOERR
)
throw
IOException
(
"Could not retrieve data for variable '"
+
varname
+
"': "
+
nc_strerror
(
status
),
AT
);
}
void
NetCDFIO
::
read_data
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
const
size_t
&
pos
,
const
size_t
&
latlen
,
const
size_t
&
lonlen
,
double
*&
data
)
{
...
...
meteoio/plugins/NetCDFIO.h
View file @
43604e1d
...
...
@@ -64,9 +64,9 @@ class NetCDFIO : public IOInterface {
private:
void
parseInputOutputSection
();
void
get_parameters
(
const
int
&
ncid
,
std
::
map
<
size_t
,
std
::
string
>&
map_parameters
);
void
copy_data
(
const
std
::
map
<
size_t
,
double
*>
map_data
,
const
size_t
&
number_of_stations
,
const
size_t
&
number_of_records
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
);
void
readData
(
const
int
&
ncid
,
const
size_t
&
index_start
,
const
std
::
vector
<
Date
>&
vec_date
,
const
std
::
map
<
size_t
,
std
::
string
>&
map_parameters
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
);
void
get_parameters
(
const
int
&
ncid
,
std
::
map
<
std
::
string
,
size_t
>&
map_parameters
,
MeteoData
&
meteo_data
);
void
copy_data
(
const
int
&
ncid
,
const
std
::
map
<
std
::
string
,
double
*>
map_data
,
const
size_t
&
number_of_stations
,
const
size_t
&
number_of_records
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
);
void
readData
(
const
int
&
ncid
,
const
size_t
&
index_start
,
const
std
::
vector
<
Date
>&
vec_date
,
const
std
::
map
<
std
::
string
,
size_t
>&
map_parameters
,
const
MeteoData
&
meteo_data
,
std
::
vector
<
std
::
vector
<
MeteoData
>
>&
vecMeteo
);
void
readMetaData
(
const
int
&
ncid
,
std
::
vector
<
StationData
>&
vecStation
);
void
copy_grid
(
const
size_t
&
latlen
,
const
size_t
&
lonlen
,
double
*&
lat
,
double
*&
lon
,
double
*&
grid
,
Grid2DObject
&
grid_out
);
std
::
string
get_varname
(
const
MeteoGrids
::
Parameters
&
parameter
);
...
...
@@ -91,6 +91,7 @@ class NetCDFIO : public IOInterface {
const
size_t
&
pos
,
const
size_t
&
latlen
,
const
size_t
&
lonlen
,
double
*&
data
);
void
read_data_2D
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
const
size_t
&
record
,
const
size_t
&
count
,
const
size_t
&
length
,
double
*&
data
);
void
read_value
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
double
&
data
);
void
read_data
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
double
*&
data
);
void
write_data
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
double
*&
data
);
void
write_data
(
const
int
&
ncid
,
const
std
::
string
&
varname
,
const
int
&
varid
,
const
Grid2DObject
&
grid
,
const
size_t
&
pos_start
,
double
*&
data
);
...
...
@@ -115,8 +116,8 @@ class NetCDFIO : public IOInterface {
static
const
double
plugin_nodata
;
//plugin specific nodata value, e.g. -999
static
const
std
::
string
lat_str
,
lon_str
,
z_str
,
ta_str
,
rh_str
;
static
const
std
::
string
cf_time
,
cf_units
,
cf_days
,
cf_seconds
;
static
const
std
::
string
xx
_altitude
,
xx
_aspect
,
xx
_slope
;
static
std
::
map
<
size_t
,
std
::
string
>
paramname
;
///<Associate a name with meteo parameters in Parameters
static
const
std
::
string
cnrm
_altitude
,
cnrm
_aspect
,
cnrm
_slope
;
static
std
::
map
<
std
::
string
,
size_t
>
paramname
;
///<Associate a name with meteo parameters in Parameters
static
const
bool
__init
;
///<helper variable to enable the init of static collection data
static
bool
initStaticData
();
///<initialize the static map
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment