$search
00001 #ifndef PI_PROPERTIES_NETCDFHEADER_SERIALIZER 00002 #define PI_PROPERTIES_NETCDFHEADER_SERIALIZER 00003 00004 #include <rtt/Property.hpp> 00005 #include <boost/lexical_cast.hpp> 00006 00007 #include <netcdf.h> 00008 00009 #define DIMENSION_VAR 1 00010 #define DIMENSION_ARRAY 2 00011 00012 #include <iostream> 00013 using namespace std; 00014 00015 namespace RTT 00016 { 00020 class NetcdfHeaderMarshaller 00021 : public marsh::MarshallInterface 00022 { 00023 int nameless_counter; 00024 std::string prefix; 00025 int ncid; 00026 int dimsid; 00027 int ncopen; 00028 00029 public: 00030 00031 NetcdfHeaderMarshaller(int ncid, int dimsid) : ncid( ncid ), dimsid(dimsid), ncopen(0) {} 00032 00033 virtual ~NetcdfHeaderMarshaller() {} 00034 00035 virtual void serialize(base::PropertyBase* v) 00036 { 00037 Property<PropertyBag>* bag = dynamic_cast< Property<PropertyBag>* >( v ); 00038 if ( bag ) 00039 this->serialize( *bag ); 00040 else { 00041 Property<char>* Pc = dynamic_cast< Property<char>* >( v ); 00042 if ( Pc ) 00043 { 00044 store(Pc); 00045 return; 00046 } 00047 Property<short>* Ps = dynamic_cast< Property<short>* >( v ); 00048 if (Ps) 00049 { 00050 store(Ps); 00051 return; 00052 } 00053 Property<int>* Pi = dynamic_cast< Property<int>* >( v ); 00054 if (Pi) 00055 { 00056 store(Pi); 00057 return; 00058 } 00059 Property<float>* Pf = dynamic_cast< Property<float>* >( v ); 00060 if (Pf) 00061 { 00062 store(Pf); 00063 return; 00064 } 00065 Property<double>* Pd = dynamic_cast< Property<double>* >( v ); 00066 if (Pd) 00067 { 00068 store(Pd); 00069 return; 00070 } 00071 Property<std::vector<double> >* Pv = dynamic_cast< Property<std::vector<double> >* >( v ); 00072 if (Pv) 00073 { 00074 store(Pv); 00075 return; 00076 } 00077 } 00078 } 00079 00080 virtual void serialize(const PropertyBag &v) 00081 { 00082 int retval; 00083 00088 if ( ncopen ) { 00089 ncopen++; 00090 } 00091 else { 00092 retval = nc_redef(ncid); 00093 if ( retval ) 00094 log(Error) << "Could not enter define mode in NetcdfHeaderMarshaller, error "<< retval <<endlog(); 00095 else 00096 ncopen++; 00097 } 00098 00099 for ( 00100 PropertyBag::const_iterator i = v.getProperties().begin(); 00101 i != v.getProperties().end(); 00102 i++ ) 00103 { 00104 this->serialize(*i); 00105 } 00106 00110 if (--ncopen) 00111 log(Info) << "Serializer still in progress" <<endlog(); 00112 else { 00113 retval = nc_enddef(ncid); 00114 if (retval) 00115 log(Error) << "Could not leave define mode, error" << retval <<endlog(); 00116 } 00117 } 00118 00119 virtual void serialize(const Property<PropertyBag> &v) 00120 { 00121 std::string oldpref = prefix; 00122 00123 // Avoid a "." in the beginning of a variable name 00124 if(prefix.empty()) 00125 prefix = v.getName(); 00126 else 00127 prefix += "." + v.getName(); 00128 00129 serialize(v.rvalue()); 00130 00131 prefix = oldpref; 00132 nameless_counter = 0; 00133 } 00134 00138 void store(Property<char> *v) 00139 { 00140 int retval; 00141 int varid; 00142 std::string sname = composeName(v->getName()); 00143 00147 retval = nc_def_var(ncid, sname.c_str(), NC_BYTE, DIMENSION_VAR, 00148 &dimsid, &varid); 00149 if ( retval ) 00150 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog(); 00151 else 00152 log(Info) << "Variable "<< sname << " successfully created" <<endlog(); 00153 } 00154 00158 void store(Property<short> *v) 00159 { 00160 int retval; 00161 int varid; 00162 std::string sname = composeName(v->getName()); 00163 00167 retval = nc_def_var(ncid, sname.c_str(), NC_SHORT, DIMENSION_VAR, 00168 &dimsid, &varid); 00169 if ( retval ) 00170 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog(); 00171 else 00172 log(Info) << "Variable "<< sname << " successfully created" <<endlog(); 00173 } 00174 00178 void store(Property<int> *v) 00179 { 00180 int retval; 00181 int varid; 00182 std::string sname = composeName(v->getName()); 00183 00187 retval = nc_def_var(ncid, sname.c_str(), NC_INT, DIMENSION_VAR, 00188 &dimsid, &varid); 00189 if ( retval ) 00190 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog(); 00191 else 00192 log(Info) << "Variable "<< sname << " successfully created" <<endlog(); 00193 } 00194 00198 void store(Property<float> *v) 00199 { 00200 int retval; 00201 int varid; 00202 std::string sname = composeName(v->getName()); 00203 00207 retval = nc_def_var(ncid, sname.c_str(), NC_FLOAT, DIMENSION_VAR, 00208 &dimsid, &varid); 00209 if ( retval ) 00210 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog(); 00211 else 00212 log(Info) << "Variable "<< sname << " successfully created" <<endlog(); 00213 } 00214 00218 void store(Property<double> *v) 00219 { 00220 int retval; 00221 int varid; 00222 std::string sname = composeName(v->getName()); 00223 00227 retval = nc_def_var(ncid, sname.c_str(), NC_DOUBLE, DIMENSION_VAR, 00228 &dimsid, &varid); 00229 00230 if ( retval ) 00231 log(Error) << "Could not create variable " << sname << ", error " << retval <<endlog(); 00232 else 00233 log(Info) << "Variable "<< sname << " successfully created" <<endlog(); 00234 } 00235 00239 void store(Property<std::vector<double> > *v) 00240 { 00241 int retval; 00242 int varid; 00243 00244 std::string dim_name = v->getName().c_str(); 00245 dim_name += "_dim"; 00246 const char *dimname = dim_name.c_str(); 00247 00248 const char *name = v->getName().c_str(); 00249 00250 int dims[ DIMENSION_ARRAY ]; 00251 int var_dim; 00252 00253 // create new dimension 00254 retval = nc_def_dim(ncid, dimname, v->rvalue().size(), &var_dim); 00255 if ( retval ) 00256 log(Error) << "Could not create new dimension for "<< dimname <<", error "<< retval <<endlog(); 00257 00258 // fill in dims 00259 dims[0] = dimsid; 00260 dims[1] = var_dim; 00261 00262 retval = nc_def_var(ncid, name, NC_DOUBLE, DIMENSION_ARRAY, 00263 dims, &varid); 00264 if ( retval ) 00265 log(Error) << "Could not create " << name << ", error " << retval <<endlog(); 00266 else 00267 log(Info) << "Variable "<< name << " successfully created" <<endlog(); 00268 } 00269 00270 std::string composeName(std::string propertyName) 00271 { 00272 std::string last_name; 00273 00274 if( propertyName.empty() ) { 00275 nameless_counter++; 00276 last_name = boost::lexical_cast<std::string>( nameless_counter ); 00277 } 00278 else { 00279 nameless_counter = 0; 00280 last_name = propertyName; 00281 } 00282 if ( prefix.empty() ) 00283 return last_name; 00284 else 00285 return prefix + "." + last_name; 00286 } 00287 00288 virtual void flush() {} 00289 }; 00290 } 00291 #endif