OrocosComponentLibrary  2.8.3
NetcdfHeaderMarshaller.hpp
1 #ifndef PI_PROPERTIES_NETCDFHEADER_SERIALIZER
2 #define PI_PROPERTIES_NETCDFHEADER_SERIALIZER
3 
4 #include <rtt/Property.hpp>
5 #include <boost/lexical_cast.hpp>
6 
7 #include <netcdf.h>
8 
9 #define DIMENSION_VAR 1
10 #define DIMENSION_ARRAY 2
11 
12 #include <iostream>
13 using namespace std;
14 
15 namespace RTT
16 {
21  : public marsh::MarshallInterface
22  {
23  int nameless_counter;
24  std::string prefix;
25  int ncid;
26  int dimsid;
27  int ncopen;
28 
29  public:
30 
31  NetcdfHeaderMarshaller(int ncid, int dimsid) : ncid( ncid ), dimsid(dimsid), ncopen(0) {}
32 
33  virtual ~NetcdfHeaderMarshaller() {}
34 
35  virtual void serialize(base::PropertyBase* v)
36  {
37  Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v );
38  if ( bag )
39  this->serialize( *bag );
40  else {
41  Property<char>* Pc = dynamic_cast< Property<char>* >( v );
42  if ( Pc )
43  {
44  store(Pc);
45  return;
46  }
47  Property<short>* Ps = dynamic_cast< Property<short>* >( v );
48  if (Ps)
49  {
50  store(Ps);
51  return;
52  }
53  Property<int>* Pi = dynamic_cast< Property<int>* >( v );
54  if (Pi)
55  {
56  store(Pi);
57  return;
58  }
59  Property<float>* Pf = dynamic_cast< Property<float>* >( v );
60  if (Pf)
61  {
62  store(Pf);
63  return;
64  }
65  Property<double>* Pd = dynamic_cast< Property<double>* >( v );
66  if (Pd)
67  {
68  store(Pd);
69  return;
70  }
71  Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v );
72  if (Pv)
73  {
74  store(Pv);
75  return;
76  }
77  }
78  }
79 
80  virtual void serialize(const PropertyBag &v)
81  {
82  int retval;
83 
88  if ( ncopen ) {
89  ncopen++;
90  }
91  else {
92  retval = nc_redef(ncid);
93  if ( retval )
94  log(Error) << "Could not enter define mode in NetcdfHeaderMarshaller, error "<< retval <<endlog();
95  else
96  ncopen++;
97  }
98 
99  for (
100  PropertyBag::const_iterator i = v.getProperties().begin();
101  i != v.getProperties().end();
102  i++ )
103  {
104  this->serialize(*i);
105  }
106 
110  if (--ncopen)
111  log(Info) << "Serializer still in progress" <<endlog();
112  else {
113  retval = nc_enddef(ncid);
114  if (retval)
115  log(Error) << "Could not leave define mode, error" << retval <<endlog();
116  }
117  }
118 
119  virtual void serialize(const Property<PropertyBag> &v)
120  {
121  std::string oldpref = prefix;
122 
123  // Avoid a "." in the beginning of a variable name
124  if(prefix.empty())
125  prefix = v.getName();
126  else
127  prefix += "." + v.getName();
128 
129  serialize(v.rvalue());
130 
131  prefix = oldpref;
132  nameless_counter = 0;
133  }
134 
138  void store(Property<char> *v)
139  {
140  int retval;
141  int varid;
142  std::string sname = composeName(v->getName());
143 
147  retval = nc_def_var(ncid, sname.c_str(), NC_BYTE, DIMENSION_VAR,
148  &dimsid, &varid);
149  if ( retval )
150  log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
151  else
152  log(Info) << "Variable "<< sname << " successfully created" <<endlog();
153  }
154 
158  void store(Property<short> *v)
159  {
160  int retval;
161  int varid;
162  std::string sname = composeName(v->getName());
163 
167  retval = nc_def_var(ncid, sname.c_str(), NC_SHORT, DIMENSION_VAR,
168  &dimsid, &varid);
169  if ( retval )
170  log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
171  else
172  log(Info) << "Variable "<< sname << " successfully created" <<endlog();
173  }
174 
178  void store(Property<int> *v)
179  {
180  int retval;
181  int varid;
182  std::string sname = composeName(v->getName());
183 
187  retval = nc_def_var(ncid, sname.c_str(), NC_INT, DIMENSION_VAR,
188  &dimsid, &varid);
189  if ( retval )
190  log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
191  else
192  log(Info) << "Variable "<< sname << " successfully created" <<endlog();
193  }
194 
198  void store(Property<float> *v)
199  {
200  int retval;
201  int varid;
202  std::string sname = composeName(v->getName());
203 
207  retval = nc_def_var(ncid, sname.c_str(), NC_FLOAT, DIMENSION_VAR,
208  &dimsid, &varid);
209  if ( retval )
210  log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
211  else
212  log(Info) << "Variable "<< sname << " successfully created" <<endlog();
213  }
214 
218  void store(Property<double> *v)
219  {
220  int retval;
221  int varid;
222  std::string sname = composeName(v->getName());
223 
227  retval = nc_def_var(ncid, sname.c_str(), NC_DOUBLE, DIMENSION_VAR,
228  &dimsid, &varid);
229 
230  if ( retval )
231  log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog();
232  else
233  log(Info) << "Variable "<< sname << " successfully created" <<endlog();
234  }
235 
239  void store(Property<std::vector<double> > *v)
240  {
241  int retval;
242  int varid;
243 
244  std::string dim_name = v->getName().c_str();
245  dim_name += "_dim";
246  const char *dimname = dim_name.c_str();
247 
248  const char *name = v->getName().c_str();
249 
250  int dims[ DIMENSION_ARRAY ];
251  int var_dim;
252 
253  // create new dimension
254  retval = nc_def_dim(ncid, dimname, v->rvalue().size(), &var_dim);
255  if ( retval )
256  log(Error) << "Could not create new dimension for "<< dimname <<", error "<< retval <<endlog();
257 
258  // fill in dims
259  dims[0] = dimsid;
260  dims[1] = var_dim;
261 
262  retval = nc_def_var(ncid, name, NC_DOUBLE, DIMENSION_ARRAY,
263  dims, &varid);
264  if ( retval )
265  log(Error) << "Could not create " << name << ", error " << retval <<endlog();
266  else
267  log(Info) << "Variable "<< name << " successfully created" <<endlog();
268  }
269 
270  std::string composeName(std::string propertyName)
271  {
272  std::string last_name;
273 
274  if( propertyName.empty() ) {
275  nameless_counter++;
276  last_name = boost::lexical_cast<std::string>( nameless_counter );
277  }
278  else {
279  nameless_counter = 0;
280  last_name = propertyName;
281  }
282  if ( prefix.empty() )
283  return last_name;
284  else
285  return prefix + "." + last_name;
286  }
287 
288  virtual void flush() {}
289  };
290 }
291 #endif
virtual void serialize(const PropertyBag &v)
A marsh::MarshallInterface for generating variables in a netcdf dataset.
STL namespace.
void store(Property< double > *v)
Create a variable of data type double.
void store(Property< char > *v)
Create a variable of data type char.
void store(Property< int > *v)
Create a variable of data type int.
void store(Property< float > *v)
Create a variable of data type float.
void store(Property< short > *v)
Create a variable of data type short.
Definition: Category.hpp:10
void store(Property< std::vector< double > > *v)
Create a variable with two dimensions of data type double.