General Purpose Geodetic Library
SgNetCdf.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 
24 #include <math.h>
25 
26 #include <QtCore/QFile>
27 
28 #include <SgIdentities.h>
29 #include <SgLogger.h>
30 #include <SgMJD.h>
31 #include <SgNetCdf.h>
32 #include <SgVersion.h>
33 
34 
35 //
36 //
37 static const QString dimensionUnityName("DimUnity");
38 static const int dimensionUnityValue = 1;
40 
41 /*=======================================================================================================
42 *
43 * Helpers:
44 *
45 *======================================================================================================*/
46 //
47 size_t ncdfaux_type_2_size(nc_type type)
48 {
49  size_t size_of_type=1;
50  switch (type)
51  {
52  case NC_BYTE:
53  case NC_CHAR:
54  size_of_type = sizeof(char);
55  break;
56  case NC_SHORT:
57  size_of_type = sizeof(short);
58  break;
59  case NC_INT:
60  size_of_type = sizeof(int);
61  break;
62  case NC_FLOAT:
63  size_of_type = sizeof(float);
64  break;
65  case NC_DOUBLE:
66  size_of_type = sizeof(double);
67  break;
68  case NC_NAT:
69  logger->write(SgLogger::WRN, SgLogger::IO_NCDF, "ncdfaux_type_2_size: unexpected data type");
70  break;
71  };
72  return size_of_type;
73 };
74 
75 
76 
77 //
78 void ncdfaux_data_allocate(void*& dest, nc_type type, size_t num)
79 {
80  if (dest != NULL)
81  {
83  "ncdfaux_data_allocate: the destination is not clean");
84  };
85  size_t size_of_type=ncdfaux_type_2_size(type);
86  switch (type)
87  {
88  case NC_BYTE:
89  case NC_CHAR:
90  dest = new char[num];
91  break;
92  case NC_SHORT:
93  dest = new short[num];
94  break;
95  case NC_INT:
96  dest = new int[num];
97  break;
98  case NC_FLOAT:
99  dest = new float[num];
100  break;
101  case NC_DOUBLE:
102  dest = new double[num];
103  break;
104  case NC_NAT:
105  dest = NULL;
106  logger->write(SgLogger::WRN, SgLogger::IO_NCDF, "ncdfaux_data_allocate: unexpected data type");
107  break;
108  };
109  if (dest)
110  memset(dest, 0, size_of_type*num);
111 };
112 
113 
114 
115 //
116 void ncdfaux_data_allocate_n_copy(void*& dest, const void* src, nc_type type, size_t num)
117 {
118  if (dest != NULL)
119  {
121  "ncdfaux_data_allocate_n_copy: the destination is not clean");
122  };
123  size_t size_of_type=ncdfaux_type_2_size(type);
124  switch (type)
125  {
126  case NC_BYTE:
127  case NC_CHAR:
128  dest = new char[num];
129  break;
130  case NC_SHORT:
131  dest = new short[num];
132  break;
133  case NC_INT:
134  dest = new int[num];
135  break;
136  case NC_FLOAT:
137  dest = new float[num];
138  break;
139  case NC_DOUBLE:
140  dest = new double[num];
141  break;
142  case NC_NAT:
144  "ncdfaux_data_allocate_n_copy: unexpected data type");
145  break;
146  };
147  memcpy(dest, src, size_of_type*num);
148 };
149 
150 
151 
152 //
153 void ncdfaux_data_free(void*& dest, nc_type type)
154 {
155  if (!dest)
156  {
157  logger->write(SgLogger::WRN, SgLogger::IO_NCDF, "ncdfaux_data_free: the destination is NULL");
158  return;
159  };
160  switch (type)
161  {
162  case NC_BYTE:
163  case NC_CHAR:
164  delete[] (char*)dest;
165  break;
166  case NC_SHORT:
167  delete[] (short*)dest;
168  break;
169  case NC_INT:
170  delete[] (int*)dest;
171  break;
172  case NC_FLOAT:
173  delete[] (float*)dest;
174  break;
175  case NC_DOUBLE:
176  delete[] (double*)dest;
177  break;
178  case NC_NAT:
179  logger->write(SgLogger::WRN, SgLogger::IO_NCDF, "ncdfaux_data_free: unexpected data type");
180  break;
181  };
182  dest = NULL;
183 };
184 
185 
186 
187 //
188 QString ncdfaux_type_2_string(nc_type xtype)
189 {
190  QString str("");
191  switch (xtype)
192  {
193  case NC_BYTE:
194  str = "NC_BYTE";
195  break;
196  case NC_CHAR:
197  str = "NC_CHAR";
198  break;
199  case NC_SHORT:
200  str = "NC_SHORT";
201  break;
202  case NC_INT:
203  str = "NC_INT";
204  break;
205  case NC_FLOAT:
206  str = "NC_FLOAT";
207  break;
208  case NC_DOUBLE:
209  str = "NC_DOUBLE";
210  break;
211  case NC_NAT:
212  str = "NC_NAT";
213  break;
214  };
215  return str;
216 };
217 
218 
219 
220 
221 
222 
223 
224 /*=====================================================================================================*/
225 /* */
226 /* SgNcdfDimension implementation */
227 /* */
228 /*=====================================================================================================*/
229 //
230 // static first:
232 {
233  return "SgNcdfDimension";
234 };
235 
236 
237 
238 //
240 {
241  std::cout << " dim #" << id_ << ", \"" << qPrintable(name_) << "\" = "
242  << n_ << "\n";
243 };
244 /*=====================================================================================================*/
245 
246 
247 const QString SgNetCdf::svcStub("Stub");
248 const QString SgNetCdf::svcCreateTime("CreateTime");
249 const QString SgNetCdf::svcCreatedBy("CreatedBy");
250 const QString SgNetCdf::svcProgram("Program");
251 const QString SgNetCdf::svcSubroutine("Subroutine");
252 const QString SgNetCdf::svcVgosDbVersion("vgosDB_Version");
253 const QString SgNetCdf::svcDataOrigin("DataOrigin");
254 const QString SgNetCdf::svcTimeTag("TimeTag");
255 const QString SgNetCdf::svcTimeTagFile("TimeTagFile");
256 const QString SgNetCdf::svcSession("Session");
257 const QString SgNetCdf::svcStation("Station");
258 const QString SgNetCdf::svcBand("Band");
259 
260 
261 
262 /*=====================================================================================================*/
263 /* */
264 /* SgNcdfAttribute implementation */
265 /* */
266 /*=====================================================================================================*/
267 //
268 // static first:
270 {
271  return "SgNcdfAttribute";
272 };
273 
274 
275 
276 //
278  : name_("")
279 {
280  data_ = NULL;
281  numOfElements_ = 0;
282  typeOfData_ = NC_NAT; // == "not a type"
283 };
284 
285 
286 
287 //
288 SgNcdfAttribute::SgNcdfAttribute(const QString name, nc_type typeOfData,
289  size_t numOfElements, void *data)
290  : name_(name)
291 {
292  typeOfData_ = typeOfData;
293  numOfElements_ = numOfElements;
294  data_ = NULL;
296 };
297 
298 
299 
300 //
302  : name_(attr.getName())
303 {
306  data_ = NULL;
308 };
309 
310 
311 
312 //
314 {
315  if (data_)
317 };
318 
319 
320 
321 //
322 void SgNcdfAttribute::setData(const void* src, size_t num)
323 {
324  if (data_)
327 };
328 
329 
330 
331 //
332 int SgNcdfAttribute::nc_get_attr(int ncid, int varid)
333 {
334  int rc(0);
335  if (!data_)
337  switch (typeOfData_)
338  {
339  case NC_BYTE:
340  rc = nc_get_att_schar(ncid, varid, qPrintable(name_), (signed char*)data_);
341  break;
342  case NC_CHAR:
343  rc = nc_get_att_text(ncid, varid, qPrintable(name_), (char*)data_);
344  break;
345  case NC_SHORT:
346  rc = nc_get_att_short(ncid, varid, qPrintable(name_), (short*)data_);
347  break;
348  case NC_INT:
349  rc = nc_get_att_int(ncid, varid, qPrintable(name_), (int*)data_);
350  break;
351  case NC_FLOAT:
352  rc = nc_get_att_float(ncid, varid, qPrintable(name_), (float*)data_);
353  break;
354  case NC_DOUBLE:
355  rc = nc_get_att_double(ncid, varid, qPrintable(name_), (double*)data_);
356  break;
357  case NC_NAT:
358  rc = NC_EBADTYPE;
360  "::readAttr(): unexpected data type");
361  break;
362  };
363  return rc;
364 };
365 
366 
367 
368 //
369 int SgNcdfAttribute::nc_put_attr(int ncid, int varid)
370 {
371  int rc(0);
372  if (!data_)
373  {
375  "::nc_put_attr(): the data is NULL");
376  return NC_ENOMEM;
377  };
378  switch (typeOfData_)
379  {
380  case NC_CHAR:
381  rc = nc_put_att_text(ncid, varid, qPrintable(name_), numOfElements_,
382  (const char*)data_);
383  break;
384  case NC_BYTE:
385  case NC_SHORT:
386  case NC_INT:
387  case NC_FLOAT:
388  case NC_DOUBLE:
389  rc = nc_put_att(ncid, varid, qPrintable(name_), typeOfData_, numOfElements_, data_);
390  break;
391  case NC_NAT:
392  rc = NC_EBADTYPE;
394  "::nc_put_attr(): unexpected data type");
395  break;
396  };
397  return rc;
398 };
399 
400 
401 
402 //
404 {
405 
406 };
407 /*=====================================================================================================*/
408 
409 
410 
411 
412 /*=====================================================================================================*/
413 /* */
414 /* SgNcdfVariable implementation */
415 /* */
416 /*=====================================================================================================*/
417 //
418 // static first:
420 {
421  return "SgNcdfVariable";
422 };
423 
424 
425 
426 //
428  name_(),
429  dimensionByName_(),
430  dimensions_(),
431  attributeByName_()
432 {
433  id_ = -1;
434  data_ = NULL;
435  typeOfData_ = NC_NAT; // == "not a type"
436  numOfElements_ = 0;
437 };
438 
439 
440 
441 //
443 {
444  if (data_)
446  for (int i=0; i<dimensions_.size(); i++)
447  delete dimensions_.at(i);
448  dimensions_.clear();
449  dimensionByName_.clear();
450  QMap<QString, SgNcdfAttribute*>::iterator it=attributeByName_.begin();
451  for (; it!=attributeByName_.end(); ++it)
452  delete it.value();
453  attributeByName_.clear();
454 };
455 
456 
457 
458 //
459 const char* SgNcdfVariable::data2char() const
460 {
461  if (typeOfData_ != NC_CHAR)
463  "::data2char(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
464  return (const char*)data_;
465 };
466 
467 
468 
469 //
471 {
472  if (typeOfData_ != NC_CHAR)
474  "::data2char(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
475  return (char*)data_;
476 };
477 
478 
479 
480 //
481 const short* SgNcdfVariable::data2short() const
482 {
483  if (typeOfData_ != NC_SHORT)
485  "::data2short(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
486  return (const short*)data_;
487 };
488 
489 
490 
491 //
493 {
494  if (typeOfData_ != NC_SHORT)
496  "::data2short(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
497  return (short*)data_;
498 };
499 
500 
501 
502 //
503 const int* SgNcdfVariable::data2int() const
504 {
505  if (typeOfData_ != NC_INT)
507  "::data2int(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
508  return (const int*)data_;
509 };
510 
511 
512 
513 //
515 {
516  if (typeOfData_ != NC_INT)
518  "::data2int(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
519  return (int*)data_;
520 };
521 
522 
523 
524 //
525 const double* SgNcdfVariable::data2double() const
526 {
527  if (typeOfData_ != NC_DOUBLE)
529  "::data2double(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
530  return (const double*)data_;
531 };
532 
533 
534 
535 //
537 {
538  if (typeOfData_ != NC_DOUBLE)
540  "::data2double(): wrong conversion, the data is of type " + ncdfaux_type_2_string(typeOfData_));
541  return (double*)data_;
542 };
543 
544 
545 
546 //
547 void SgNcdfVariable::addDimension(const QString& name, int n, int id, int idx)
548 {
549  SgNcdfDimension *d=new SgNcdfDimension(name, n, id);
550 
551  if (idx < 0)
552  dimensions_.append(d);
553  else
554  dimensions_.insert(idx, d);
555 
556  if (!dimensionByName_.contains(name))
557  dimensionByName_.insert(d->getName(), d);
558 
559  if (dimensions_.size() == 1)
560  numOfElements_ = n;
561  else
562  numOfElements_ *= n;
563 };
564 
565 
566 
567 //
568 void SgNcdfVariable::delDimension(const QString& name)
569 {
570  int n, idx;
571  if (!dimensionByName_.contains(name))
572  {
574  "::delDimension(): the dimension " + name + " is not in the map");
575  return;
576  };
577  //
578  n = dimensionByName_.value(name)->getN();
579  //
580  idx = -1;
581  for (int i=0; i<dimensions_.size(); i++)
582  if (dimensions_.at(i)->getName() == name)
583  idx = i;
584 
585  if (idx == -1)
587  "::delDimension(): cannot find [" + name + "] in the list");
588  else
589  {
590  delete dimensions_.at(idx);
591  dimensions_.removeAt(idx);
592  };
593  //
594  //n = dimensionByName_.value(name)->getN();
595  // remove from the map:
596  //dimensionByName_.remove(name);
597  if (n != 0)
598  {
599  if (dimensionByName_.size() == 0)
600  numOfElements_ = 0;
601  else
602  numOfElements_ /= n;
603  }
604  else
606  "::delDimension(): the dimension " + name + " was set to zero");
607 };
608 
609 
610 
611 //
613 {
614  if (attributeByName_.contains(attr.getName()))
615  {
617  "::addAttribute(): the attribute " + attr.getName() + " is already in the list");
618  delAttribute(attr.getName());
619  };
620  SgNcdfAttribute *a=new SgNcdfAttribute(attr);
621  attributeByName_.insert(a->getName(), a);
622 };
623 
624 
625 
626 //
628 {
629  if (attributeByName_.contains(a->getName()))
630  {
632  "::addAttribute(): the attribute " + a->getName() + " is already in the list");
633  delAttribute(a->getName());
634  };
635  attributeByName_.insert(a->getName(), a);
636 };
637 
638 
639 
640 //
641 void SgNcdfVariable::delAttribute(const QString& name)
642 {
643  if (!attributeByName_.contains(name))
644  {
646  "::delAttribute(): the attribute " + name + " is not in the list");
647  return;
648  };
649  delete attributeByName_.value(name);
650  // remove from the map:
651  attributeByName_.remove(name);
652 };
653 
654 
655 
656 //
658 {
659  if (dimensions_.size()==0)
660  {
661  numOfElements_ = 0;
662  return;
663  };
664  numOfElements_ = 1;
665  for (int i=0; i<dimensions_.size(); i++)
666  numOfElements_ *= dimensions_.at(i)->getN();
667 };
668 
669 
670 
671 //
673 {
674  int rc(0);
675  if (!data_)
677  switch (typeOfData_)
678  {
679  case NC_BYTE:
680  rc = nc_get_var_schar(ncid, id_, (signed char*)data_);
681  break;
682  case NC_CHAR:
683  rc = nc_get_var_text(ncid, id_, (char*)data_);
684  break;
685  case NC_SHORT:
686  rc = nc_get_var_short(ncid, id_, (short*)data_);
687  break;
688  case NC_INT:
689  rc = nc_get_var_int(ncid, id_, (int*)data_);
690  break;
691  case NC_FLOAT:
692  rc = nc_get_var_float(ncid, id_, (float*)data_);
693  break;
694  case NC_DOUBLE:
695  rc = nc_get_var_double(ncid, id_, (double*)data_);
696  break;
697  case NC_NAT:
698  rc = NC_EBADTYPE;
700  "::nc_get_var(): unexpected data type");
701  break;
702  };
703  return rc;
704 };
705 
706 
707 
708 //
710 {
711  int rc(0);
712  if (!data_)
713  {
715  "::nc_put_var(): the data is NULL");
716  return NC_ENOMEM;
717  };
718  switch (typeOfData_)
719  {
720  case NC_BYTE:
721  rc = nc_put_var_schar(ncid, id_, (const signed char*)data_);
722  break;
723  case NC_CHAR:
724  rc = nc_put_var_text(ncid, id_, (const char*)data_);
725  break;
726  case NC_SHORT:
727  rc = nc_put_var_short(ncid, id_, (const short*)data_);
728  break;
729  case NC_INT:
730  rc = nc_put_var_int(ncid, id_, (const int*)data_);
731  break;
732  case NC_FLOAT:
733  rc = nc_put_var_float(ncid, id_, (const float*)data_);
734  break;
735  case NC_DOUBLE:
736  rc = nc_put_var_double(ncid, id_, (const double*)data_);
737  break;
738  case NC_NAT:
739  rc = NC_EBADTYPE;
741  "::nc_put_var(): unexpected data type");
742  break;
743  };
744  return rc;
745 };
746 
747 
748 
749 //
751 {
752  size_t size_of_type=ncdfaux_type_2_size(typeOfData_);
753  void *oldData=data_;
754  data_ = NULL;
756  for (int i=0; i<mult; i++)
757  memcpy((unsigned char*)data_ + size_of_type*numOfElements_*i, oldData, size_of_type*numOfElements_);
758  ncdfaux_data_free(oldData, typeOfData_);
760  "::multiplyData(): the data of \"" + name_ + "\" were multiplied " +
761  QString("").setNum(mult) + " times");
762  //
763  // adjust the dimensions:
764  if (dimensions_.size()==1 && dimensions_.at(0)->getN()==1)
765  dimensions_.first()->setN(mult);
766  else
767  {
768  SgNcdfDimension *d=new SgNcdfDimension("REPEAT-multiplier", mult, -1);
769  dimensions_.prepend(d);
770  dimensionByName_.insert(d->getName(), d);
771  };
772  numOfElements_ *= mult;
773 };
774 
775 
776 
777 //
779 {
780  int nSize;
781  SgNcdfAttribute *attr=new SgNcdfAttribute("Size", NC_INT, 1, &(nSize=sizeOfData()));
782  addAttribute(attr);
783 
784  if (attributeByName_.contains("REPEAT"))
785  {
787  "::check4multiplication(): the variable \"" + name_ + "\" already has an attribute \"REPEAT\"");
788  return;
789  };
790  int cDim;
791  if (dimensions_.size() && (cDim=dimensions_.at(0)->getN())>1) // ok, there is something
792  {
793  QString cDimName=dimensions_.at(0)->getName();
794  bool canBeConvolved=true;
795  size_t size_of_type=ncdfaux_type_2_size(typeOfData_);
796  size_t size_of_newData;
797  void *newData=NULL;
798  int newNumOfElements=1;
799  for (int i=1; i<dimensions_.size(); i++)
800  newNumOfElements *= dimensions_.at(i)->getN();
801 
802  ncdfaux_data_allocate(newData, typeOfData_, newNumOfElements);
803  size_of_newData = size_of_type*newNumOfElements;
804  memcpy((unsigned char*)newData, data_, size_of_newData);
805  for (int i=0; i<cDim && canBeConvolved; i++)
806  if (memcmp((unsigned char*)data_ + size_of_newData*i, newData, size_of_newData) != 0)
807  canBeConvolved = false;
808  if (canBeConvolved) // ok, do it:
809  {
810  // adjust the dimensions:
811  delDimension(cDimName);
812  if (!dimensions_.size())
813  {
815  numOfElements_ = newNumOfElements;
816  };
817  // set up the attribute:
818  attr = new SgNcdfAttribute("REPEAT", NC_INT, 1, &cDim);
819  addAttribute(attr);
820  attr = new SgNcdfAttribute("StoredSize", NC_INT, 1, &(nSize=sizeOfData()));
821  addAttribute(attr);
822  // delete old data:
824  data_ = newData;
825  // make report:
827  "::check4multiplication(): the variable \"" + name_ +
828  "\" has been convolved: dimension \"" + cDimName + "\", multiplier=" +
829  QString("").setNum(cDim));
830  };
831  };
832 };
833 
834 
835 
836 //
838 {
839  if (data_)
840  {
842  "::allocateData(): the data of \"" + name_ + "\" were already allocated");
844  };
845  if (numOfElements_>0)
847  else
849  "::allocateData(): impossible to allocate the data of \"" + name_ + "\": the size is zero");
850 };
851 
852 
853 
854 //
856 {
858 };
859 
860 
861 
862 //
864 {
865  QString str("");
866  std::cout << "Variable # " << id_ << " \"" << qPrintable(name_) << "\" of type ";
867  std::cout << qPrintable(ncdfaux_type_2_string(typeOfData_));
868  std::cout << " and length " << numOfElements_ << "\n";
869  std::cout << " Dimensions:\n";
870  for (int i=0; i<dimensions_.size(); i++)
871  dimensions_.at(i)->debug_output();
872  // attributes:
873  if (attributeByName_.size())
874  {
875  std::cout << " Variable's attributes:\n";
876  const QList<SgNcdfAttribute*> &atts = attributeByName_.values();
877  for (int i=0; i<atts.size(); i++)
878  {
879  SgNcdfAttribute *a=atts.at(i);
880 
881  std::cout << " Attr \"" << qPrintable(a->getName()) << "\" of type ";
882  std::cout << qPrintable(ncdfaux_type_2_string(a->getTypeOfData()));
883  std::cout << " and length " << a->getNumOfElements();
884  str = "";
885  switch (a->getTypeOfData())
886  {
887  case NC_BYTE:
888  for (unsigned int k=0; k<a->getNumOfElements(); k++)
889  str += QString("").sprintf("%d,", ((signed char*)a->getData())[k]);
890  break;
891  case NC_CHAR:
892  str = QString::fromLatin1((const char*)a->getData(), a->getNumOfElements());
893  break;
894  case NC_SHORT:
895  for (unsigned int k=0; k<a->getNumOfElements(); k++)
896  str += QString("").sprintf("%d,", ((short*)a->getData())[k]);
897  break;
898  case NC_INT:
899  for (unsigned int k=0; k<a->getNumOfElements(); k++)
900  str += QString("").sprintf("%d,", ((int*)a->getData())[k]);
901  break;
902  case NC_FLOAT:
903  for (unsigned int k=0; k<a->getNumOfElements(); k++)
904  str += QString("").sprintf("%g,", ((float*)a->getData())[k]);
905  break;
906  case NC_DOUBLE:
907  for (unsigned int k=0; k<a->getNumOfElements(); k++)
908  str += QString("").sprintf("%g,", ((double*)a->getData())[k]);
909  break;
910  case NC_NAT:
911  str = "***";
912  break;
913  };
914  std::cout << "; value : [" << qPrintable(str) << "]\n";
915  };
916  };
917  // values:
918  std::cout << " Value: ";
919  switch (typeOfData_)
920  {
921  case NC_BYTE:
922  for (unsigned int k=0; k<numOfElements_; k++)
923  std::cout << qPrintable(QString("").sprintf("%d,", ((signed char*)data_)[k]));
924  std::cout << "\n";
925  break;
926  case NC_CHAR:
927  std::cout << qPrintable(QString::fromLatin1((const char*)data_, numOfElements_));
928  std::cout << "\n";
929  break;
930  case NC_SHORT:
931  for (unsigned int k=0; k<numOfElements_; k++)
932  std::cout << qPrintable(QString("").sprintf("%d,", ((short*)data_)[k]));
933  std::cout << "\n";
934  break;
935  case NC_INT:
936  for (unsigned int k=0; k<numOfElements_; k++)
937  std::cout << qPrintable(QString("").sprintf("%d,", ((int*)data_)[k]));
938  std::cout << "\n";
939  break;
940  case NC_FLOAT:
941  for (unsigned int k=0; k<numOfElements_; k++)
942  std::cout << qPrintable(QString("").sprintf("%g,", ((float*)data_)[k]));
943  std::cout << "\n";
944  break;
945  case NC_DOUBLE:
946  for (unsigned int k=0; k<numOfElements_; k++)
947  std::cout << qPrintable(QString("").sprintf("%g,", ((double*)data_)[k]));
948  std::cout << "\n";
949  break;
950  case NC_NAT:
951  std::cout << "NC_NAT";
952  std::cout << "\n";
953  break;
954  };
955 };
956 /*=====================================================================================================*/
957 
958 
959 
960 
961 
962 
963 /*=====================================================================================================*/
964 /* */
965 /* SgNetCdf implementation */
966 /* */
967 /*=====================================================================================================*/
968 //
969 // static first:
970 const QString SgNetCdf::className()
971 {
972  return "SgNetCdf";
973 };
974 
975 
976 
977 //
979  fileName_(""),
980  dimensionByName_(),
981  serviceVars_(),
982  contentVars_(),
983 // dUnity_(dimensionUnityName, dimensionUnityValue, -1),
984  fmtVerId_(""),
985  sessionId_(""),
986  stationId_(""),
987  bandId_("")
988 {
989  identities_ = NULL;
992 };
993 
994 
995 
996 //
997 SgNetCdf::SgNetCdf(const QString& fileName, const SgIdentities *ids, const QString& fmtVerId,
998  const QString& sessionId, const QString& stationId, const QString& bandId) :
999  fileName_(fileName),
1000  dimensionByName_(),
1001  serviceVars_(),
1002  contentVars_(),
1003 // dUnity_(dimensionUnityName, dimensionUnityValue, -1),
1004  fmtVerId_(fmtVerId),
1005  sessionId_(sessionId),
1006  stationId_(stationId),
1007  bandId_(bandId)
1008 {
1009  identities_ = ids;
1012 };
1013 
1014 
1015 
1016 //
1018 {
1019  identities_ = NULL;
1020  reset();
1021  // clear the map, it still contains "Unity"
1022  QMap<QString, SgNcdfDimension*>::iterator it_d=dimensionByName_.begin();
1023  for (; it_d!=dimensionByName_.end(); ++it_d)
1024  delete it_d.value();
1025  dimensionByName_.clear();
1026 };
1027 
1028 
1029 
1030 //
1032 {
1033  QMap<QString, SgNcdfDimension*>::iterator it_d=dimensionByName_.begin();
1034  for (; it_d!=dimensionByName_.end(); ++it_d)
1035  delete it_d.value();
1036  dimensionByName_.clear();
1038 
1039  //
1040  QMap<QString, SgNcdfVariable*>::iterator it;
1041  for (it=serviceVars_.begin(); it!=serviceVars_.end(); ++it)
1042  delete it.value();
1043  for (it=contentVars_.begin(); it!=contentVars_.end(); ++it)
1044  delete it.value();
1045  serviceVars_.clear();
1046  contentVars_.clear();
1048 };
1049 
1050 
1051 
1052 //
1054 {
1055  bool isOk(false);
1056  int ncid, rc;
1057  // checking:
1058  if (!fileName_.size())
1059  {
1061  "::getData(): the file name is not specified");
1062  return isOk;
1063  };
1064  if ((rc=nc_open(qPrintable(fileName_), 0, &ncid)) != NC_NOERR)
1065  {
1066  printf("%s: %s\n", qPrintable("Error opening " + fileName_), nc_strerror(rc));
1068  "::getData(): cannot open the file " + fileName_);
1069  return isOk;
1070  };
1071  //
1072  reset();
1073  //
1074  // general variables:
1075  size_t len;
1076  nc_type xtype;
1077  //
1078  // get dimensions:
1079  QMap<int, SgNcdfDimension*> dimById;
1080  int numOfDims;
1081  char buff[NC_MAX_NAME + 1];
1082  if ((rc=nc_inq_ndims(ncid, &numOfDims)) != NC_NOERR)
1083  {
1084  printf("%s: %s\n",
1085  qPrintable("Error inquiring number of dimensions from " + fileName_), nc_strerror(rc));
1087  "::getData(): inquire of total number of dimensions has failed");
1088  nc_close(ncid);
1089  return isOk;
1090  };
1091  for (int i=0; i<numOfDims; i++)
1092  {
1093  if ((rc=nc_inq_dim(ncid, i, buff, &len)) != NC_NOERR)
1094  {
1095  printf("%s: %s\n",
1096  qPrintable("Error inquiring dimension name and length from " + fileName_), nc_strerror(rc));
1098  "::getData(): inquire of dimension name and length for dim#" + QString("").setNum(i) +
1099  " has failed");
1100  nc_close(ncid);
1101  return isOk;
1102  };
1103  dimById.insert(i, new SgNcdfDimension(QString(buff), len, i));
1104  };
1105  //
1106  //
1107  // get variables:
1108  QMap<int, SgNcdfVariable*> varById;
1109  int numOfVars;
1110  if ((rc=nc_inq_nvars(ncid, &numOfVars)) != NC_NOERR)
1111  {
1112  printf("%s: %s\n",
1113  qPrintable("Error inquiring number of dimensions from " + fileName_), nc_strerror(rc));
1115  "::getData(): inquire of total number of variables has failed");
1116  nc_close(ncid);
1117  return isOk;
1118  };
1119  for (int i=0; i<numOfVars; i++)
1120  {
1121  int dimids[NC_MAX_VAR_DIMS];
1122  int ndims, natts;
1123  SgNcdfVariable *v=NULL;
1124  if ((rc=nc_inq_var(ncid, i, buff, &xtype, &ndims, dimids, &natts)) != NC_NOERR)
1125  {
1126  printf("%s: %s\n",
1127  qPrintable("Error inquiring variable from " + fileName_), nc_strerror(rc));
1129  "::getData(): inquire of variable for var#" + QString("").setNum(i) +
1130  " has failed");
1131  nc_close(ncid);
1132  return isOk;
1133  };
1134  v = new SgNcdfVariable;
1135  v->setName(QString(buff));
1136  v->setTypeOfData(xtype);
1137  v->setId(i);
1138  // dimensions:
1139  for (int j=0; j<ndims; j++)
1140  {
1141  SgNcdfDimension *d=dimById.value(dimids[j]);
1142  v->addDimension(*d);
1143  };
1144  // attributes:
1145  for (int j=0; j<natts; j++)
1146  {
1147  SgNcdfAttribute *attr=new SgNcdfAttribute;
1148  if ((rc=nc_inq_attname(ncid, i, j, buff)) != NC_NOERR)
1149  {
1150  printf("%s: %s\n",
1151  qPrintable("Error inquiring attribute name from " + fileName_), nc_strerror(rc));
1153  "::getData(): inquire of name of attribute# "+ QString("").setNum(j) + " for variable #" +
1154  QString("").setNum(i) + " has failed");
1155  nc_close(ncid);
1156  return isOk;
1157  };
1158  attr->setName(QString(buff));
1159  if ((nc_inq_att(ncid, i, buff, &xtype, &len)) != NC_NOERR)
1160  {
1161  printf("%s: %s\n",
1162  qPrintable("Error inquiring attribute from " + fileName_), nc_strerror(rc));
1164  "::getData(): inquire of attribute# "+ QString("").setNum(j) + " for variable #" +
1165  QString("").setNum(i) + " has failed");
1166  nc_close(ncid);
1167  return isOk;
1168  };
1169  attr->setTypeOfData(xtype);
1170  attr->setNumOfElements(len);
1171  if ((rc=attr->nc_get_attr(ncid, i)) != NC_NOERR)
1172  {
1173  printf("%s: %s\n",
1174  qPrintable("Error inquiring attribute name from " + fileName_), nc_strerror(rc));
1176  "::getData(): inquire of name of attribute# "+ QString("").setNum(j) + " for variable #" +
1177  QString("").setNum(i) + " has failed");
1178  nc_close(ncid);
1179  return isOk;
1180  };
1181  v->addAttribute(attr);
1182  };
1183  // read the data:
1184  if ((rc=v->nc_get_var(ncid)) != NC_NOERR)
1185  {
1186  printf("%s: %s\n",
1187  qPrintable("Error reading variable from " + fileName_), nc_strerror(rc));
1189  "::getData(): reading of data of variable# "+ QString("").setNum(i) + " has failed");
1190  nc_close(ncid);
1191  return isOk;
1192  };
1193  // check for "REPEAT" attribute:
1194  if (v->attributeByName().contains("REPEAT"))
1195  {
1196  SgNcdfAttribute *att=v->attributeByName().value("REPEAT");
1197  if (att && att->getTypeOfData()==NC_INT && att->getNumOfElements()==1)
1198  {
1199  int mult=*(int*)att->getData();
1200  v->multiplyData(mult);
1201  }
1202  else
1204  "::getData(): reading of data of variable# "+ QString("").setNum(i) +
1205  ": has wrong attribute REPEAT");
1206  };
1207  varById.insert(i, v);
1208  };
1209  //
1210  //
1211  // dimensions:
1212  QMap<int, SgNcdfDimension*>::iterator it_d=dimById.begin();
1213  for(; it_d!=dimById.end(); ++it_d)
1214  dimensionByName_.insert(it_d.value()->getName(), it_d.value());
1215  dimById.clear();
1216  //
1217  // variables:
1218  const QString srvVarNames("Stub:CreateTime:CreatedBy:Program:Subroutine:DataOrigin:TimeTag:"
1219  "TimeTagFile:Session:Station:REPEAT:vgosDB_Version");
1220  QMap<int, SgNcdfVariable*>::iterator it_v=varById.begin();
1221  for(; it_v!=varById.end(); ++it_v)
1222  {
1223  SgNcdfVariable *v=it_v.value();
1224  if (srvVarNames.contains(v->getName()))
1225  serviceVars_.insert(v->getName().toUpper(), v);
1226  else
1227  contentVars_.insert(v->getName().toUpper(), v);
1228  };
1229  varById.clear();
1230 
1232  "::getData(): read " + QString("").setNum(dimensionByName_.size()) + " dimensions, " +
1233  QString("").setNum(serviceVars_.size()) + " service and " +
1234  QString("").setNum(contentVars_.size()) + " content variables");
1235 
1236  nc_close(ncid);
1237  isOk = true;
1238  return isOk;
1239 };
1240 
1241 
1242 
1243 //
1244 bool SgNetCdf::setServiceVar(const QString& varName, const QString& varValue)
1245 {
1246  QString str("");
1247  SgNcdfVariable *var=new SgNcdfVariable;
1248  int len=varValue.size();
1249  var->setName(varName);
1250  var->setTypeOfData(NC_CHAR);
1251  var->setId(serviceVars_.size());
1252  str.sprintf("Char_x_%d", len);
1253  var->addDimension(str, len, -1);
1254  var->allocateData();
1255  strncpy(var->data2char(), qPrintable(varValue), len);
1256  registerVariable(var, true);
1257  return true;
1258 };
1259 
1260 
1261 
1262 //
1263 void SgNetCdf::setServiceVars(const QString& stub, const QString& dataOrigin, const QString& timeTag,
1264  const QString& timeTagFile)
1265 {
1266  QString str("");
1267  if (stub.size())
1268  setServiceVar(svcStub, stub);
1269  else
1270  std::cout << " no stub! \n";
1271  //
1272  setServiceVar(svcCreateTime, SgMJD::currentMJD().toUtc().toString(SgMJD::F_Simple) + " UTC");
1273  //
1274  if (identities_)
1275  {
1276  if (identities_->getUserName().size())
1277  str = identities_->getUserName();
1278  if (identities_->getAcFullName().size())
1279  str += ", " + identities_->getAcFullName();
1282  str = identities_->getDriverVersion().name() + " executed from ";
1283  else
1284  str = "";
1286  " on " + identities_->getMachineNodeName() + "[" + identities_->getMachineMachineName() + "] " +
1288  //
1289  setServiceVar(svcSubroutine, "Class " + className() + " of " + libraryVersion.name());
1290  };
1291  //
1292  if (fmtVerId_.size())
1294  //
1295  if (dataOrigin.size())
1296  setServiceVar(svcDataOrigin, dataOrigin);
1297  //
1298  if (timeTag.size())
1299  setServiceVar(svcTimeTag, timeTag);
1300  //
1301  if (timeTagFile.size())
1302  setServiceVar(svcTimeTagFile, timeTagFile);
1303  //
1304  if (sessionId_.size())
1306  //
1307  if (stationId_.size())
1309  //
1310  if (bandId_.size())
1312 };
1313 
1314 
1315 
1316 //
1317 void SgNetCdf::registerVariable(SgNcdfVariable* var, bool is4Service)
1318 {
1319  // check the input:
1320  if (!var)
1321  {
1323  "::registerVariable(): the variable is NULL");
1324  return;
1325  };
1326  if (!var->dimensions().size())
1327  {
1329  "::registerVariable(): the variable \"" + var->getName() + "\" has no dimension");
1330  return;
1331  };
1332  QMap<QString, SgNcdfVariable*> &vars=is4Service?serviceVars_:contentVars_;
1333  if (vars.contains(var->getName().toUpper()))
1335  "::registerVariable(): the variable \"" + var->getName() + "\" already in the " +
1336  (is4Service?"service":"content") + " map");
1337  else
1338  vars.insert(var->getName().toUpper(), var);
1339 // contentVars_.insert(var->getName().toUpper(), var);
1340  for (int i=0; i<var->dimensions().size(); i++)
1341  {
1342  SgNcdfDimension *d=var->dimensions().at(i);
1343  if (!dimensionByName_.contains(d->getName()))
1344  dimensionByName_.insert(d->getName(), new SgNcdfDimension(*d));
1345  else // check the dimension:
1346  if (dimensionByName_.value(d->getName())->getN() != d->getN())
1348  "::registerVariable(): the dimension \"" + d->getName() + "\" has different meanings, " +
1349  QString("").setNum(dimensionByName_.value(d->getName())->getN()) + " and " +
1350  QString("").setNum(d->getN()));
1351  };
1352 };
1353 
1354 
1355 
1356 //
1358 {
1359  if (operationMode_ == OM_REGULAR) // normal work:
1360  {
1361  int ncid, rc;
1362  bool isOk=false;
1363  // checking:
1364  if (!fileName_.size())
1365  {
1367  "::putData(): the file name is not specified");
1368  return isOk;
1369  };
1370  if ((rc=nc_create(qPrintable(fileName_), 0, &ncid)) != NC_NOERR)
1371  {
1372  printf("NetCDF: %s\n", nc_strerror(rc));
1374  "::putData(): cannot create the file " + fileName_ + ": " + QString(nc_strerror(rc)));
1375  return isOk;
1376  };
1377  //
1378  // check for REPEATable variables (it can change dimensions):
1379  for (QMap<QString, SgNcdfVariable*>::iterator it=contentVars_.begin(); it!=contentVars_.end(); ++it)
1380  it.value()->check4multiplication();
1381  //
1382  // tell netCDF about our dimensions (describe the dimensions):
1383  for (QMap<QString, SgNcdfDimension*>::iterator it=dimensionByName_.begin(); it!=dimensionByName_.end();
1384  ++it)
1385  {
1386  SgNcdfDimension *dim=it.value();
1387  int dimId;
1388  if ((rc=nc_def_dim(ncid, qPrintable(dim->getName()), dim->getN(), &dimId)) != NC_NOERR)
1389  {
1390  printf("%s\n", nc_strerror(rc));
1392  "::putData(): defining of a new dimension " + dim->getName() + " has been failed");
1393  nc_close(ncid);
1394  return isOk;
1395  };
1396  dim->setId(dimId);
1397  };
1398  //
1399  // describe the variables:
1400  QList<SgNcdfVariable*> variables;
1401  QMap<int, SgNcdfVariable*> varByOrder;
1402  //
1403  // sort the service variables by their ID:
1404  for (QMap<QString, SgNcdfVariable*>::iterator it=serviceVars_.begin(); it!=serviceVars_.end(); ++it)
1405  varByOrder.insert(it.value()->getId(), it.value());
1406  variables = varByOrder.values();
1407  varByOrder.clear();
1408  // sort the content variables by their sizes:
1409  for (QMap<QString, SgNcdfVariable*>::iterator it=contentVars_.begin(); it!=contentVars_.end(); ++it)
1410  varByOrder.insertMulti(it.value()->sizeOfData(), it.value());
1411  // varByOrder.insert(it.value()->getId(), it.value());
1412  //
1413  variables << varByOrder.values();
1414  varByOrder.clear();
1415  for (int i=0; i<variables.size(); i++)
1416  {
1417  SgNcdfVariable *var=variables.at(i);
1418  int nDims=var->dimensions().size();
1419  int *dimids=new int[nDims];
1420  int varId;
1421  for (int j=0; j<nDims; j++)
1422  dimids[j] = dimensionByName_[var->dimensions().at(j)->getName()]->getId();
1423  if ((rc=nc_def_var(ncid, qPrintable(var->getName()), var->getTypeOfData(), nDims, dimids, &varId))
1424  != NC_NOERR)
1425  {
1426  printf("%s\n", nc_strerror(rc));
1428  "::putData(): defining of a new variable " + var->getName() + " has been failed");
1429  nc_close(ncid);
1430  delete[] dimids;
1431  return isOk;
1432  };
1433  delete[] dimids;
1434  var->setId(varId);
1435  for (QMap<QString, SgNcdfAttribute*>::const_iterator it=var->attributeByName().begin();
1436  it!=var->attributeByName().end(); ++it)
1437  {
1438  SgNcdfAttribute *att=it.value();
1439  if ((rc=att->nc_put_attr(ncid, var->getId())) != NC_NOERR)
1440  {
1441  printf("%s: %s\n",
1442  qPrintable("Error specifying an attribute " + att->getName() + " for " + var->getName()),
1443  nc_strerror(rc));
1445  "::putData(): defining the attribute \"" + att->getName() + "\" for variable " +
1446  var->getName() + " has been failed");
1447  nc_close(ncid);
1448  return isOk;
1449  };
1450  };
1451  };
1452  nc_enddef(ncid);
1453  //
1454  // end of definitions,
1455  // data output:
1456  //
1457  for (int i=0; i<variables.size(); i++)
1458  {
1459  SgNcdfVariable *var=variables.at(i);
1460  if ((rc=var->nc_put_var(ncid)) != NC_NOERR)
1461  {
1462  printf("%s: %s\n", qPrintable("Error writting variable to " + fileName_), nc_strerror(rc));
1464  "::putData(): writting the variable " + qPrintable(var->getName()) + " has failed");
1465  nc_close(ncid);
1466  return isOk;
1467  };
1468  };
1469  //
1470  nc_close(ncid);
1471  //
1472  // adjust permissions:
1473  QFile f(fileName_);
1474  QFile::Permissions perm=f.permissions();
1475  if (!f.setPermissions(perm | QFile::WriteGroup))
1477  "::putData(): cannot adjust the permissions of the file \"" + f.fileName() + "\"");
1478  //
1479  isOk = true;
1480  return isOk;
1481  }
1482  else // dry run:
1483  {
1484  if (!fileName_.size())
1485  {
1487  "::putData(): the file name is not specified");
1488  return false;
1489  };
1490 
1491  std::cout << "DRY RUN: The netCDF file will be created: \""
1492  << qPrintable(fileName_) << "\"\n";
1493  return true;
1494  };
1495 };
1496 /*=====================================================================================================*/
1497 
1498 
SgLogger * logger
Definition: SgLogger.cpp:231
static const int dimensionUnityValue
Definition: SgNetCdf.cpp:38
size_t ncdfaux_type_2_size(nc_type type)
Definition: SgNetCdf.cpp:47
void ncdfaux_data_allocate(void *&dest, nc_type type, size_t num)
Definition: SgNetCdf.cpp:78
QString ncdfaux_type_2_string(nc_type xtype)
Definition: SgNetCdf.cpp:188
void ncdfaux_data_free(void *&dest, nc_type type)
Definition: SgNetCdf.cpp:153
static const QString dimensionUnityName("DimUnity")
void ncdfaux_data_allocate_n_copy(void *&dest, const void *src, nc_type type, size_t num)
Definition: SgNetCdf.cpp:116
const SgNcdfDimension dUnity(dimensionUnityName, dimensionUnityValue, -1)
SgVersion libraryVersion("SgLib", 0, 7, 5, "Tuscarora (rc1)", SgMJD(2022, 2, 18, 17, 34))
const QString & getExecBinaryName() const
Definition: SgIdentities.h:279
const QString & getMachineMachineName() const
Definition: SgIdentities.h:303
const QString & getMachineRelease() const
Definition: SgIdentities.h:319
const QString & getMachineNodeName() const
Definition: SgIdentities.h:295
const QString & getAcFullName() const
Definition: SgIdentities.h:239
const SgVersion & getDriverVersion() const
Definition: SgIdentities.h:287
const QString & getExecDir() const
Definition: SgIdentities.h:263
const QString & getUserName() const
Definition: SgIdentities.h:215
const QString & getMachineSysName() const
Definition: SgIdentities.h:311
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_NCDF
Definition: SgLogger.h:66
@ IO_TXT
Definition: SgLogger.h:65
@ F_Simple
Digits: 2010/04/02 17:02:43.6.
Definition: SgMJD.h:68
static SgMJD currentMJD()
Definition: SgMJD.cpp:118
static const QString className()
Definition: SgNetCdf.cpp:269
nc_type getTypeOfData() const
Definition: SgNetCdf.h:157
void setNumOfElements(size_t num)
Definition: SgNetCdf.h:163
void setData(const void *, size_t)
Definition: SgNetCdf.cpp:322
size_t numOfElements_
Definition: SgNetCdf.h:187
void setTypeOfData(nc_type type)
Definition: SgNetCdf.h:162
size_t getNumOfElements() const
Definition: SgNetCdf.h:158
int nc_put_attr(int ncid, int varid)
Definition: SgNetCdf.cpp:369
void setName(const QString &str)
Definition: SgNetCdf.h:161
nc_type typeOfData_
Definition: SgNetCdf.h:186
const void * getData() const
Definition: SgNetCdf.h:159
void debug_output()
Definition: SgNetCdf.cpp:403
int nc_get_attr(int ncid, int varid)
Definition: SgNetCdf.cpp:332
void * data_
Definition: SgNetCdf.h:188
const QString & getName() const
Definition: SgNetCdf.h:156
QString name_
Definition: SgNetCdf.h:185
void setId(int id)
Definition: SgNetCdf.h:104
int getN() const
Definition: SgNetCdf.h:94
const QString & getName() const
Definition: SgNetCdf.h:90
void debug_output()
Definition: SgNetCdf.cpp:239
static const QString className()
Definition: SgNetCdf.cpp:231
QString name_
Definition: SgNetCdf.h:116
void multiplyData(int)
Definition: SgNetCdf.cpp:750
void delAttribute(const QString &)
Definition: SgNetCdf.cpp:641
QMap< QString, SgNcdfAttribute * > attributeByName_
Definition: SgNetCdf.h:294
nc_type getTypeOfData() const
Definition: SgNetCdf.h:222
int getId() const
Definition: SgNetCdf.h:221
int nc_put_var(int ncid)
Definition: SgNetCdf.cpp:709
QMap< QString, SgNcdfDimension * > dimensionByName_
Definition: SgNetCdf.h:292
size_t numOfElements_
Definition: SgNetCdf.h:296
void setId(int id)
Definition: SgNetCdf.h:241
const char * data2char() const
Definition: SgNetCdf.cpp:459
void setName(const QString &name)
Definition: SgNetCdf.h:240
int nc_get_var(int ncid)
Definition: SgNetCdf.cpp:672
void addAttribute(const SgNcdfAttribute &)
Definition: SgNetCdf.cpp:612
void setTypeOfData(nc_type type)
Definition: SgNetCdf.h:242
const int * data2int() const
Definition: SgNetCdf.cpp:503
QString name_
Definition: SgNetCdf.h:290
void allocateData()
Definition: SgNetCdf.cpp:837
const short * data2short() const
Definition: SgNetCdf.cpp:481
const QList< SgNcdfDimension * > & dimensions() const
Definition: SgNetCdf.h:247
int sizeOfData() const
Definition: SgNetCdf.cpp:855
const double * data2double() const
Definition: SgNetCdf.cpp:525
void addDimension(const SgNcdfDimension &d, int idx=-1)
Definition: SgNetCdf.h:259
const QString & getName() const
Definition: SgNetCdf.h:220
void debug_output()
Definition: SgNetCdf.cpp:863
void delDimension(const QString &)
Definition: SgNetCdf.cpp:568
void * data_
Definition: SgNetCdf.h:297
QList< SgNcdfDimension * > dimensions_
Definition: SgNetCdf.h:293
void check4multiplication()
Definition: SgNetCdf.cpp:778
static const QString className()
Definition: SgNetCdf.cpp:419
nc_type typeOfData_
Definition: SgNetCdf.h:295
const QMap< QString, SgNcdfAttribute * > & attributeByName() const
Definition: SgNetCdf.h:248
void calcNumOfElements()
Definition: SgNetCdf.cpp:657
bool setServiceVar(const QString &varName, const QString &varValue)
Definition: SgNetCdf.cpp:1244
static const QString svcSubroutine
Definition: SgNetCdf.h:332
void reset()
Definition: SgNetCdf.cpp:1031
void setServiceVars(const QString &stub, const QString &dataOrigin, const QString &timeTag, const QString &timeTagFile)
Definition: SgNetCdf.cpp:1263
static const QString svcCreatedBy
Definition: SgNetCdf.h:330
static const QString svcDataOrigin
Definition: SgNetCdf.h:334
bool putData()
Definition: SgNetCdf.cpp:1357
QString stationId_
Definition: SgNetCdf.h:464
QMap< QString, SgNcdfDimension * > dimensionByName_
Definition: SgNetCdf.h:457
static const QString svcProgram
Definition: SgNetCdf.h:331
QString fileName_
Definition: SgNetCdf.h:456
static const QString svcTimeTag
Definition: SgNetCdf.h:335
static const QString svcStation
Definition: SgNetCdf.h:338
const SgIdentities * identities_
Definition: SgNetCdf.h:455
QString fmtVerId_
Definition: SgNetCdf.h:462
void registerVariable(SgNcdfVariable *, bool is4Service=false)
Definition: SgNetCdf.cpp:1317
static const QString svcVgosDbVersion
Definition: SgNetCdf.h:333
QMap< QString, SgNcdfVariable * > serviceVars_
Definition: SgNetCdf.h:458
static const QString svcSession
Definition: SgNetCdf.h:337
QMap< QString, SgNcdfVariable * > contentVars_
Definition: SgNetCdf.h:459
QString bandId_
Definition: SgNetCdf.h:465
static const QString svcCreateTime
Definition: SgNetCdf.h:329
@ OM_REGULAR
Definition: SgNetCdf.h:324
static const QString className()
Definition: SgNetCdf.cpp:970
QString sessionId_
Definition: SgNetCdf.h:463
OperationMode operationMode_
Definition: SgNetCdf.h:466
static const QString svcTimeTagFile
Definition: SgNetCdf.h:336
static const QString svcBand
Definition: SgNetCdf.h:339
static const QString svcStub
Definition: SgNetCdf.h:328
bool getData()
Definition: SgNetCdf.cpp:1053
const QString & getSoftwareName() const
Definition: SgVersion.h:254
QString name(NameFormat fmt=NF_Human) const
Definition: SgVersion.cpp:54