- Timestamp:
- 10/11/10 16:10:10 (14 years ago)
- Location:
- XMLIO_V2/dev/dev_rv/src/XMLIO
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
XMLIO_V2/dev/dev_rv/src/XMLIO/NetCDF4_data_output.hpp
r127 r128 45 45 { 46 46 string domid = ((*itt)->name.hasValue()) ? (string)(*itt)->name : (*itt)->getId(); 47 string lonid = string("lon_").append(domid);48 string latid = string("lat_").append(domid);47 string lonid = (sdom.size() == 1)? string("lon"): string("lon_").append(domid); 48 string latid = (sdom.size() == 1)? string("lat"): string("lat_").append(domid); 49 49 dims[lonid] = (*itt)->ni; 50 50 dims[latid] = (*itt)->nj; … … 129 129 130 130 Poco::HashMap<string, string> hm; 131 Poco::HashMap<string, float> hmf; 131 132 132 133 const std::set<const CDomain*> sdom = this->getRelFile()->getEnabledDomains(); … … 137 138 { 138 139 string domid = ((*itt)->name.hasValue()) ? (string)(*itt)->name : (*itt)->getId(); 139 string lonid = string("lon_").append(domid);140 string latid = string("lat_").append(domid);140 string lonid = (sdom.size() == 1)? string("lon"): string("lon_").append(domid); 141 string latid = (sdom.size() == 1)? string("lat"): string("lat_").append(domid); 141 142 142 143 if (!(latVar = dataFile->add_var(latid.c_str(), ncFloat, dataFile->get_dim(latid.c_str())))) … … 151 152 hm["units"] = "degrees_north"; 152 153 hm["long_name"] = "Latitude" ; 153 this->addStringAttributesToVar(latVar, hm); 154 hm["nav_model"] = domid ; 155 if ((*itt)->yvalue.hasValue()) 156 { 157 hmf["valid_min"] = ((Array<double, 1>)(*itt)->yvalue)(0); 158 hmf["valid_max"] = ((Array<double, 1>)(*itt)->yvalue)(((Array<double, 1>)(*itt)->yvalue).size()-1); 159 this->addStringAttributesToVar(latVar, hmf); 160 hmf.clear(); 161 } 162 this->addStringAttributesToVar_str(latVar, hm); 154 163 hm.clear(); 155 164 156 165 // Attribut de longitude. 157 hm["axis"] = "X" ; 158 hm["standard_name"] = "longitude" ; 159 hm["units"] = "degrees_east"; 160 hm["long_name"] = "Longitude" ; 161 this->addStringAttributesToVar(lonVar, hm); 166 hm["axis"] = "X" ; 167 hm["standard_name"] = "longitude" ; 168 hm["units"] = "degrees_east"; 169 hm["long_name"] = "Longitude" ; 170 hm["nav_model"] = domid ; 171 if ((*itt)->xvalue.hasValue()) 172 { 173 hmf["valid_min"] = ((Array<double, 1>)(*itt)->xvalue)(0); 174 hmf["valid_max"] = ((Array<double, 1>)(*itt)->xvalue)(((Array<double, 1>)(*itt)->xvalue).size()-1); 175 this->addStringAttributesToVar(lonVar, hmf); 176 hmf.clear(); 177 } 178 this->addStringAttributesToVar_str(lonVar, hm); 162 179 hm.clear(); 163 180 … … 179 196 throw XMLIOUndefinedValueException("Impossible d'ajouter la variable "+ (*it)->getId() +" !"); 180 197 181 hm["axis"] = "Z" ; 198 hm["axis"] = "Z" ; 199 hm["title"] = axisid ; 200 hm["positive"] = "unknown" ; 201 182 202 if ((*it)->standard_name.hasValue())hm["standard_name"] = (*it)->standard_name ; 183 203 if ((*it)->long_name.hasValue()) hm["long_name"] = (*it)->long_name ; 184 204 if ((*it)->unit.hasValue()) hm["units"] = (*it)->unit; 185 this->addStringAttributesToVar(othvar, hm); 205 if ((*it)->value.hasValue()) 206 { 207 hmf["valid_min"] = ((Array<double, 1>)(*it)->value)(0); 208 hmf["valid_max"] = ((Array<double, 1>)(*it)->value)(((Array<double, 1>)(*it)->value).size()-1); 209 this->addStringAttributesToVar(othvar, hmf); 210 hmf.clear(); 211 } 212 this->addStringAttributesToVar_str(othvar, hm); 186 213 hm.clear(); 187 214 … … 197 224 NcVar *var = NULL; 198 225 Poco::HashMap<string, string> hm; 226 Poco::HashMap<string, float> hmf; 199 227 bool lonlat = false, wtime = true; 200 228 const std::vector<CField*>& enabledFields = getRelFile()->getEnabledFields(); 229 const std::set<const CDomain*> sdom = this->getRelFile()->getEnabledDomains(); 201 230 202 231 std::vector<CField*>::const_iterator it; … … 204 233 for ( it = enabledFields.begin() ; it != enabledFields.end(); it++ ) 205 234 { 206 CField* field = (*it); 207 const CField* bfield = (*it)->getBaseObject(); 208 const CDomain* rdom = field->getGrid()->getRelDomain(); 209 const CAxis* raxis = field->getGrid()->getRelAxis(); 235 CField * field = (*it); 236 const CField * bfield = (*it)->getBaseObject(); 237 const CDomain * rdom = field->getGrid()->getRelDomain(); 238 const CAxis * raxis = field->getGrid()->getRelAxis(); 239 FieldOperation* fope = field->operation.getValue(); 240 Duration * ffope = field->freq_op.getValue(); 210 241 211 242 string fieldid = (field->name.hasValue()) ? (string)field->name : bfield->getId(); … … 213 244 string axisid = (raxis->name.hasValue()) ? (string)raxis->name : raxis ->getId(); 214 245 215 string lonid = string("lon_").append(domid); // Nom de la coordonnée longitudinale associée.216 string latid = string("lat_").append(domid); // Nom de la coordonnée latitudinale associée.246 string lonid = (sdom.size() == 1)? string("lon"): string("lon_").append(domid); // Nom de la coordonnée longitudinale associée. 247 string latid = (sdom.size() == 1)? string("lat"): string("lat_").append(domid); // Nom de la coordonnée latitudinale associée. 217 248 218 249 lonlat = !field->getGrid()->_hasAxis(); 219 250 220 if (field->operation.hasValue()) 251 252 ////////////////////////////////////// A DEPLACER 253 if (fope != NULL) 221 254 { // Si une opération sur le champ est définie ... 222 if (f ield->operation.getId().compare("once") == 0)255 if (fope->getId().compare("once") == 0) 223 256 { wtime = false; field->freq_op.setValue(NoneDu); } 224 257 } … … 231 264 // Si la fréquence d'opération n'est pas définie, on l'initialise à 0s. 232 265 // Une fréquence à 0s signifie que l'opération se fera à chaque écriture de données depuis la simulation. 233 if ( !field->freq_op.hasValue())266 if (ffope == NULL) 234 267 field->freq_op.setValue(NoneDu); 235 ((FieldOperation)field->operation).setFreqOp(Duration(field->freq_op)); 268 269 field->operation.getValue()->setFreqOp(field->freq_op); 270 ///////////////////////////////////////////// 236 271 237 272 tvar = ncFloat; … … 271 306 } 272 307 273 if (field->standard_name.hasValue())hm["standard_name"] = field->standard_name ; 274 if (field->long_name.hasValue()) hm["long_name"] = field->long_name ; 275 if (field->unit.hasValue()) hm["units"] = field->unit; 276 this->addStringAttributesToVar(var, hm); 308 if (field->standard_name.hasValue())hm["standard_name"] = field->standard_name ; 309 if (field->long_name.hasValue()) hm["long_name"] = field->long_name ; 310 if (field->unit.hasValue()) hm["units"] = field->unit; 311 312 if (field->operation.hasValue()) 313 { 314 hm["online_operation"] = field->operation.getValue()->getId(); 315 316 if (!field->operation.getValue()->getFreqOp().isNone()) 317 hm["interval_operation"] = field->operation.getValue()->getFreqOp().toString(); 318 else 319 hm["interval_operation"] = ((Duration)this->getRelFile()->output_freq).toString(); 320 } 321 hm["interval_write"] = ((Duration)this->getRelFile()->output_freq).toString(); 322 323 this->addStringAttributesToVar_str(var, hm); 277 324 hm.clear(); 278 325 } … … 281 328 private : 282 329 283 void addStringAttributesToVar(NcVar * const var, const Poco::HashMap<string, string>& attr) 330 template <class U> 331 void addStringAttributesToVar(NcVar * const var, const Poco::HashMap<string, U>& attr) 332 { 333 typename Poco::HashMap<string, U>::ConstIterator it; 334 335 for ( it = attr.begin() ; it != attr.end(); it++ ) 336 if (!var->add_att((*it).first.c_str(), (*it).second)) 337 throw XMLIOUndefinedValueException("Impossible d'ajouter l'attribut' "+ (*it).first +" à la variable "+ var->name() +" !"); 338 } 339 340 void addStringAttributesToVar_str(NcVar * const var, const Poco::HashMap<string, string>& attr) 284 341 { 285 342 Poco::HashMap<string, string>::ConstIterator it; -
XMLIO_V2/dev/dev_rv/src/XMLIO/attribut.hpp
r127 r128 64 64 virtual void setValue(const Ctype & value_) 65 65 { _hasValue = true ; value = value_ ;} 66 67 Ctype* getValue(void) 68 { if (!_hasValue) return(NULL); return (&value); } 66 69 67 70 virtual void getValue(Ctype & value_) const -
XMLIO_V2/dev/dev_rv/src/XMLIO/c_interface.cpp
r127 r128 67 67 } 68 68 69 std::cout << std::endl << " * ----------- Affichage de l'arborescence ----------- * " << std::endl << std::endl; 69 // Ecriture des avertissements obtenus jusqu'à présent. 70 std::cout << std::endl; ILogger::Flush(std::cout); 71 72 /*std::cout << " * ----------- Affichage de l'arborescence ----------- * " << std::endl << std::endl; 70 73 71 74 // On écrit l'arborescence résultante du traitement sur la sortie de log. 72 75 Context::ShowTree(std::clog); 73 std::cout << std::endl; 76 std::cout << std::endl;*/ 74 77 } 75 78 -
XMLIO_V2/dev/dev_rv/src/XMLIO/context.hpp
r126 r128 111 111 } 112 112 113 virtual void resolveDescInheritance(const AttributRegistrar* const _parent = 0)113 virtual void solveDescInheritance(const AttributRegistrar* const _parent = 0) 114 114 { 115 115 if (_parent != 0) return; 116 116 // Résolution des héritages descendants pour chacun des groupes de définitions. 117 if(fieldDef != NULL) fieldDef -> resolveDescInheritance();118 if(fileDef != NULL) fileDef -> resolveDescInheritance();119 if(axisDef != NULL) axisDef -> resolveDescInheritance();120 if(gridDef != NULL) gridDef -> resolveDescInheritance();121 if(domainDef != NULL) domainDef-> resolveDescInheritance();117 if(fieldDef != NULL) fieldDef ->solveDescInheritance(); 118 if(fileDef != NULL) fileDef ->solveDescInheritance(); 119 if(axisDef != NULL) axisDef ->solveDescInheritance(); 120 if(gridDef != NULL) gridDef ->solveDescInheritance(); 121 if(domainDef != NULL) domainDef->solveDescInheritance(); 122 122 } 123 123 … … 154 154 155 155 // Ne plus utiliser, disponible dans les classe treatment. 156 static void ResolveInheritance(void)156 static void SolveInheritance(void) 157 157 { 158 158 Poco::HashMap<string, StrHashMap<Context> > &AllListContext = Context::GetAllListObject(); … … 161 161 // Résolution des héritages descendants (cà d des héritages de groupes) pour chacun des contextes. 162 162 Context::SetCurrentContext((*it).first); 163 ((*it).second)[(*it).first]-> resolveDescInheritance();163 ((*it).second)[(*it).first]->solveDescInheritance(); 164 164 165 165 // Résolution des héritages par référence au niveau des fichiers. 166 166 const std::vector<CFile*>& allFiles = CFile::GetCurrentListObject().getVector(); 167 for (unsigned int i = 0; i < allFiles.size(); i++) allFiles[i]-> resolveFieldRefInheritance();167 for (unsigned int i = 0; i < allFiles.size(); i++) allFiles[i]->solveFieldRefInheritance(); 168 168 } 169 169 } -
XMLIO_V2/dev/dev_rv/src/XMLIO/data_treatment.hpp
r127 r128 81 81 void doTreatment(const AbstractCalendar& cal) 82 82 { 83 // Résolution des héritages pour le context actuel (Context:: ResolveInheritance() résoud les héritages pour tous les contextes).83 // Résolution des héritages pour le context actuel (Context::SolveInheritance() résoud les héritages pour tous les contextes). 84 84 //std::cout << "(Message temporaire) Résolution des héritages ..." << std::endl; 85 85 this->solveAllInheritance(); … … 119 119 { 120 120 // Résolution des héritages descendants (cà d des héritages de groupes) pour chacun des contextes. 121 currentContext-> resolveDescInheritance();121 currentContext->solveDescInheritance(); 122 122 123 123 // Résolution des héritages par référence au niveau des fichiers. 124 124 const std::vector<CFile*>& allFiles = CFile::GetCurrentListObject().getVector(); 125 for (unsigned int i = 0; i < allFiles.size(); i++) allFiles[i]-> resolveFieldRefInheritance();125 for (unsigned int i = 0; i < allFiles.size(); i++) allFiles[i]->solveFieldRefInheritance(); 126 126 } 127 127 -
XMLIO_V2/dev/dev_rv/src/XMLIO/declare_attribut.hpp
r127 r128 29 29 \ 30 30 void setAttr##att_name(const Attr_##att_name& _newattr) { att_name = _newattr; } \ 31 void set_##att_name 31 void set_##att_name (const Attr_##att_name& _newattr) { att_name = _newattr; }\ 32 32 \ 33 33 void setAttr##att_name(const att_type& _newattr) { att_name.setValue(_newattr); }\ -
XMLIO_V2/dev/dev_rv/src/XMLIO/duration.hpp
r123 r128 11 11 { 12 12 public : 13 14 struct _duration& operator=(const struct _duration& ddr) 15 { 16 year = ddr.year; month = ddr.month ; day = ddr.day; 17 hour = ddr.hour; minute = ddr.minute; second = ddr.second; 18 return (*this); 19 } 13 20 14 21 friend std::ostream& operator<<(std::ostream& out, const struct _duration& d) … … 58 65 } 59 66 67 bool isNone(void) const 68 { 69 if ((year==0) && (month ==0) && (day ==0) && 70 (hour==0) && (minute==0) && (second==0)) 71 return (true); 72 return (false); 73 } 74 75 struct _duration& resolve(const AbstractCalendar&); 76 77 std::string toString(void) const 78 { 79 const struct _duration& own = *this; 80 std::ostringstream oss; oss << own; return (oss.str()); 81 } 82 83 public: /* static */ 84 60 85 static struct _duration FromString(const string& str) 61 86 { … … 64 89 iss >> dr; return dr; 65 90 } 66 67 struct _duration& resolve(const AbstractCalendar&);68 91 69 92 double year, month, day, hour, minute, second; -
XMLIO_V2/dev/dev_rv/src/XMLIO/field.hpp
r125 r128 18 18 CField(const string& _id) : ObjectTemplate<CField>(_id), FieldAttribut(), lastStored(NULL), grid(NULL), file(NULL) 19 19 {/* Ne rien faire de plus */} 20 21 static string GetName(void) { return ("field"); }22 static string GetDefName(void) { return (CField::GetName()); }23 20 24 21 inline void solveGridRef(void) ; … … 48 45 void setRelFile(CFile* _file) { file = _file; } 49 46 47 public: /* virtual */ 48 50 49 virtual CField* getReference(void) const 51 50 { … … 59 58 virtual ~CField(void) 60 59 { if(lastStored != NULL) delete lastStored; } 60 61 public: /* static */ 62 63 static string GetName(void) { return ("field"); } 64 static string GetDefName(void) { return (CField::GetName()); } 61 65 62 66 private : … … 75 79 DECLARE_GROUP(Field) 76 80 81 /* Pour la gestion des références aux groupes de champs */ 82 namespace XMLIOSERVER 83 { 84 template <> 85 CField& GroupTemplate<CField, FieldAttribut>::createChildRef(const CField* const _ori) 86 { 87 if (!_ori->hasId()) 88 throw (new XMLIOUndefinedValueException("Impossible de créer une référence à un élément sans identifiant !")); 89 90 CField& obj = *ObjectTemplate<CField>::CreateObject(); 91 obj.field_ref = _ori->getId(); 92 childList.addObject(&obj); 93 return (obj); 94 } 95 96 template <> 97 void GroupTemplate<CField, FieldAttribut>::solveRefInheritance (void) 98 { 99 std::vector<CField*> _allf ; 100 101 if(!group_ref.hasValue() || (GetName().compare("field_group") != 0)) return; 102 if (!GroupTemplate<CField, FieldAttribut>::HasObject(group_ref)) 103 { WARNING("Référence invalide sur l'objet "+GetName()+" nommé \""+((string)group_ref)+"\""); return; } 104 105 const GroupTemplate<CField, FieldAttribut>* const gref 106 = GroupTemplate<CField, FieldAttribut>::GetObject(group_ref); 107 108 gref->getAllChildren(_allf); 109 std::vector<CField*>::iterator it ; 110 for ( it = _allf.begin() ; it != _allf.end(); it++ ) 111 this->createChildRef(*it); 112 } 113 114 115 } // namespace XMLIOSERVER 116 77 117 #endif // __FIELD__ -
XMLIO_V2/dev/dev_rv/src/XMLIO/file.hpp
r127 r128 77 77 } 78 78 79 void resolveFieldRefInheritance(void)79 void solveFieldRefInheritance(void) 80 80 { // Résolution des héritages par référence de chacun des champs contenus dans le fichier. 81 81 std::vector<CField*> allF; this->getAllFields(allF); 82 for (unsigned int i = 0; i < allF.size(); i++) allF[i]-> resolveRefInheritance();82 for (unsigned int i = 0; i < allF.size(); i++) allF[i]->solveRefInheritance(); 83 83 } 84 84 … … 153 153 virtual void printChild(ostream& out) const { out << *vfieldGroup << std::endl; } 154 154 155 virtual void resolveDescInheritance(const AttributRegistrar* const _parent = 0)156 { addAttributes(*_parent); if(vfieldGroup != NULL) vfieldGroup-> resolveDescInheritance(); }155 virtual void solveDescInheritance(const AttributRegistrar* const _parent = 0) 156 { addAttributes(*_parent); if(vfieldGroup != NULL) vfieldGroup->solveDescInheritance(); } 157 157 158 158 virtual ~CFile(void) -
XMLIO_V2/dev/dev_rv/src/XMLIO/group_template.hpp
r127 r128 5 5 { 6 6 template <class T, class U> 7 class GroupTemplate : public ObjectTemplate<GroupTemplate<T, U> >, public U7 class GroupTemplate : public ObjectTemplate<GroupTemplate<T, U> >, public virtual U 8 8 { 9 9 public: 10 10 11 DECLARE_ATTR(group_ref, string) ; // Attribut présent uniqument dans les groupes. 12 11 13 GroupTemplate(void) 12 : ObjectTemplate<GroupTemplate<T, U> >() , U(), childList(), groupList()13 { /* Ne rien faire de plus */}14 : ObjectTemplate<GroupTemplate<T, U> >()/*, U()*/, childList(), groupList() 15 { RegisterAttribut(&group_ref) ; } 14 16 15 17 GroupTemplate(const string& _id) 16 : ObjectTemplate<GroupTemplate<T, U> >(_id) , U(), childList(), groupList()17 { /* Ne rien faire de plus */}18 : ObjectTemplate<GroupTemplate<T, U> >(_id)/*, U()*/, childList(), groupList() 19 { RegisterAttribut(&group_ref) ; } 18 20 19 21 /// Pour les groupes d'objets enfants /// … … 62 64 return (obj); 63 65 } 66 67 T& createChildRef(const T* const _ori) 68 { return (*_ori); } 64 69 65 70 T& getChild(const string& _id) const … … 97 102 delete groupList.getVector()[i]; 98 103 } 104 105 virtual void solveRefInheritance (void) 106 { /* Ne rien faire de plus */ } 99 107 100 108 virtual bool hasChild(void) const { return ((getNbGroup() + getNbChild())>0); } … … 109 117 } 110 118 111 virtual void resolveDescInheritance(const AttributRegistrar* const _parent = 0)119 virtual void solveDescInheritance(const AttributRegistrar* const _parent = 0) 112 120 { 113 121 const vector<T*>& childvect = childList.getVector(); … … 119 127 for(unsigned int i = 0; i < childvect.size() ; i++) 120 128 // on complÚte les attributs des enfants. 121 childvect[i] -> resolveDescInheritance(this);129 childvect[i] -> solveDescInheritance(this); 122 130 123 131 for(unsigned int i = 0; i < groupvect.size() ; i++) 124 // on complÚte les attributs des groupes enfants. 125 groupvect[i] -> resolveDescInheritance(this); 132 { // on complÚte les attributs des groupes enfants. 133 groupvect[i] -> solveRefInheritance (); 134 groupvect[i] -> solveDescInheritance(this); 135 } 126 136 } 127 137 … … 144 154 _parse<W> (_node_inc); 145 155 } 156 146 157 attributes.clear(); 147 158 } -
XMLIO_V2/dev/dev_rv/src/XMLIO/logger.hpp
r122 r128 18 18 private : 19 19 20 ILogger( )20 ILogger(void) 21 21 { signal(SIGSEGV, SigHandler); } 22 23 private : /* static */ 22 24 23 25 static ILogger LOGGER; 24 26 25 public : 27 public : /* static */ 26 28 27 29 static ILogger& GetLogger(void) { return (ILogger::LOGGER); } 30 31 static void Flush(std::ostream& out = std::clog) 32 { ILogger::GetLogger().flush(out); } 28 33 29 34 static void ShowBTrace(std::ostream& out = std::clog) … … 63 68 } 64 69 65 ~ILogger(void) 66 { std::cout << str() << std::endl; } 70 public : 71 72 void flush(std::ostream& out = std::clog) 73 { out << str() << std::endl; str(""); } 74 75 ~ILogger(void) { this->flush(); } 67 76 68 77 }; // class XMLIOLogger … … 84 93 85 94 std::ostream& IncIndent(std::ostream& out) { Indent++; return (NIndent(out)); } 86 std::ostream& DecEndl (std::ostream& out) { Indent--; return (out); }95 std::ostream& DecEndl (std::ostream& out) { Indent--; return (out); } 87 96 ///////////////////////////////////////////////////////////////////// 88 97 89 98 } // namespace XMLIOSERVER 90 99 91 #define ERROR(MSG) (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": error : " << MSG << std::endl) 92 #define WARNING(MSG) (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": warning : " << MSG << std::endl) 93 #define INFO(MSG) (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": info : " << MSG << std::endl) 100 #define ERROR(MSG)\ 101 (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": error : " << MSG << std::endl) 102 #define WARNING(MSG)\ 103 (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": warning : " << MSG << std::endl) 104 #define INFO(MSG)\ 105 (ILogger::GetLogger() << __FILE__ << ":" << __LINE__ << ": info : " << MSG << std::endl) 94 106 // A compléter. 95 107 -
XMLIO_V2/dev/dev_rv/src/XMLIO/object_template.hpp
r126 r128 81 81 { out << NIndent << "<!-- No child -->" << std::endl; } 82 82 83 virtual void resolveDescInheritance(const AttributRegistrar* _parent = 0)83 virtual void solveDescInheritance(const AttributRegistrar* _parent = 0) 84 84 { this->addAttributes(*_parent); } 85 85 86 virtual void resolveRefInheritance (void)86 virtual void solveRefInheritance (void) 87 87 { 88 88 std::set<T*> sset; -
XMLIO_V2/dev/dev_rv/src/XMLIO/xmlio.hpp
r127 r128 67 67 #include "file_attribut.hpp" 68 68 69 #undef DECLARE_ATTR70 71 69 #include "group_template.hpp" 72 70 #include "declare_group.hpp" … … 79 77 #include "file.hpp" 80 78 79 #undef DECLARE_ATTR 81 80 #undef DECLARE_GROUP 82 81
Note: See TracChangeset
for help on using the changeset viewer.