NetCDF-C++ 4.3.1
ncGroup.cpp
1#include "ncGroup.h"
2#include "ncVar.h"
3#include "ncDim.h"
4#include "ncVlenType.h"
5#include "ncCompoundType.h"
6#include "ncOpaqueType.h"
7#include "ncGroupAtt.h"
8#include "ncByte.h"
9#include "ncUbyte.h"
10#include "ncChar.h"
11#include "ncShort.h"
12#include "ncUshort.h"
13#include "ncInt.h"
14#include "ncUint.h"
15#include "ncInt64.h"
16#include "ncUint64.h"
17#include "ncFloat.h"
18#include "ncDouble.h"
19#include "ncString.h"
20#include <ncException.h>
21#include "ncCheck.h"
22using namespace std;
23using namespace netCDF::exceptions;
24
25namespace netCDF {
26 // Global comparator operator ==============
27 // comparator operator
28 bool operator<(const NcGroup& lhs,const NcGroup& rhs)
29 {
30 return false;
31 }
32
33 // comparator operator
34 bool operator>(const NcGroup& lhs,const NcGroup& rhs)
35 {
36 return true;
37 }
38}
39
40using namespace netCDF;
41
43
44NcGroup::~NcGroup()
45{
46}
47
48// Constructor generates a null object.
50 nullObject(true),
51 myId(-1)
52{}
53
54
55// constructor
56NcGroup::NcGroup(const int groupId) :
57 nullObject(false),
58 myId(groupId)
59{ }
60
61// assignment operator
63{
65 myId = rhs.myId;
66 return *this;
67}
68
69// The copy constructor.
71 nullObject(rhs.nullObject),
72 myId(rhs.myId)
73{}
74
75
76// equivalence operator
77bool NcGroup::operator==(const NcGroup & rhs) const
78{
79 if(nullObject)
80 return nullObject == rhs.nullObject;
81 else
82 return myId == rhs.myId;
83}
84
85// != operator
86bool NcGroup::operator!=(const NcGroup & rhs) const
87{
88 return !(*this == rhs);
89}
90
91
92// /////////////
93// NcGroup-related methods
94// /////////////
95
96// Get the group name.
97string NcGroup::getName(bool fullName) const {
98 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getName on a Null group",__FILE__,__LINE__);
99 string groupName;
100 if(fullName){
101 // return full name of group with foward "/" separarating sub-groups.
102 size_t lenp;
103 ncCheck(nc_inq_grpname_len(myId,&lenp),__FILE__,__LINE__);
104 char* charName= new char[lenp+1];
105 ncCheck(nc_inq_grpname_full(myId,&lenp,charName),__FILE__,__LINE__);
106 groupName = charName;
107 delete charName;
108 }
109 else {
110 // return the (local) name of this group.
111 char charName[NC_MAX_NAME+1];
112 ncCheck(nc_inq_grpname(myId,charName),__FILE__,__LINE__);
113 groupName = charName;
114 }
115 return groupName;
116}
117
118// returns true if this is the root group.
120 bool result = getName() == "/";
121 return result;
122}
123
124// Get the parent group.
126 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getParentGroup on a Null group",__FILE__,__LINE__);
127 try {
128 int parentId;
129 ncCheck(nc_inq_grp_parent(myId,&parentId),__FILE__,__LINE__);
130 NcGroup ncGroupParent(parentId);
131 return ncGroupParent;
132 }
133 catch (NcEnoGrp& e) {
134 // no group found, so return null group
135 return NcGroup();
136 }
137}
138
139
140// Get the group id.
141int NcGroup::getId() const {
142 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getId on a Null group",__FILE__,__LINE__);
143 return myId;
144}
145
146// Get the number of NcGroup objects.
148 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getGroupCount on a Null group",__FILE__,__LINE__);
149 // initialize group counter
150 int ngroups=0;
151
152 // record this group
153 if(location == ParentsAndCurrentGrps || location == AllGrps) {
154 ngroups ++;
155 }
156
157 // number of children in current group
158 if(location == ChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
159 int numgrps;
160 int* ncids=NULL;
161 ncCheck(nc_inq_grps(getId(), &numgrps,ncids),__FILE__,__LINE__);
162 ngroups += numgrps;
163 }
164
165 // search in parent groups
166 if(location == ParentsGrps || location == ParentsAndCurrentGrps || location == AllGrps ) {
167 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
168 ngroups += groups.size();
169 }
170
171
172 // get the number of all children that are childreof children
173 if(location == ChildrenOfChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
174 multimap<string,NcGroup> groups(getGroups(ChildrenOfChildrenGrps));
175 ngroups += groups.size();
176 }
177
178 return ngroups;
179}
180
181
182// Get the set of child NcGroup objects.
183multimap<std::string,NcGroup> NcGroup::getGroups(NcGroup::GroupLocation location) const {
184 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getGroups on a Null group",__FILE__,__LINE__);
185 // create a container to hold the NcGroup's.
186 multimap<string,NcGroup> ncGroups;
187
188 // record this group
189 if(location == ParentsAndCurrentGrps || location == AllGrps) {
190 ncGroups.insert(pair<const string,NcGroup>(getName(),*this));
191 }
192
193 // the child groups of the current group
194 if(location == ChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
195 // get the number of groups
196 int groupCount = getGroupCount();
197 if (groupCount){
198 vector<int> ncids(groupCount);
199 int* numgrps=NULL;
200 // now get the id of each NcGroup and populate the ncGroups container.
201 ncCheck(nc_inq_grps(myId, numgrps,&ncids[0]),__FILE__,__LINE__);
202 for(int i=0; i<groupCount;i++){
203 NcGroup tmpGroup(ncids[i]);
204 ncGroups.insert(pair<const string,NcGroup>(tmpGroup.getName(),tmpGroup));
205 }
206 }
207 }
208
209 // search in parent groups.
210 if(location == ParentsGrps || location == ParentsAndCurrentGrps || location == AllGrps ) {
211 NcGroup tmpGroup(*this);
212 if(!tmpGroup.isRootGroup()) {
213 while(1) {
214 const NcGroup parentGroup(tmpGroup.getParentGroup());
215 if(parentGroup.isNull()) break;
216 ncGroups.insert(pair<const string,NcGroup>(parentGroup.getName(),parentGroup));
217 tmpGroup=parentGroup;
218 }
219 }
220 }
221
222 // search in child groups of the children
223 if(location == ChildrenOfChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
224 multimap<string,NcGroup>::iterator it;
225 multimap<string,NcGroup> groups(getGroups(ChildrenGrps));
226 for (it=groups.begin();it!=groups.end();it++) {
227 multimap<string,NcGroup> childGroups(it->second.getGroups(AllChildrenGrps));
228 ncGroups.insert(childGroups.begin(),childGroups.end());
229 }
230 }
231
232 return ncGroups;
233}
234
235// Get the named child NcGroup object.
236NcGroup NcGroup::getGroup(const string& name,NcGroup::GroupLocation location) const{
237 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getGroup on a Null group",__FILE__,__LINE__);
238 multimap<string,NcGroup> ncGroups(getGroups(location));
239 pair<multimap<string,NcGroup>::iterator,multimap<string,NcGroup>::iterator> ret;
240 ret = ncGroups.equal_range(name);
241 if(ret.first == ret.second)
242 return NcGroup(); // null group is returned
243 else
244 return ret.first->second;
245}
246
247
248
249// Get all NcGroup objects with a given name.
250set<NcGroup> NcGroup::getGroups(const std::string& name,NcGroup::GroupLocation location) const {
251 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getGroups on a Null group",__FILE__,__LINE__);
252 // get the set of ncGroups in this group and above.
253 multimap<std::string,NcGroup> ncGroups(getGroups(location));
254 pair<multimap<string,NcGroup>::iterator,multimap<string,NcGroup>::iterator> ret;
255 multimap<string,NcGroup>::iterator it;
256 ret = ncGroups.equal_range(name);
257 set<NcGroup> tmpGroup;
258 for (it=ret.first; it!=ret.second; ++it) {
259 tmpGroup.insert(it->second);
260 }
261 return tmpGroup;
262}
263
264// Add a new child NcGroup object.
265NcGroup NcGroup::addGroup(const string& name) const {
266 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::addGroup on a Null group",__FILE__,__LINE__);
267 int new_ncid;
268 ncCheck(nc_def_grp(myId,const_cast<char*> (name.c_str()),&new_ncid),__FILE__,__LINE__);
269 return NcGroup(new_ncid);
270}
271
272
273
274// /////////////
275// NcVar-related accessors
276// /////////////
277
278// Get the number of NcVar objects in this group.
280
281 // search in current group.
282 NcGroup tmpGroup(*this);
283 int nvars=0;
284 // search in current group
285 if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
286 ncCheck(nc_inq_nvars(tmpGroup.getId(), &nvars),__FILE__,__LINE__);
287 }
288
289 // search recursively in all parent groups.
290 if(location == Parents || location == ParentsAndCurrent || location ==All) {
291 tmpGroup=getParentGroup();
292 while(!tmpGroup.isNull()) {
293 int nvarsp;
294 ncCheck(nc_inq_nvars(tmpGroup.getId(), &nvarsp),__FILE__,__LINE__);
295 nvars += nvarsp;
296 // continue loop with the parent.
297 tmpGroup=tmpGroup.getParentGroup();
298 }
299 }
300
301 // search recursively in all child groups
302 if(location == ChildrenAndCurrent || location == Children || location == All) {
303 multimap<string,NcGroup>::iterator it;
304 multimap<string,NcGroup> groups(getGroups());
305 for (it=groups.begin();it!=groups.end();it++) {
306 nvars += it->second.getVarCount(ChildrenAndCurrent);
307 }
308 }
309 return nvars;
310}
311
312// Get the collection of NcVar objects.
313multimap<std::string,NcVar> NcGroup::getVars(NcGroup::Location location) const {
314
315 // create a container to hold the NcVar's.
316 multimap<string,NcVar> ncVars;
317
318 // search in current group.
319 NcGroup tmpGroup(*this);
320 if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
321 // get the number of variables.
322 int varCount = getVarCount();
323 if (varCount){
324 // now get the name of each NcVar object and populate the ncVars container.
325 int* nvars=NULL;
326 vector<int> varids(varCount);
327 ncCheck(nc_inq_varids(myId, nvars,&varids[0]),__FILE__,__LINE__);
328 for(int i=0; i<varCount;i++){
329 NcVar tmpVar(*this,varids[i]);
330 ncVars.insert(pair<const string,NcVar>(tmpVar.getName(),tmpVar));
331 }
332 }
333 }
334
335
336 // search recursively in all parent groups.
337 if(location == Parents || location == ParentsAndCurrent || location ==All) {
338 tmpGroup=getParentGroup();
339 while(!tmpGroup.isNull()) {
340 // get the number of variables
341 int varCount = tmpGroup.getVarCount();
342 if (varCount){
343 // now get the name of each NcVar object and populate the ncVars container.
344 int* nvars=NULL;
345 vector<int> varids(varCount);
346 ncCheck(nc_inq_varids(tmpGroup.getId(), nvars,&varids[0]),__FILE__,__LINE__);
347 for(int i=0; i<varCount;i++){
348 NcVar tmpVar(tmpGroup,varids[i]);
349 ncVars.insert(pair<const string,NcVar>(tmpVar.getName(),tmpVar));
350 }
351 }
352 // continue loop with the parent.
353 tmpGroup=tmpGroup.getParentGroup();
354 }
355 }
356
357 // search recusively in all child groups.
358 if(location == ChildrenAndCurrent || location == Children || location == All ) {
359 multimap<string,NcGroup>::iterator it;
360 multimap<string,NcGroup> groups(getGroups());
361 for (it=groups.begin();it!=groups.end();it++) {
362 multimap<string,NcVar> vars=it->second.getVars(ChildrenAndCurrent);
363 ncVars.insert(vars.begin(),vars.end());
364 }
365 }
366
367 return ncVars;
368}
369
370
371// Get all NcVar objects with a given name.
372set<NcVar> NcGroup::getVars(const string& name,NcGroup::Location location) const {
373 // get the set of ncVars in this group and above.
374 multimap<std::string,NcVar> ncVars(getVars(location));
375 pair<multimap<string,NcVar>::iterator,multimap<string,NcVar>::iterator> ret;
376 multimap<string,NcVar>::iterator it;
377 ret = ncVars.equal_range(name);
378 set<NcVar> tmpVar;
379 for (it=ret.first; it!=ret.second; ++it) {
380 tmpVar.insert(it->second);
381 }
382 return tmpVar;
383}
384
385
386
387// Get the named NcVar object.
388NcVar NcGroup::getVar(const string& name,NcGroup::Location location) const {
389 multimap<std::string,NcVar> ncVars(getVars(location));
390 pair<multimap<string,NcVar>::iterator,multimap<string,NcVar>::iterator> ret;
391 ret = ncVars.equal_range(name);
392 if(ret.first == ret.second)
393 // no matching netCDF variable found so return null object.
394 return NcVar();
395 else
396 return ret.first->second;
397}
398
399// Adds a new netCDF scalar variable.
400NcVar NcGroup::addVar(const std::string& name, const NcType& ncType) const {
401 return NcGroup::addVar(name, ncType, std::vector<NcDim>());
402}
403
404// Add a new netCDF variable.
405NcVar NcGroup::addVar(const string& name, const string& typeName, const string& dimName) const {
406 ncCheckDefineMode(myId);
407
408 // get an NcType object with the given type name.
409 NcType tmpType(getType(typeName,NcGroup::ParentsAndCurrent));
410 if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar failed: typeName must be defined in either the current group or a parent group",__FILE__,__LINE__);
411
412 // get a NcDim object with the given dimension name
413 NcDim tmpDim(getDim(dimName,NcGroup::ParentsAndCurrent));
414 if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar failed: dimName must be defined in either the current group or a parent group",__FILE__,__LINE__);
415
416 // finally define a new netCDF variable
417 int varId;
418 int dimId(tmpDim.getId());
419 ncCheck(nc_def_var(myId,name.c_str(),tmpType.getId(),1,&dimId,&varId),__FILE__,__LINE__);
420 // return an NcVar object for this new variable
421 return NcVar(*this,varId);
422}
423
424
425// Add a new netCDF variable.
426NcVar NcGroup::addVar(const string& name, const NcType& ncType, const NcDim& ncDim) const {
427 ncCheckDefineMode(myId);
428
429 // check NcType object is valid
430 if(ncType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar with a Null NcType object",__FILE__,__LINE__);
432 if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar failed: NcType must be defined in either the current group or a parent group",__FILE__,__LINE__);
433
434 // check NcDim object is valid
435 if(ncDim.isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar with a Null NcDim object",__FILE__,__LINE__);
437 if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar failed: NcDim must be defined in either the current group or a parent group",__FILE__,__LINE__);
438
439 // finally define a new netCDF variable
440 int varId;
441 int dimId(tmpDim.getId());
442 ncCheck(nc_def_var(myId,name.c_str(),tmpType.getId(),1,&dimId,&varId),__FILE__,__LINE__);
443 // return an NcVar object for this new variable
444 return NcVar(*this,varId);
445}
446
447
448// Add a new netCDF multi-dimensional variable.
449NcVar NcGroup::addVar(const string& name, const string& typeName, const vector<string>& dimNames) const {
450 ncCheckDefineMode(myId);
451
452 // get an NcType object with the given name.
453 NcType tmpType(getType(typeName,NcGroup::ParentsAndCurrent));
454 if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar failed: typeName must be defined in either the current group or a parent group",__FILE__,__LINE__);
455
456 // get a set of NcDim objects corresponding to the given dimension names.
457 vector<int> dimIds;
458 dimIds.reserve(dimNames.size());
459 for (size_t i=0; i<dimNames.size();i++){
460 NcDim tmpDim(getDim(dimNames[i],NcGroup::ParentsAndCurrent));
461 if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar failed: dimNames must be defined in either the current group or a parent group",__FILE__,__LINE__);
462 dimIds.push_back(tmpDim.getId());
463 }
464
465 // finally define a new netCDF variable
466 int varId;
467 int *dimIdsPtr = dimIds.empty() ? 0 : &dimIds[0];
468 ncCheck(nc_def_var(myId,name.c_str(),tmpType.getId(),dimIds.size(), dimIdsPtr,&varId),__FILE__,__LINE__);
469 // return an NcVar object for this new variable
470 return NcVar(*this,varId);
471}
472
473// Add a new netCDF multi-dimensional variable.
474NcVar NcGroup::addVar(const string& name, const NcType& ncType, const vector<NcDim>& ncDimVector) const {
475 ncCheckDefineMode(myId);
476
477 // check NcType object is valid
478 if(ncType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar with a Null NcType object",__FILE__,__LINE__);
480 if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcGroup::addVar failed: NcType must be defined in either the current group or a parent group",__FILE__,__LINE__);
481
482 // check NcDim objects are valid
483 vector<NcDim>::const_iterator iter;
484 vector<int> dimIds;
485 dimIds.reserve(ncDimVector.size());
486 for (iter=ncDimVector.begin();iter < ncDimVector.end(); iter++) {
487 if(iter->isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar with a Null NcDim object",__FILE__,__LINE__);
488 NcDim tmpDim(getDim(iter->getName(),NcGroup::ParentsAndCurrent));
489 if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcGroup::addVar failed: NcDim must be defined in either the current group or a parent group",__FILE__,__LINE__);
490 dimIds.push_back(tmpDim.getId());
491 }
492
493 // finally define a new netCDF variable
494 int varId;
495 int *dimIdsPtr = dimIds.empty() ? 0 : &dimIds[0];
496 ncCheck(nc_def_var(myId,name.c_str(),tmpType.getId(),dimIds.size(), dimIdsPtr,&varId),__FILE__,__LINE__);
497 // return an NcVar object for this new variable
498 return NcVar(*this,varId);
499}
500
501
502// /////////////
503// NcAtt-related methods
504// /////////////
505
506// Get the number of group attributes.
508
509 // search in current group.
510 NcGroup tmpGroup(*this);
511 int ngatts=0;
512 // search in current group
513 if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
514 ncCheck(nc_inq_natts(tmpGroup.getId(), &ngatts),__FILE__,__LINE__);
515 }
516
517 // search recursively in all parent groups.
518 if(location == Parents || location == ParentsAndCurrent || location ==All) {
519 tmpGroup=getParentGroup();
520 while(!tmpGroup.isNull()) {
521 int ngattsp;
522 ncCheck(nc_inq_natts(tmpGroup.getId(), &ngattsp),__FILE__,__LINE__);
523 ngatts += ngattsp;
524 // continue loop with the parent.
525 tmpGroup=tmpGroup.getParentGroup();
526 }
527 }
528
529 // search recursively in all child groups
530 if(location == ChildrenAndCurrent || location == Children || location == All) {
531 multimap<string,NcGroup>::iterator it;
532 multimap<string,NcGroup> groups(getGroups());
533 for (it=groups.begin();it!=groups.end();it++) {
534 ngatts += it->second.getAttCount(ChildrenAndCurrent);
535 }
536 }
537
538 return ngatts;
539}
540
541// Get the collection of NcGroupAtt objects.
542multimap<std::string,NcGroupAtt> NcGroup::getAtts(NcGroup::Location location) const {
543
544 // create a container to hold the NcAtt's.
545 multimap<string,NcGroupAtt> ncAtts;
546
547 // search in current group.
548 NcGroup tmpGroup(*this);
549 if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
550 // get the number of attributes
551 int attCount = tmpGroup.getAttCount();
552 // now get the name of each NcAtt and populate the ncAtts container.
553 for(int i=0; i<attCount;i++){
554 char charName[NC_MAX_NAME+1];
555 ncCheck(nc_inq_attname(tmpGroup.getId(),NC_GLOBAL,i,charName),__FILE__,__LINE__);
556 NcGroupAtt tmpAtt(tmpGroup.getId(),i);
557 ncAtts.insert(pair<const string,NcGroupAtt>(string(charName),tmpAtt));
558 }
559 }
560
561 // search recursively in all parent groups.
562 if(location == Parents || location == ParentsAndCurrent || location ==All) {
563 tmpGroup=getParentGroup();
564 while(!tmpGroup.isNull()) {
565 // get the number of attributes
566 int attCount = tmpGroup.getAttCount();
567 // now get the name of each NcAtt and populate the ncAtts container.
568 for(int i=0; i<attCount;i++){
569 char charName[NC_MAX_NAME+1];
570 ncCheck(nc_inq_attname(tmpGroup.getId(),NC_GLOBAL,i,charName),__FILE__,__LINE__);
571 NcGroupAtt tmpAtt(tmpGroup.getId(),i);
572 ncAtts.insert(pair<const string,NcGroupAtt>(string(charName),tmpAtt));
573 }
574 // continue loop with the parent.
575 tmpGroup=tmpGroup.getParentGroup();
576 }
577 }
578
579 // search recusively in all child groups.
580 if(location == ChildrenAndCurrent || location == Children || location == All ) {
581 multimap<string,NcGroup>::iterator it;
582 multimap<string,NcGroup> groups(getGroups());
583 for (it=groups.begin();it!=groups.end();it++) {
584 multimap<string,NcGroupAtt> atts=it->second.getAtts(ChildrenAndCurrent);
585 ncAtts.insert(atts.begin(),atts.end());
586 }
587 }
588
589 return ncAtts;
590}
591
592// Get the named NcGroupAtt object.
593NcGroupAtt NcGroup::getAtt(const std::string& name,NcGroup::Location location) const {
594 multimap<std::string,NcGroupAtt> ncAtts(getAtts(location));
595 pair<multimap<string,NcGroupAtt>::iterator,multimap<string,NcGroupAtt>::iterator> ret;
596 ret = ncAtts.equal_range(name);
597 if(ret.first == ret.second)
598 // no matching groupAttribute so return null object.
599 return NcGroupAtt();
600 else
601 return ret.first->second;
602}
603
604// Get all NcGroupAtt objects with a given name.
605set<NcGroupAtt> NcGroup::getAtts(const string& name,NcGroup::Location location) const {
606 // get the set of ncGroupAtts in this group and above.
607 multimap<std::string,NcGroupAtt> ncAtts(getAtts(location));
608 pair<multimap<string,NcGroupAtt>::iterator,multimap<string,NcGroupAtt>::iterator> ret;
609 multimap<string,NcGroupAtt>::iterator it;
610 ret = ncAtts.equal_range(name);
611 set<NcGroupAtt> tmpAtt;
612 for (it=ret.first; it!=ret.second; ++it) {
613 tmpAtt.insert(it->second);
614 }
615 return tmpAtt;
616}
617
618
619
620
621// Creates a new NetCDF group attribute or if already exisiting replaces it.
622NcGroupAtt NcGroup::putAtt(const string& name, const string& dataValues) const {
623 ncCheckDefineMode(myId);
624 ncCheck(nc_put_att_text(myId,NC_GLOBAL,name.c_str(),dataValues.size(),dataValues.c_str()),__FILE__,__LINE__);
625 // finally instantiate this attribute and return
626 return getAtt(name);
627}
628
629// Creates a new NetCDF group attribute or if already exisiting replaces it.
630NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const unsigned char* dataValues) const {
631 ncCheckDefineMode(myId);
632 NcType::ncType typeClass(type.getTypeClass());
633 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
634 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
635 else
636 ncCheck(nc_put_att_uchar(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
637 // finally instantiate this attribute and return
638 return getAtt(name);
639}
640
641
642// Creates a new NetCDF group attribute or if already exisiting replaces it.
643NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const signed char* dataValues) const {
644 ncCheckDefineMode(myId);
645 NcType::ncType typeClass(type.getTypeClass());
646 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
647 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
648 else
649 ncCheck(nc_put_att_schar(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
650 // finally instantiate this attribute and return
651 return getAtt(name);
652}
653
654
655// Creates a new NetCDF group attribute or if already exisiting replaces it.
656NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, short datumValue) const {
657 ncCheckDefineMode(myId);
658 NcType::ncType typeClass(type.getTypeClass());
659 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
660 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
661 else
662 ncCheck(nc_put_att_short(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
663 // finally instantiate this attribute and return
664 return getAtt(name);
665}
666
667
668// Creates a new NetCDF group attribute or if already exisiting replaces it.
669NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, int datumValue) const {
670 ncCheckDefineMode(myId);
671 NcType::ncType typeClass(type.getTypeClass());
672 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
673 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
674 else
675 ncCheck(nc_put_att_int(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
676 // finally instantiate this attribute and return
677 return getAtt(name);
678}
679
680// Creates a new NetCDF group attribute or if already exisiting replaces it.
681NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, long datumValue) const {
682 ncCheckDefineMode(myId);
683 NcType::ncType typeClass(type.getTypeClass());
684 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
685 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
686 else
687 ncCheck(nc_put_att_long(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
688 // finally instantiate this attribute and return
689 return getAtt(name);
690}
691
692// Creates a new NetCDF group attribute or if already exisiting replaces it.
693NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, float datumValue) const {
694 ncCheckDefineMode(myId);
695 NcType::ncType typeClass(type.getTypeClass());
696 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
697 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
698 else
699 ncCheck(nc_put_att_float(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
700 // finally instantiate this attribute and return
701 return getAtt(name);
702}
703
704
705// Creates a new NetCDF group attribute or if already exisiting replaces it.
706NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, double datumValue) const {
707 ncCheckDefineMode(myId);
708 NcType::ncType typeClass(type.getTypeClass());
709 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
710 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
711 else
712 ncCheck(nc_put_att_double(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
713 // finally instantiate this attribute and return
714 return getAtt(name);
715}
716
717
718// Creates a new NetCDF group attribute or if already exisiting replaces it.
719NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, unsigned short datumValue) const {
720 ncCheckDefineMode(myId);
721 NcType::ncType typeClass(type.getTypeClass());
722 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
723 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
724 else
725 ncCheck(nc_put_att_ushort(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
726 // finally instantiate this attribute and return
727 return getAtt(name);
728}
729
730// Creates a new NetCDF group attribute or if already exisiting replaces it.
731NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, unsigned int datumValue) const {
732 ncCheckDefineMode(myId);
733 NcType::ncType typeClass(type.getTypeClass());
734 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
735 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
736 else
737 ncCheck(nc_put_att_uint(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
738 // finally instantiate this attribute and return
739 return getAtt(name);
740}
741
742// Creates a new NetCDF group attribute or if already exisiting replaces it.
743NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, long long datumValue) const {
744 ncCheckDefineMode(myId);
745 NcType::ncType typeClass(type.getTypeClass());
746 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
747 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
748 else
749 ncCheck(nc_put_att_longlong(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
750 // finally instantiate this attribute and return
751 return getAtt(name);
752}
753
754
755// Creates a new NetCDF group attribute or if already exisiting replaces it.
756NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, unsigned long long datumValue) const {
757 ncCheckDefineMode(myId);
758 NcType::ncType typeClass(type.getTypeClass());
759 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
760 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
761 else
762 ncCheck(nc_put_att_ulonglong(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
763 // finally instantiate this attribute and return
764 return getAtt(name);
765}
766
767
768// Creates a new NetCDF group attribute or if already exisiting replaces it.
769NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const short* dataValues) const {
770 ncCheckDefineMode(myId);
771 NcType::ncType typeClass(type.getTypeClass());
772 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
773 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
774 else
775 ncCheck(nc_put_att_short(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
776 // finally instantiate this attribute and return
777 return getAtt(name);
778}
779
780
781// Creates a new NetCDF group attribute or if already exisiting replaces it.
782NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const int* dataValues) const {
783 ncCheckDefineMode(myId);
784 NcType::ncType typeClass(type.getTypeClass());
785 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
786 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
787 else
788 ncCheck(nc_put_att_int(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
789 // finally instantiate this attribute and return
790 return getAtt(name);
791}
792
793// Creates a new NetCDF group attribute or if already exisiting replaces it.
794NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const long* dataValues) const {
795 ncCheckDefineMode(myId);
796 NcType::ncType typeClass(type.getTypeClass());
797 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
798 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
799 else
800 ncCheck(nc_put_att_long(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
801 // finally instantiate this attribute and return
802 return getAtt(name);
803}
804
805// Creates a new NetCDF group attribute or if already exisiting replaces it.
806NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const float* dataValues) const {
807 ncCheckDefineMode(myId);
808 NcType::ncType typeClass(type.getTypeClass());
809 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
810 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
811 else
812 ncCheck(nc_put_att_float(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
813 // finally instantiate this attribute and return
814 return getAtt(name);
815}
816
817
818// Creates a new NetCDF group attribute or if already exisiting replaces it.
819NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const double* dataValues) const {
820 ncCheckDefineMode(myId);
821 NcType::ncType typeClass(type.getTypeClass());
822 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
823 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
824 else
825 ncCheck(nc_put_att_double(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
826 // finally instantiate this attribute and return
827 return getAtt(name);
828}
829
830
831// Creates a new NetCDF group attribute or if already exisiting replaces it.
832NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const unsigned short* dataValues) const {
833 ncCheckDefineMode(myId);
834 NcType::ncType typeClass(type.getTypeClass());
835 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
836 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
837 else
838 ncCheck(nc_put_att_ushort(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
839 // finally instantiate this attribute and return
840 return getAtt(name);
841}
842
843// Creates a new NetCDF group attribute or if already exisiting replaces it.
844NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const unsigned int* dataValues) const {
845 ncCheckDefineMode(myId);
846 NcType::ncType typeClass(type.getTypeClass());
847 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
848 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
849 else
850 ncCheck(nc_put_att_uint(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
851 // finally instantiate this attribute and return
852 return getAtt(name);
853}
854
855// Creates a new NetCDF group attribute or if already exisiting replaces it.
856NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const long long* dataValues) const {
857 ncCheckDefineMode(myId);
858 NcType::ncType typeClass(type.getTypeClass());
859 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
860 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
861 else
862 ncCheck(nc_put_att_longlong(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
863 // finally instantiate this attribute and return
864 return getAtt(name);
865}
866
867
868// Creates a new NetCDF group attribute or if already exisiting replaces it.
869NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const unsigned long long* dataValues) const {
870 ncCheckDefineMode(myId);
871 NcType::ncType typeClass(type.getTypeClass());
872 if(typeClass == NcType::nc_VLEN || typeClass == NcType::nc_OPAQUE || typeClass == NcType::nc_ENUM || typeClass == NcType::nc_COMPOUND)
873 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
874 else
875 ncCheck(nc_put_att_ulonglong(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
876 // finally instantiate this attribute and return
877 return getAtt(name);
878}
879
880
881// Creates a new NetCDF group attribute or if already exisiting replaces it.
882NcGroupAtt NcGroup::putAtt(const string& name, size_t len, const char** dataValues) const {
883 ncCheckDefineMode(myId);
884 ncCheck(nc_put_att_string(myId,NC_GLOBAL,name.c_str(),len,dataValues),__FILE__,__LINE__);
885 // finally instantiate this attribute and return
886 return getAtt(name);
887}
888
889// Creates a new NetCDF group attribute or if already exisiting replaces it.
890 NcGroupAtt NcGroup::putAtt(const string& name, const NcType& type, size_t len, const void* dataValues) const {
891 ncCheckDefineMode(myId);
892 ncCheck(nc_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
893 // finally instantiate this attribute and return
894 return getAtt(name);
895}
896
897
898
899// /////////////
900// NcDim-related methods
901// /////////////
902
903// Get the number of NcDim objects.
905 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getDimCount on a Null group",__FILE__,__LINE__);
906
907 // intialize counter
908 int ndims=0;
909
910 // search in current group
911 if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
912 int ndimsp;
913 ncCheck(nc_inq_ndims(getId(), &ndimsp),__FILE__,__LINE__);
914 ndims += ndimsp;
915 }
916
917 // search in parent groups.
918 if(location == Parents || location == ParentsAndCurrent || location == All ) {
919 multimap<string,NcGroup>::iterator it;
920 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
921 for (it=groups.begin();it!=groups.end();it++) {
922 ndims += it->second.getDimCount();
923 }
924 }
925
926 // search in child groups.
927 if(location == Children || location == ChildrenAndCurrent || location == All ) {
928 multimap<string,NcGroup>::iterator it;
929 multimap<string,NcGroup> groups(getGroups(AllChildrenGrps));
930 for (it=groups.begin();it!=groups.end();it++) {
931 ndims += it->second.getDimCount();
932 }
933 }
934 return ndims;
935}
936
937
938// Get the set of NcDim objects.
939multimap<string,NcDim> NcGroup::getDims(NcGroup::Location location) const {
940 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getDims on a Null group",__FILE__,__LINE__);
941 // create a container to hold the NcDim's.
942 multimap<string,NcDim> ncDims;
943
944 // search in current group
945 if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
946 int dimCount = getDimCount();
947 if (dimCount){
948 vector<int> dimids(dimCount);
949 ncCheck(nc_inq_dimids(getId(), &dimCount, &dimids[0], 0),__FILE__,__LINE__);
950 // now get the name of each NcDim and populate the nDims container.
951 for(int i=0; i<dimCount;i++){
952 NcDim tmpDim(*this,dimids[i]);
953 ncDims.insert(pair<const string,NcDim>(tmpDim.getName(),tmpDim));
954 }
955 }
956 }
957
958 // search in parent groups.
959 if(location == Parents || location == ParentsAndCurrent || location == All ) {
960 multimap<string,NcGroup>::iterator it;
961 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
962 for (it=groups.begin();it!=groups.end();it++) {
963 multimap<string,NcDim> dimTmp(it->second.getDims());
964 ncDims.insert(dimTmp.begin(),dimTmp.end());
965 }
966 }
967
968 // search in child groups (makes recursive calls).
969 if(location == Children || location == ChildrenAndCurrent || location == All ) {
970 multimap<string,NcGroup>::iterator it;
971 multimap<string,NcGroup> groups(getGroups(AllChildrenGrps));
972 for (it=groups.begin();it!=groups.end();it++) {
973 multimap<string,NcDim> dimTmp(it->second.getDims());
974 ncDims.insert(dimTmp.begin(),dimTmp.end());
975 }
976 }
977
978 return ncDims;
979}
980
981
982
983// Get the named NcDim object.
984NcDim NcGroup::getDim(const string& name,NcGroup::Location location) const {
985 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getDim on a Null group",__FILE__,__LINE__);
986 multimap<string,NcDim> ncDims(getDims(location));
987 pair<multimap<string,NcDim>::iterator,multimap<string,NcDim>::iterator> ret;
988 ret = ncDims.equal_range(name);
989 if(ret.first == ret.second)
990 return NcDim(); // null group is returned
991 else
992 return ret.first->second;
993}
994
995
996// Get all NcDim objects with a given name.
997set<NcDim> NcGroup::getDims(const string& name,NcGroup::Location location) const {
998 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getDims on a Null group",__FILE__,__LINE__);
999 // get the set of ncDims in this group and above.
1000 multimap<string,NcDim> ncDims(getDims(location));
1001 pair<multimap<string,NcDim>::iterator,multimap<string,NcDim>::iterator> ret;
1002 multimap<string,NcDim>::iterator it;
1003 ret = ncDims.equal_range(name);
1004 set<NcDim> tmpDim;
1005 for (it=ret.first; it!=ret.second; ++it) {
1006 tmpDim.insert(it->second);
1007 }
1008 return tmpDim;
1009}
1010
1011// Add a new NcDim object.
1012NcDim NcGroup::addDim(const string& name, size_t dimSize) const {
1013 ncCheckDefineMode(myId);
1014 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::addDim on a Null group",__FILE__,__LINE__);
1015 int dimId;
1016 ncCheck(nc_def_dim(myId,name.c_str(),dimSize,&dimId),__FILE__,__LINE__);
1017 // finally return NcDim object for this new variable
1018 return NcDim(*this,dimId);
1019}
1020
1021// Add a new NcDim object with unlimited size..
1022NcDim NcGroup::addDim(const string& name) const {
1023 ncCheckDefineMode(myId);
1024 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::addDim on a Null group",__FILE__,__LINE__);
1025 int dimId;
1026 ncCheck(nc_def_dim(myId,name.c_str(),NC_UNLIMITED,&dimId),__FILE__,__LINE__);
1027 // finally return NcDim object for this new variable
1028 return NcDim(*this,dimId);
1029}
1030
1031
1032
1033
1034
1035// /////////////
1036// type-object related methods
1037// /////////////
1038
1039// Gets the number of type objects.
1041
1042 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypeCount on a Null group",__FILE__,__LINE__);
1043
1044 // intialize counter
1045 int ntypes=0;
1046
1047 // search in current group
1048 if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
1049 int ntypesp;
1050 int* typeidsp=NULL;
1051 ncCheck(nc_inq_typeids(getId(), &ntypesp,typeidsp),__FILE__,__LINE__);
1052 ntypes+= ntypesp;
1053 }
1054
1055 // search in parent groups.
1056 if(location == Parents || location == ParentsAndCurrent || location == All ) {
1057 multimap<string,NcGroup>::iterator it;
1058 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
1059 for (it=groups.begin();it!=groups.end();it++) {
1060 ntypes += it->second.getTypeCount();
1061 }
1062 }
1063
1064 // search in child groups.
1065 if(location == Children || location == ChildrenAndCurrent || location == All ) {
1066 multimap<string,NcGroup>::iterator it;
1067 multimap<string,NcGroup> groups(getGroups(AllChildrenGrps));
1068 for (it=groups.begin();it!=groups.end();it++) {
1069 ntypes += it->second.getTypeCount();
1070 }
1071 }
1072 return ntypes;
1073}
1074
1075
1076
1077// Gets the number of type objects with a given enumeration type.
1079
1080 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypeCount on a Null group",__FILE__,__LINE__);
1081
1082 // intialize counter
1083 int ntypes=0;
1084
1085 // search in current group
1086 if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
1087 int ntypesp;
1088 int* typeidsp=NULL;
1089 ncCheck(nc_inq_typeids(getId(), &ntypesp,typeidsp),__FILE__,__LINE__);
1090 if (ntypesp){
1091 vector<int> typeids(ntypesp);
1092 ncCheck(nc_inq_typeids(getId(), &ntypesp,&typeids[0]),__FILE__,__LINE__);
1093 for (int i=0; i<ntypesp;i++){
1094 NcType tmpType(*this,typeids[i]);
1095 if(tmpType.getTypeClass() == enumType) ntypes++;
1096 }
1097 }
1098 }
1099
1100 // search in parent groups.
1101 if(location == Parents || location == ParentsAndCurrent || location == All ) {
1102 multimap<string,NcGroup>::iterator it;
1103 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
1104 for (it=groups.begin();it!=groups.end();it++) {
1105 ntypes += it->second.getTypeCount(enumType);
1106 }
1107 }
1108
1109 // search in child groups.
1110 if(location == Children || location == ChildrenAndCurrent || location == All ) {
1111 multimap<string,NcGroup>::iterator it;
1112 multimap<string,NcGroup> groups(getGroups(AllChildrenGrps));
1113 for (it=groups.begin();it!=groups.end();it++) {
1114 ntypes += it->second.getTypeCount(enumType);
1115 }
1116 }
1117 return ntypes;
1118}
1119
1120
1121// Gets the collection of NcType objects.
1122multimap<string,NcType> NcGroup::getTypes(NcGroup::Location location) const {
1123 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypes on a Null group",__FILE__,__LINE__);
1124 // create a container to hold the NcType's.
1125 multimap<string,NcType> ncTypes;
1126
1127 // search in current group
1128 if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
1129 int typeCount = getTypeCount();
1130 if (typeCount){
1131 vector<int> typeids(typeCount);
1132 ncCheck(nc_inq_typeids(getId(), &typeCount,&typeids[0]),__FILE__,__LINE__);
1133 // now get the name of each NcType and populate the nTypes container.
1134 for(int i=0; i<typeCount;i++){
1135 NcType tmpType(*this,typeids[i]);
1136 ncTypes.insert(pair<const string,NcType>(tmpType.getName(),tmpType));
1137 }
1138 }
1139 }
1140
1141 // search in parent groups.
1142 if(location == Parents || location == ParentsAndCurrent || location == All ) {
1143 multimap<string,NcGroup>::iterator it;
1144 multimap<string,NcGroup> groups(getGroups(ParentsGrps));
1145 for (it=groups.begin();it!=groups.end();it++) {
1146 multimap<string,NcType> typeTmp(it->second.getTypes());
1147 ncTypes.insert(typeTmp.begin(),typeTmp.end());
1148 }
1149 }
1150
1151 // search in child groups (makes recursive calls).
1152 if(location == Children || location == ChildrenAndCurrent || location == All ) {
1153 multimap<string,NcGroup>::iterator it;
1154 multimap<string,NcGroup> groups(getGroups(AllChildrenGrps));
1155 for (it=groups.begin();it!=groups.end();it++) {
1156 multimap<string,NcType> typeTmp(it->second.getTypes());
1157 ncTypes.insert(typeTmp.begin(),typeTmp.end());
1158 }
1159 }
1160
1161 return ncTypes;
1162}
1163
1164
1165// Gets the collection of NcType objects with a given name.
1166set<NcType> NcGroup::getTypes(const string& name, NcGroup::Location location) const {
1167 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypes on a Null group",__FILE__,__LINE__);
1168 // iterator for the multimap container.
1169 multimap<string,NcType>::iterator it;
1170 // return argument of equal_range: iterators to lower and upper bounds of the range.
1171 pair<multimap<string,NcType>::iterator,multimap<string,NcType>::iterator> ret;
1172 // get the entire collection of types.
1173 multimap<string,NcType> types(getTypes(location));
1174 // define STL set object to hold the result
1175 set<NcType> tmpType;
1176 // get the set of NcType objects with a given name
1177 ret=types.equal_range(name);
1178 for (it=ret.first;it!=ret.second;it++) {
1179 tmpType.insert(it->second);
1180 }
1181 return tmpType;
1182}
1183
1184
1185// Gets the collection of NcType objects with a given data type.
1186set<NcType> NcGroup::getTypes(NcType::ncType enumType, NcGroup::Location location) const {
1187 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypes on a Null group",__FILE__,__LINE__);
1188 // iterator for the multimap container.
1189 multimap<string,NcType>::iterator it;
1190 // get the entire collection of types.
1191 multimap<string,NcType> types(getTypes(location));
1192 // define STL set object to hold the result
1193 set<NcType> tmpType;
1194 // get the set of NcType objects with a given data type
1195 for (it=types.begin();it!=types.end();it++) {
1196 if(it->second.getTypeClass() == enumType) {
1197 tmpType.insert(it->second);
1198 }
1199 }
1200 return(tmpType);
1201}
1202
1203
1204// Gets the collection of NcType objects with a given name and data type.
1205set<NcType> NcGroup::getTypes(const string& name, NcType::ncType enumType, NcGroup::Location location) const {
1206 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getTypes on a Null group",__FILE__,__LINE__);
1207 // iterator for the multimap container.
1208 multimap<string,NcType>::iterator it;
1209 // return argument of equal_range: iterators to lower and upper bounds of the range.
1210 pair<multimap<string,NcType>::iterator,multimap<string,NcType>::iterator> ret;
1211 // get the entire collection of types.
1212 multimap<string,NcType> types(getTypes(location));
1213 // define STL set object to hold the result
1214 set<NcType> tmpType;
1215 // get the set of NcType objects with a given name
1216 ret=types.equal_range(name);
1217 for (it=ret.first;it!=ret.second;it++) {
1218 if((*it).second.getTypeClass() == enumType) {
1219 tmpType.insert(it->second);
1220 }
1221 }
1222 return(tmpType);
1223}
1224
1225
1226// Gets the NcType object with a given name.
1227NcType NcGroup::getType(const string& name, NcGroup::Location location) const {
1228 if(isNull()) throw NcNullGrp("Attempt to invoke NcGroup::getType on a Null group",__FILE__,__LINE__);
1229 if(name == "byte" ) return ncByte;
1230 if(name == "ubyte" ) return ncUbyte;
1231 if(name == "char" ) return ncChar;
1232 if(name == "short" ) return ncShort;
1233 if(name == "ushort" ) return ncUshort;
1234 if(name == "int" ) return ncInt;
1235 if(name == "uint" ) return ncUint;
1236 if(name == "int64" ) return ncInt64;
1237 if(name == "uint64" ) return ncUint64;
1238 if(name == "float" ) return ncFloat;
1239 if(name == "double" ) return ncDouble;
1240 if(name == "string" ) return ncString;
1241
1242 // this is a user defined type
1243 // iterator for the multimap container.
1244 multimap<string,NcType>::iterator it;
1245 // return argument of equal_range: iterators to lower and upper bounds of the range.
1246 pair<multimap<string,NcType>::iterator,multimap<string,NcType>::iterator> ret;
1247 // get the entire collection of types.
1248 multimap<string,NcType> types(getTypes(location));
1249 // define STL set object to hold the result
1250 set<NcType> tmpType;
1251 // get the set of NcType objects with a given name
1252 ret=types.equal_range(name);
1253 if(ret.first == ret.second)
1254 return NcType();
1255 else
1256 return ret.first->second;
1257}
1258
1259
1260// Adds a new netCDF Enum type.
1261NcEnumType NcGroup::addEnumType(const string& name,NcEnumType::ncEnumType baseType) const {
1262 ncCheckDefineMode(myId);
1263 nc_type typeId;
1264 ncCheck(nc_def_enum(myId, baseType, name.c_str(), &typeId),__FILE__,__LINE__);
1265 NcEnumType ncTypeTmp(*this,name);
1266 return ncTypeTmp;
1267}
1268
1269
1270// Adds a new netCDF Vlen type.
1271NcVlenType NcGroup::addVlenType(const string& name,NcType& baseType) const {
1272 ncCheckDefineMode(myId);
1273 nc_type typeId;
1274 ncCheck(nc_def_vlen(myId, const_cast<char*>(name.c_str()),baseType.getId(),&typeId),__FILE__,__LINE__);
1275 NcVlenType ncTypeTmp(*this,name);
1276 return ncTypeTmp;
1277}
1278
1279
1280// Adds a new netCDF Opaque type.
1281NcOpaqueType NcGroup::addOpaqueType(const string& name, size_t size) const {
1282 ncCheckDefineMode(myId);
1283 nc_type typeId;
1284 ncCheck(nc_def_opaque(myId, size,const_cast<char*>(name.c_str()), &typeId),__FILE__,__LINE__);
1285 NcOpaqueType ncTypeTmp(*this,name);
1286 return ncTypeTmp;
1287}
1288
1289// Adds a new netCDF UserDefined type.
1290NcCompoundType NcGroup::addCompoundType(const string& name, size_t size) const {
1291 ncCheckDefineMode(myId);
1292 nc_type typeId;
1293 ncCheck(nc_def_compound(myId, size,const_cast<char*>(name.c_str()),&typeId),__FILE__,__LINE__);
1294 NcCompoundType ncTypeTmp(*this,name);
1295 return ncTypeTmp;
1296}
1297
1298
1299// Get the collection of coordinate variables.
1300map<string,NcGroup> NcGroup::getCoordVars(NcGroup::Location location) const {
1301 map<string,NcGroup> coordVars;
1302
1303 // search in current group and parent groups.
1304 NcGroup tmpGroup(*this);
1305 multimap<string,NcDim>::iterator itD;
1306 multimap<string,NcVar>::iterator itV;
1307 while(1) {
1308 // get the collection of NcDim objects defined in this group.
1309 multimap<string,NcDim> dimTmp(tmpGroup.getDims());
1310 multimap<string,NcVar> varTmp(tmpGroup.getVars());
1311 for (itD=dimTmp.begin();itD!=dimTmp.end();itD++) {
1312 string coordName(itD->first);
1313 itV = varTmp.find(coordName);
1314 if(itV != varTmp.end()) {
1315 coordVars.insert(pair<const string,NcGroup>(string(coordName),tmpGroup));
1316 }
1317 }
1318 if(location != ParentsAndCurrent || location != All || tmpGroup.isRootGroup()) {
1319 break;
1320 }
1321 // continue loop with the parent.
1322 tmpGroup=tmpGroup.getParentGroup();
1323 }
1324
1325 // search in child groups (makes recursive calls).
1326 if(location == ChildrenAndCurrent || location == All ) {
1327 multimap<string,NcGroup>::iterator it;
1328 multimap<string,NcGroup> groups(getGroups());
1329 for (it=groups.begin();it!=groups.end();it++) {
1330 map<string,NcGroup> coordVarsTmp=getCoordVars(ChildrenAndCurrent);
1331 coordVars.insert(coordVarsTmp.begin(),coordVarsTmp.end());
1332 }
1333 }
1334
1335 return coordVars;
1336}
1337
1338// Get the NcDim and NcVar object pair for a named coordinate variables.
1339void NcGroup::getCoordVar(string& coordVarName, NcDim& ncDim, NcVar& ncVar, NcGroup::Location location) const {
1340
1341 // search in current group and parent groups.
1342 multimap<string,NcDim>::iterator itD;
1343 NcGroup tmpGroup(*this);
1344 multimap<string,NcVar>::iterator itV;
1345 while(1) {
1346 // get the collection of NcDim objects defined in this group.
1347 multimap<string,NcDim> dimTmp(tmpGroup.getDims());
1348 multimap<string,NcVar> varTmp(tmpGroup.getVars());
1349 itD=dimTmp.find(coordVarName);
1350 itV=varTmp.find(coordVarName);
1351 if(itD != dimTmp.end() && itV != varTmp.end()) {
1352 ncDim=itD->second;
1353 ncVar=itV->second;
1354 return;
1355 }
1356 if(location != ParentsAndCurrent || location != All || tmpGroup.isRootGroup()) {
1357 break;
1358 }
1359 // continue loop with the parent.
1360 tmpGroup=tmpGroup.getParentGroup();
1361 }
1362
1363 // search in child groups (makes recursive calls).
1364 if(location == ChildrenAndCurrent || location == All ) {
1365 multimap<string,NcGroup>::iterator it;
1366 multimap<string,NcGroup> groups(getGroups());
1367 for (it=groups.begin();it!=groups.end();it++) {
1368 getCoordVar(coordVarName,ncDim,ncVar,ChildrenAndCurrent);
1369 if(!ncDim.isNull()) break;
1370 }
1371 }
1372
1373 if(ncDim.isNull()) {
1374 // return null objects as no coordinates variables were obtained.
1375 NcDim dimTmp;
1376 NcVar varTmp;
1377 ncDim=dimTmp;
1378 ncVar=varTmp;
1379 return;
1380 }
1381
1382}
Class represents a netCDF compound type.
Class represents a netCDF dimension.
Definition: ncDim.h:13
std::string getName() const
The name of this dimension.
Definition: ncDim.cpp:106
bool isNull() const
Returns true if this object is null (i.e.
Definition: ncDim.h:62
Class represents a netCDF enum type.
Definition: ncEnumType.h:16
ncEnumType
List of NetCDF-4 Enumeration types.
Definition: ncEnumType.h:20
Class represents a netCDF group attribute.
Definition: ncGroupAtt.h:13
Class represents a netCDF group.
Definition: ncGroup.h:28
int getGroupCount(NcGroup::GroupLocation location=ChildrenGrps) const
Gets the number of NcGroup objects.
Definition: ncGroup.cpp:147
NcGroup & operator=(const NcGroup &rhs)
assignment operator
Definition: ncGroup.cpp:62
NcCompoundType addCompoundType(const std::string &name, size_t size) const
Adds a new netCDF UserDefined type.
Definition: ncGroup.cpp:1290
bool operator!=(const NcGroup &rhs) const
!= operator
Definition: ncGroup.cpp:86
NcVlenType addVlenType(const std::string &name, NcType &basetype) const
Adds a new netCDF Vlen type.
Definition: ncGroup.cpp:1271
NcGroup getGroup(const std::string &name, NcGroup::GroupLocation location=ChildrenGrps) const
Gets the named child NcGroup object.
Definition: ncGroup.cpp:236
void getCoordVar(std::string &coordVarName, NcDim &ncDim, NcVar &ncVar, NcGroup::Location location=Current) const
Gets the NcDim and NcVar object pair for a named coordinate variable.
Definition: ncGroup.cpp:1339
int getTypeCount(NcGroup::Location location=Current) const
Gets the number of type objects.
Definition: ncGroup.cpp:1040
int getId() const
Gets the group id.
Definition: ncGroup.cpp:141
NcType getType(const std::string &name, NcGroup::Location location=Current) const
Gets the NcType object with a given name.
Definition: ncGroup.cpp:1227
int getVarCount(NcGroup::Location location=Current) const
Gets the number of NcVar objects in this group.
Definition: ncGroup.cpp:279
std::multimap< std::string, NcGroupAtt > getAtts(NcGroup::Location location=Current) const
Gets the collection of NcGroupAtt objects.
Definition: ncGroup.cpp:542
NcGroupAtt putAtt(const std::string &name, size_t len, const char **dataValues) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
NcGroup()
Constructor generates a null object.
Definition: ncGroup.cpp:49
NcDim addDim(const std::string &name, size_t dimSize) const
Adds a new netCDF dimension.
NcGroupAtt getAtt(const std::string &name, NcGroup::Location location=Current) const
Gets the named NcGroupAtt object.
Definition: ncGroup.cpp:593
bool isRootGroup() const
Returns true if this is the root group, otherwise returns false.
Definition: ncGroup.cpp:119
NcGroup addGroup(const std::string &name) const
Adds a new child netCDF group object.
Definition: ncGroup.cpp:265
Location
The enumeration list contains the options for selecting groups.
Definition: ncGroup.h:49
@ ParentsAndCurrent
Select from contents of current and parents groups.
Definition: ncGroup.h:53
@ Current
Select from contents of current group.
Definition: ncGroup.h:50
@ Children
Select from contents of children groups.
Definition: ncGroup.h:52
@ ChildrenAndCurrent
Select from contents of current and child groups.
Definition: ncGroup.h:54
@ All
Select from contents of current, parents and child groups.
Definition: ncGroup.h:55
@ Parents
Select from contents of parents groups.
Definition: ncGroup.h:51
bool operator==(const NcGroup &rhs) const
equivalence operator
Definition: ncGroup.cpp:77
std::multimap< std::string, NcVar > getVars(NcGroup::Location location=Current) const
Get the collection of NcVar objects.
Definition: ncGroup.cpp:313
std::map< std::string, NcGroup > getCoordVars(NcGroup::Location location=Current) const
Gets a collection of coordinate variables.
Definition: ncGroup.cpp:1300
GroupLocation
The enumeration list contains the options for selecting groups (used for returned set of NcGroup obje...
Definition: ncGroup.h:36
@ ParentsAndCurrentGrps
Select from set of parent groups(includes the current group).
Definition: ncGroup.h:41
@ ChildrenOfChildrenGrps
Select from set of all children of children in the current group.
Definition: ncGroup.h:39
@ ParentsGrps
Select from set of parent groups (excludes the current group).
Definition: ncGroup.h:38
@ AllGrps
Select from set of parent groups, current groups and all the children beneath.
Definition: ncGroup.h:42
@ ChildrenGrps
Select from the set of children in the current group.
Definition: ncGroup.h:37
@ AllChildrenGrps
Select from set of all children of the current group and beneath.
Definition: ncGroup.h:40
NcOpaqueType addOpaqueType(const std::string &name, size_t size) const
Adds a new netCDF Opaque type.
Definition: ncGroup.cpp:1281
std::string getName(bool fullName=false) const
Gets the group name.
Definition: ncGroup.cpp:97
int getAttCount(NcGroup::Location location=Current) const
Gets the number of group attributes.
Definition: ncGroup.cpp:507
NcEnumType addEnumType(const std::string &name, NcEnumType::ncEnumType basetype) const
Adds a new netCDF enum type.
Definition: ncGroup.cpp:1261
NcGroup getParentGroup() const
Gets the parent group.
Definition: ncGroup.cpp:125
NcVar getVar(const std::string &name, NcGroup::Location location=Current) const
Gets the named NcVar object.
Definition: ncGroup.cpp:388
bool nullObject
assignment operator
Definition: ncGroup.h:570
NcDim getDim(const std::string &name, NcGroup::Location location=Current) const
Gets the named NcDim object.
Definition: ncGroup.cpp:984
NcVar addVar(const std::string &name, const NcType &ncType) const
Adds a new netCDF scalar variable.
Definition: ncGroup.cpp:400
bool isNull() const
Returns true if this object is null (i.e.
Definition: ncGroup.h:158
std::multimap< std::string, NcGroup > getGroups(NcGroup::GroupLocation location=ChildrenGrps) const
Gets the collection of NcGroup objects.
Definition: ncGroup.cpp:183
std::multimap< std::string, NcType > getTypes(NcGroup::Location location=Current) const
Gets the collection of NcType objects.
Definition: ncGroup.cpp:1122
int getDimCount(NcGroup::Location location=Current) const
Gets the number of NcDim objects.
Definition: ncGroup.cpp:904
std::multimap< std::string, NcDim > getDims(NcGroup::Location location=Current) const
Gets the collection of NcDim objects.
Definition: ncGroup.cpp:939
Class represents a netCDF opaque type.
Definition: ncOpaqueType.h:15
Base class inherited by NcOpaque, NcVlen, NcCompound and NcEnum classes.
Definition: ncType.h:15
ncType getTypeClass() const
The type class returned as enumeration type.
Definition: ncType.cpp:116
ncType
List of netCDF types that can be represented.
Definition: ncType.h:26
@ nc_OPAQUE
"NcOpaque type"
Definition: ncType.h:40
@ nc_VLEN
"NcVlen type"
Definition: ncType.h:39
@ nc_ENUM
"NcEnum type"
Definition: ncType.h:41
@ nc_COMPOUND
"NcCompound type"
Definition: ncType.h:42
std::string getName() const
The name of this type.
Definition: ncType.cpp:94
bool isNull() const
Returns true if this object is null (i.e.
Definition: ncType.h:133
nc_type getId() const
The netCDF Id of this type.
Definition: ncType.h:88
Class represents a netCDF variable.
Definition: ncVar.h:34
std::string getName() const
Name of this NcVar object.
Definition: ncVar.cpp:528
Class represents a netCDF VLEN type.
Definition: ncVlenType.h:15
Thrown if cannot return a netCDF group.
Definition: ncException.h:384
Thrown if the requested operation is on a NULL dimension.
Definition: ncException.h:417
Thrown if the requested operation is on a NULL group.
Definition: ncException.h:395
Thrown if the requested operation is on a NULL type.
Definition: ncException.h:406
Exception classes.
Definition: ncException.h:16
C++ API for netCDF4.
Definition: ncAtt.h:10
NcShort ncShort
A global instance of the NcShort class within the netCDF namespace.
Definition: ncShort.cpp:7
NcFloat ncFloat
A global instance of the NcFloat class within the netCDF namespace.
Definition: ncFloat.cpp:7
NcInt64 ncInt64
A global instance of the NcInt64 class within the netCDF namespace.
Definition: ncInt64.cpp:7
void ncCheckDefineMode(int ncid)
Function checks if the file (group) is in define mode.
Definition: ncCheck.cpp:83
NcUint64 ncUint64
A global instance of the NcUint64 class within the netCDF namespace.
Definition: ncUint64.cpp:7
NcUint ncUint
A global instance of the NcUint class within the netCDF namespace.
Definition: ncUint.cpp:7
NcString ncString
A global instance of the NcString class within the netCDF namespace.
Definition: ncString.cpp:7
NcInt ncInt
A global instance of the NcInt class within the netCDF namespace.
Definition: ncInt.cpp:7
NcDouble ncDouble
A global instance of the NcDouble class within the netCDF namespace.
Definition: ncDouble.cpp:7
void ncCheck(int retCode, const char *file, int line)
Function checks error code and if necessary throws an exception.
Definition: ncCheck.cpp:11
NcUbyte ncUbyte
A global instance of the NcUbyte class within the netCDF namespace.
Definition: ncUbyte.cpp:7
NcChar ncChar
A global instance of the NcChar class within the netCDF namespace.
Definition: ncChar.cpp:7
NcByte ncByte
A global instance of the NcByte class within the netCDF namespace.
Definition: ncByte.cpp:7

Return to the Main Unidata NetCDF page.
Generated on Wed Nov 10 2021 15:25:08 for NetCDF-C++. NetCDF is a Unidata library.