General Purpose Geodetic Library
SgDbhImage.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 #include <iostream>
24 #include <stdlib.h>
25 
26 
27 #include <SgDbhImage.h>
28 #include <SgDbhFormat.h>
29 #include <SgLogger.h>
30 #include <SgVersion.h>
31 
32 
33 
34 const QString SgDbhDatumDescriptor::typeNames_[6] = {"R8", "I2", "A2", "D8", "J4", "??"};
35 
36 
37 /*=======================================================================================================
38 *
39 * SgDbhDatumDescriptor, methods:
40 *
41 *======================================================================================================*/
43 {
44  setLCode("ARTIFIC.");
45  setDescription("An undescribed item");
46  dim1_ = dim2_ = dim3_ = 0;
47  modifiedAtVersion_ = nTc_ = nTe_ = -1;
48  offset_ = -1;
49  type_ = T_UNKN;
50 };
51 
52 
53 
54 //
55 void SgDbhDatumDescriptor::setLCode(const QString& lCode)
56 {
57  lCode_ = lCode.leftJustified(8, ' ', true);
58 };
59 
60 
61 
62 //
63 void SgDbhDatumDescriptor::setDescription(const QString& description)
64 {
65  description_ = description.leftJustified(32, '.', true);
66 };
67 
68 
69 
70 //
71 SgDbhDatumDescriptor::SgDbhDatumDescriptor(const QString& lCode, const QString& description)
72 {
73  setLCode(lCode);
74  setDescription(description);
75  dim1_ = dim2_ = dim3_ = 0;
76  modifiedAtVersion_ = nTc_ = nTe_ = -1;
77  offset_ = -1;
78  type_ = T_UNKN;
79 };
80 
81 
82 
83 //
85 {
86  setLCode(descriptor.lCode_);
87  setDescription(descriptor.description_);
88  type_ = descriptor.type_;
89  dim1_ = descriptor.dim1_;
90  dim2_ = descriptor.dim2_;
91  dim3_ = descriptor.dim3_;
93  nTc_ = descriptor.nTc_;
94  nTe_ = descriptor.nTe_;
95  offset_ = descriptor.offset_;
96  return *this;
97 };
98 /*=====================================================================================================*/
99 
100 
101 
102 
103 /*=======================================================================================================
104 *
105 * METHODS:
106 *
107 *======================================================================================================*/
109  canonicalName_(""),
110  history_(),
111  descriptorByLCode_(),
112  listOfDataBlocksToc0_(),
113  listOfObservations_(),
114  listOfNewDescriptors_(),
115  listOfDeletedDescriptors_(),
116  alterCode_("@")
117 {
120  currentVersion_ = -1;
121  dumpStream_ = NULL;
123  format_ = new SgDbhFormat;
124  // test purposes:
125  isSessionCodeAltered_ = false;
126 };
127 
128 
129 
130 //
132 {
133  // clear history list:
135  // just clear the hash
136  descriptorByLCode_.clear();
137  //
138  while (!listOfDataBlocksToc0_.isEmpty())
139  delete listOfDataBlocksToc0_.takeFirst();
140  //
141  // clear list of observations:
143  //
144  while (!listOfNewDescriptors_.isEmpty())
145  delete listOfNewDescriptors_.takeFirst();
146  //
147  while (!listOfDeletedDescriptors_.isEmpty())
148  delete listOfDeletedDescriptors_.takeFirst();
149  //
150  delete startBlock_;
151  startBlock_ = NULL;
152  //
153  delete format_;
154  format_ = NULL;
155 
156  dumpStream_ = NULL;
157 };
158 
159 
160 
161 //
163 {
164  return startBlock_->epoch();
165 };
166 
167 
168 
169 //
171 {
172  return startBlock_->version();
173 };
174 
175 
176 
177 //
178 const QString& SgDbhImage::fileName() const
179 {
180  return startBlock_->dbName();
181 };
182 
183 
184 
185 //
186 const QString& SgDbhImage::sessionDescription() const
187 {
188  return startBlock_->expDescript();
189 };
190 
191 
192 
193 //
194 const QString& SgDbhImage::sessionID() const
195 {
196  return startBlock_->sessionID();
197 };
198 
199 
200 
201 //
202 const QString& SgDbhImage::previousFileName() const
203 {
204  return startBlock_->prevDb();
205 };
206 
207 
208 
209 //
211 {
212  return startBlock_->prevDescript();
213 };
214 
215 
216 
217 //
219 {
220  // clear history list:
221  while (!history_.isEmpty())
222  delete history_.takeFirst();
223 };
224 
225 
226 
227 //
229 {
230  // clear list of observations:
231  while (!listOfObservations_.isEmpty())
232  delete listOfObservations_.takeFirst();
233 };
234 
235 
236 
237 //
238 void SgDbhImage::addHistoryEntry(const QString& text, const SgMJD& t)
239 {
241  entry->setEvent(text, startBlock_->dbName(), currentVersion_, t);
242  history_ << entry;
244 };
245 
246 
247 
248 //
250 {
251  SgDbhDataBlock *dataBlock=NULL;
252 
253  if (descriptor->nTc()==0) //TOC#0:
254  {
255  if (obsNum>=0) // just notify user:
257  QString().sprintf(": properRecord(): obsNum %d is greater or equal 0 for TOC#0",
258  obsNum));
259  dataBlock = listOfDataBlocksToc0_.at(descriptor->nTe());
260  }
261  else // Observations:
262  {
263  if (obsNum<0)
264  {
266  QString().sprintf(": properRecord(): obsNum %d is less than 0",
267  obsNum));
268  return NULL;
269  };
270  if (listOfObservations_.size()<=obsNum)
271  {
273  QString().sprintf(": properRecord(): obsNum %d >= listOfObservations_.size(), %d",
274  obsNum, listOfObservations_.size()));
275  return NULL;
276  };
277  // here ranges of obsNum are OK
278  SgDbhObservationEntry* obsEntry = listOfObservations_.at(obsNum);
279  if (!obsEntry)
280  {
282  QString().sprintf(": properRecord(): Observation entry is NULL for obsNum %d",
283  obsNum));
284  return NULL;
285  };
286  QList<SgDbhDataBlock*> *listOfDataBlocks = obsEntry->dataBlocksFromTocI(descriptor->nTc());
287  if (!listOfDataBlocks)
288  {
290  QString().sprintf(": properRecord(): listOfDataBlocks is NULL for obsNum %d and TOC#%d",
291  obsNum, descriptor->nTc()));
292  return NULL;
293  };
294  dataBlock = listOfDataBlocks->at(descriptor->nTe());
295  };
296 
297  if (!dataBlock)
298  {
300  QString().sprintf(": properRecord(): Data Block is NULL for obsNum %d TOC#%d TE#%d",
301  obsNum, descriptor->nTc(), descriptor->nTe()));
302  return NULL;
303  };
304  QHash<int, SgDbhPhysicalRecord*> *recByType = dataBlock->recordByType();
305  if (!recByType->contains(descriptor->type()))
306  {
308  QString().sprintf(": properRecord(): recordByType_ hash (TOC#%d, TE#%d) does not contain"
309  "the record of type %d", descriptor->nTc(), descriptor->nTe(), descriptor->type()));
310  return NULL;
311  };
312  return recByType->value(descriptor->type());
313 };
314 
315 
316 
317 //
318 QString SgDbhImage::getStr(SgDbhDatumDescriptor *d, int i, int j, int obsNumber)
319 {
320  if (!d)
321  {
323  ": getStr(): descriptor is NULL");
324  return QString("UNDEF");
325  };
326  return ((SgDbhDataRecordString*)properRecord(d, obsNumber))->getValue(d, i,j);
327 };
328 
329 
330 
331 //
332 template<class C> C SgDbhImage::getData(const QString& typeName,
333  SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber)
334 {
335  if (!d)
336  {
338  ": getData(): the " + typeName + " descriptor is NULL");
339  return C (0);
340  };
341  return ((SgDbhDataRecord<C>*)properRecord(d, obsNumber))->value(d, i,j,k);
342 };
343 
344 
345 
346 //
347 double SgDbhImage::getR8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber)
348 {
349  return getData<double>("double:R8", d, i,j,k, obsNumber);
350 };
351 
352 
353 
354 //
355 double SgDbhImage::getD8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber)
356 {
357  return getData<double>("double:D8", d, i,j,k, obsNumber);
358 };
359 
360 
361 
362 //
363 int SgDbhImage::getJ4(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber)
364 {
365  return getData<int>("int:J4", d, i,j,k, obsNumber);
366 };
367 
368 
369 
370 //
371 short SgDbhImage::getI2(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber)
372 {
373  return getData<short>("short:I2", d, i,j,k, obsNumber);
374 };
375 
376 
377 
378 //
379 void SgDbhImage::setStr(SgDbhDatumDescriptor *d, int i, int j, int obsNumber, const QString& str)
380 {
382  {
383  if (!d)
384  {
386  ": setStr(): descriptor is NULL");
387  return;
388  };
389  ((SgDbhDataRecordString*)properRecord(d, obsNumber))->setValue(d, i,j, str);
392  }
393  else
395  ": setStr(): the image is in inconsistent state");
396 };
397 
398 
399 
400 //
401 template<class C>
402 void SgDbhImage::setData(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, C v)
403 {
405  {
406  if (!d)
407  {
409  ": setData(): descriptor is NULL");
410  return;
411  };
412  ((SgDbhDataRecord<C>*)properRecord(d, obsNumber))->access(d, i,j,k) = v;
415  }
416  else
418  ": setData(): the image is in inconsistent state");
419 };
420 
421 
422 
423 //
424 void SgDbhImage::setR8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, double r8)
425 {
426  return setData<double>(d, i,j,k, obsNumber, r8);
427 };
428 
429 
430 
431 //
432 void SgDbhImage::setD8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, double d8)
433 {
434  return setData<double>(d, i,j,k, obsNumber, d8);
435 };
436 
437 
438 
439 //
440 void SgDbhImage::setJ4(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, int j4)
441 {
442  return setData<int>(d, i,j,k, obsNumber, j4);
443 };
444 
445 
446 
447 //
448 void SgDbhImage::setI2(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, short i2)
449 {
450  return setData<short>(d, i,j,k, obsNumber, i2);
451 };
452 
453 
454 
455 //
457 {
458  // check currently read TOC number:
459  if (format_->currentTcNumber()!=0)
460  {
462  QString().sprintf(": copyToc0Content(): Wrong order of calling, current TOC is TOC#%d",
464  // anyway, we ask correct TOC number explicitly, so "return" is commented out
465  /* return; */
466  };
467 
468  // copy header (TOC#0) data to listOfDataBlocksToc0_:
469  SgDbhTcBlock *tcBlock0=format_->listOfTcBlocks()->at(0);
470  for (int teCount=0; teCount<tcBlock0->listOfTeBlocks()->size(); teCount++)
471  {
472  SgDbhDataBlock *dataBlock=new SgDbhDataBlock;
473  *dataBlock = *tcBlock0->listOfTeBlocks()->at(teCount);
474  listOfDataBlocksToc0_.append(dataBlock);
475  };
476  //
477  // collect all parameter descriptors to descriptorByLCode_:
478  for (int i=0; i<format_->listOfTcBlocks()->size(); i++)
479  {
480  SgDbhTcBlock *tcBlock=format_->listOfTcBlocks()->at(i);
481  for (int j=0; j<tcBlock->listOfTeBlocks()->size(); j++)
482  {
483  SgDbhTeBlock *teBlock=tcBlock->listOfTeBlocks()->at(j);
484  for (int k=0; k<teBlock->listOfDescriptors()->size(); k++)
485  {
486  SgDbhDatumDescriptor *descriptor=teBlock->listOfDescriptors()->at(k);
487  // check for duplicates (could happen for old files):
488  if (descriptorByLCode_.contains(descriptor->getLCode()))
489  // complain:
491  QString("").sprintf(": copyToc0Content(): the TOC#0 already contains the parameter [%s]",
492  qPrintable(descriptor->getLCode())));
493  else
494  if (descriptor->getLCode()!="R-FILLER" &&
495  descriptor->getLCode()!="I-FILLER" &&
496  descriptor->getLCode()!="A-FILLER" &&
497  descriptor->getLCode()!="D-FILLER" &&
498  descriptor->getLCode()!="J-FILLER")
499  descriptorByLCode_.insert(descriptor->getLCode(), descriptor);
500  };
501  };
502  };
503 };
504 
505 
506 
507 //
509 {
511 
512 
513 };
514 
515 
516 
517 //
519 {
520  // check lists:
521  if (listOfNewDescriptors_.isEmpty() && listOfDeletedDescriptors_.isEmpty()) // nothing to do:
522  {
524  return;
525  };
526  for (int i=0; i<listOfNewDescriptors_.size(); i++)
527  for (int j=0; j<listOfDeletedDescriptors_.size() && i<listOfNewDescriptors_.size(); j++)
528  {
531  if (d2Add->getLCode() == d2Del->getLCode())
532  {
533  listOfNewDescriptors_.removeAt(i);
534  listOfDeletedDescriptors_.removeAt(j);
535  i--;
536  j--;
537  delete d2Add;
538  delete d2Del;
539  };
540  };
541 
542  int numOfModified=0;
543 
544  // make arrangements:
545  // first, remove parameters to be deleted from the lists and the hashes:
546  while (!listOfDeletedDescriptors_.isEmpty()) // parameters to delete:
547  {
549  for (int tcIdx=0; tcIdx<format_->listOfTcBlocks()->size(); tcIdx++)
550  {
551  SgDbhTcBlock *tcBlock = format_->listOfTcBlocks()->at(tcIdx);
552  for (int teIdx=0; teIdx<tcBlock->listOfTeBlocks()->size(); teIdx++)
553  {
554  SgDbhTeBlock *teBlock = tcBlock->listOfTeBlocks()->at(teIdx);
555  for (int i=0; i<teBlock->listOfDescriptors()->size(); i++)
556  {
557  SgDbhDatumDescriptor* descriptor=teBlock->listOfDescriptors()->at(i);
558  if (descriptor->getLCode() == d->getLCode() && (d->nTc()<0 || d->nTc()==tcIdx)) // got it
559  {
560  // remove pointers from two hashes and the list:
561  tcBlock->descriptorByLCode()->remove(descriptor->getLCode());
562  descriptorByLCode_.remove(descriptor->getLCode());
563  teBlock->listOfDescriptors()->removeAt(i);
564  teBlock->setIsFormatModified(true);
565  // delete the descriptor
566  delete descriptor;
567  i--; // and adjust counter
568  numOfModified++;
569  };
570  };
571  };
572  };
573  delete d;
574  };
576  QString().sprintf(": finisFormatModifying(): deleted %d descriptors",
577  numOfModified));
578 
579  numOfModified = 0;
580  // then, add new parameters to the lists and the hashes:
581  while (!listOfNewDescriptors_.isEmpty()) // new parameters:
582  {
584  SgDbhTcBlock *tcBlock = format_->listOfTcBlocks()->at(d->nTc());
585  SgDbhTeBlock *teBlock = tcBlock->listOfTeBlocks()->at(d->nTe());
586 
587  SgDbhDatumDescriptor* descriptor = new SgDbhDatumDescriptor;
588  *descriptor = *d;
589  int i = 0;
590  // find first record with this type,
591  while (i < teBlock->listOfDescriptors()->size() &&
592  descriptor->type() != teBlock->listOfDescriptors()->at(i)->type())
593  i++;
594  // then move to the last record with this type,
595  while (i < teBlock->listOfDescriptors()->size() &&
596  descriptor->type() == teBlock->listOfDescriptors()->at(i)->type())
597  i++;
598  // and append the descriptor:
599  teBlock->listOfDescriptors()->insert(i, descriptor);
600  teBlock->setIsFormatModified(true);
601  tcBlock->descriptorByLCode()->insert(descriptor->getLCode(), descriptor);
602  descriptorByLCode_.insert(descriptor->getLCode(), descriptor);
603  numOfModified++;
604  delete d;
605  };
607  QString().sprintf(": finisFormatModifying(): added %d descriptors",
608  numOfModified));
609 
610  // adjust service records of the format descriptor:
611  for (int tcIdx=0; tcIdx<format_->listOfTcBlocks()->size(); tcIdx++)
612  {
613  SgDbhTcBlock *tcBlock = format_->listOfTcBlocks()->at(tcIdx);
614  for (int teIdx=0; teIdx<tcBlock->listOfTeBlocks()->size(); teIdx++)
615  tcBlock->listOfTeBlocks()->at(teIdx)->adjustServiceRecords();
616  };
617 
618  // modify data records:
619  // TOC#0:
621  // Observations:
622  for (int i=0; i<listOfObservations_.size(); i++)
623  {
625  for (int tcIdx=0; tcIdx<e->listOfTcsData().size(); tcIdx++)
626  updateDataRecords(e->listOfTcsData().at(tcIdx), tcIdx+1);
627  };
628  // update offsets of the descriptors:
631  ": finisFormatModifying(): data records are adjusted");
633 };
634 
635 
636 
637 //
638 void SgDbhImage::updateDataRecords(QList<SgDbhDataBlock*>* listOfDataBlocks, int tcIdx)
639 {
640  int offset=0, sizeOfType=0, recordLength=0;
641  SgDbhDataBlock *dataBlock=NULL, *newDataBlock=NULL;
642  QList<SgDbhDatumDescriptor*> *listOfDescriptors=NULL;
643  SgDbhPhysicalRecord *newRecord=NULL, *oldRecord=NULL;
645  SgDbhTeBlock *teBlock=NULL;
646  for (int teIdx=0; teIdx<listOfDataBlocks->size(); teIdx++)
647  {
648  dataBlock = listOfDataBlocks->at(teIdx);
649  teBlock = format_->listOfTcBlocks()->at(tcIdx)->listOfTeBlocks()->at(teIdx);
650  if (teBlock->isFormatModified())
651  {
652  listOfDescriptors = teBlock->listOfDescriptors();
653  newDataBlock = new SgDbhDataBlock;
654  for (int i=0; i<listOfDescriptors->size(); i++)
655  {
656  SgDbhDatumDescriptor* descriptor=listOfDescriptors->at(i);
657  if (descriptor->getLCode()=="R-FILLER")
658  {
659  offset = 0;
660  sizeOfType = sizeof(double);
661  recordType = SgDbhDatumDescriptor::T_R8;
662  recordLength = sizeOfType*teBlock->recTe().r8Num();
663  newRecord = new SgDbhDataRecord<double>;
664  newRecord->reSize(recordLength);
665  newDataBlock->listOfRecords()->append(newRecord);
666  newDataBlock->recordByType()->insert(recordType, newRecord);
667  oldRecord = dataBlock->recordByType()->value(recordType);
668  }
669  else if (descriptor->getLCode()=="I-FILLER")
670  {
671  offset = 0;
672  sizeOfType = sizeof(short);
673  recordType = SgDbhDatumDescriptor::T_I2;
674  recordLength = sizeOfType*teBlock->recTe().i2Num();
675  newRecord = new SgDbhDataRecord<short>;
676  newRecord->reSize(recordLength);
677  newDataBlock->listOfRecords()->append(newRecord);
678  newDataBlock->recordByType()->insert(recordType, newRecord);
679  oldRecord = dataBlock->recordByType()->value(recordType);
680  }
681  else if (descriptor->getLCode()=="A-FILLER")
682  {
683  offset = 0;
684  sizeOfType = 2*sizeof(char);
685  recordType = SgDbhDatumDescriptor::T_A2;
686  recordLength = sizeOfType*teBlock->recTe().a2Num();
687  newRecord = new SgDbhDataRecordString;
688  newRecord->reSize(recordLength);
689  newDataBlock->listOfRecords()->append(newRecord);
690  newDataBlock->recordByType()->insert(recordType, newRecord);
691  oldRecord = dataBlock->recordByType()->value(recordType);
692  }
693  else if (descriptor->getLCode()=="D-FILLER")
694  {
695  offset = 0;
696  sizeOfType = sizeof(double);
697  recordType = SgDbhDatumDescriptor::T_D8;
698  recordLength = sizeOfType*teBlock->recTe().d8Num();
699  newRecord = new SgDbhDataRecord<double>;
700  newRecord->reSize(recordLength);
701  newDataBlock->listOfRecords()->append(newRecord);
702  newDataBlock->recordByType()->insert(recordType, newRecord);
703  oldRecord = dataBlock->recordByType()->value(recordType);
704  }
705  else if (descriptor->getLCode()=="J-FILLER")
706  {
707  offset = 0;
708  sizeOfType = sizeof(int);
709  recordType = SgDbhDatumDescriptor::T_J4;
710  recordLength = sizeOfType*teBlock->recTe().j4Num();
711  newRecord = new SgDbhDataRecord<int>;
712  newRecord->reSize(recordLength);
713  newDataBlock->listOfRecords()->append(newRecord);
714  newDataBlock->recordByType()->insert(recordType, newRecord);
715  oldRecord = dataBlock->recordByType()->value(recordType);
716  };
717  // copy data
718  if (descriptor->offset()>-1) // if data exist already, copy it
719  memcpy(newRecord->base() + sizeOfType*offset,
720  oldRecord->base() + sizeOfType*descriptor->offset(),
721  sizeOfType*descriptor->dim1()*descriptor->dim2()*descriptor->dim3());
722  offset += descriptor->dim1()*descriptor->dim2()*descriptor->dim3();
723  };
724  // update the list of record:
725  dataBlock->recordByType()->clear(); // first, clear the hash
726  while (!dataBlock->listOfRecords()->isEmpty()) // then, clear the list
727  delete dataBlock->listOfRecords()->takeFirst();
728  // move pointers from newDataBlock to dataBlock
729  for (int i=0; i<newDataBlock->listOfRecords()->size(); i++)
730  dataBlock->listOfRecords()->append(newDataBlock->listOfRecords()->at(i));
731  QHash<int, SgDbhPhysicalRecord*>::const_iterator j;
732  for (j=newDataBlock->recordByType()->constBegin();
733  j!=newDataBlock->recordByType()->constEnd(); ++j)
734  dataBlock->recordByType()->insert(j.key(), j.value());
735  // at last, clear the temporary data storage:
736  newDataBlock->recordByType()->clear();
737  newDataBlock->listOfRecords()->clear();
738  delete newDataBlock;
739  };
740  };
741 };
742 
743 
744 
745 //
747 {
748  int offset=0;
749  QList<SgDbhDatumDescriptor*> *listOfDescriptors=NULL;
750  SgDbhTcBlock *tcBlock = NULL;
751  SgDbhTeBlock *teBlock = NULL;
752  for (int tcIdx=0; tcIdx<format_->listOfTcBlocks()->size(); tcIdx++)
753  {
754  tcBlock = format_->listOfTcBlocks()->at(tcIdx);
755  for (int teIdx=0; teIdx<tcBlock->listOfTeBlocks()->size(); teIdx++)
756  {
757  teBlock = tcBlock->listOfTeBlocks()->at(teIdx);
758  listOfDescriptors = teBlock->listOfDescriptors();
759  for (int i=0; i<listOfDescriptors->size(); i++)
760  {
761  SgDbhDatumDescriptor* descriptor=listOfDescriptors->at(i);
762  if (descriptor->getLCode()=="R-FILLER")
763  offset = 0;
764  else if (descriptor->getLCode()=="I-FILLER")
765  offset = 0;
766  else if (descriptor->getLCode()=="A-FILLER")
767  offset = 0;
768  else if (descriptor->getLCode()=="D-FILLER")
769  offset = 0;
770  else if (descriptor->getLCode()=="J-FILLER")
771  offset = 0;
772  descriptor->setOffset(offset); // update offset
773  offset += descriptor->dim1()*descriptor->dim2()*descriptor->dim3();
774  };
775  };
776  };
777 };
778 
779 
780 
781 //
783  const QList<SgDbhDataBlock*>* listOfDBlocks, int tcIdx) const
784 {
785  int numOfWrittenPhysRecords = 0;
786  SgDbhServiceRecordDr recDr;
787  SgDbhServiceRecordDe recDe;
788  recDr.setPrefix("DR");
789  recDe.setPrefix("DE");
790  recDr.reSize(24);
791  recDe.reSize(24);
792  recDr.setTcNo(tcIdx);
793  recDr.setNumOfTeBlocks(listOfDBlocks->size());
794  s << recDr;
795  numOfWrittenPhysRecords++;
796  for (int teIdx=0; teIdx<listOfDBlocks->size(); teIdx++)
797  {
798  SgDbhDataBlock* dataBlock = listOfDBlocks->at(teIdx);
799  SgDbhTcBlock *tcBlock = format_->listOfTcBlocks()->at(tcIdx);
800  SgDbhTeBlock *teBlock = tcBlock->listOfTeBlocks()->at(teIdx);
801  recDe.setTeNo(teIdx);
802  recDe.setNumOfR8(teBlock->recTe().r8Num());
803  recDe.setNumOfI2(teBlock->recTe().i2Num());
804  recDe.setNumOfA2(teBlock->recTe().a2Num());
805  recDe.setNumOfD8(teBlock->recTe().d8Num());
806  recDe.setNumOfJ4(teBlock->recTe().j4Num());
807  s << recDe;
808  numOfWrittenPhysRecords++;
809  for (int i=0; i<dataBlock->listOfRecords()->size(); i++)
810  {
811  s << *dataBlock->listOfRecords()->at(i);
812  numOfWrittenPhysRecords++;
813  };
814  };
815  recDe.setAltered();
816  recDe.setNumOfPhRecs(numOfWrittenPhysRecords);
817  s << recDe;
818 };
819 
820 
821 
822 //
824 {
825  bool isOK=true;
827  {
829  ": addDescriptor(): called when the image is not in proper state");
830  return false;
831  };
832  if (!newDescr)
833  {
835  ": addDescriptor(): descriptor is NULL");
836  return false;
837  };
838 
839  // copy input info:
841  *d = *newDescr;
842  // check if it is already in the lists:
843  if (descriptorByLCode_.contains(d->getLCode()))
844  {
846  QString().sprintf(": addDescriptor(): the descriptor [%s] is already in the list",
847  qPrintable(d->getLCode())));
848  return false;
849  };
850  // check parameters of the descriptor:
852  {
854  QString().sprintf(": addDescriptor(): the descriptor [%s] has unknown type",
855  qPrintable(d->getLCode())));
856  return false;
857  };
858  if (d->dim1()*d->dim2()*d->dim3() == 0)
859  {
861  QString().sprintf(": addDescriptor(): the descriptor [%s] has wrong dimensions (%d,%d,%d)",
862  qPrintable(d->getLCode()), d->dim1(), d->dim2(), d->dim3()));
863  return false;
864  };
865  //
866  // adjust what is possible:
868  //
869  if (d->nTc()<0) // ok, if nTc==0 -- that is the TOC#0.
870  {
871  // find out a TOC with smallest number of parameters
872  // (perhaps, later we could got other criteria)
873  int minSize=format_->listOfTcBlocks()->at(1)->descriptorByLCode()->size(), tcMinSize=-1;
874  for (int tcCount=1; tcCount<format_->listOfTcBlocks()->size(); tcCount++)
875  if (minSize>=format_->listOfTcBlocks()->at(tcCount)->descriptorByLCode()->size())
876  {
877  minSize = format_->listOfTcBlocks()->at(tcCount)->descriptorByLCode()->size();
878  tcMinSize = tcCount;
879  };
880  d->setNTc(tcMinSize);
881  }
882  else if (format_->listOfTcBlocks()->size()<=d->nTc()) // check TC index
883  {
884  logger->write(SgLogger::WRN, SgLogger::IO_DBH, className() + ": addDescriptor(): " +
885  QString().sprintf("the TOC number of the descriptor [%s] was adjusted from %d to %d",
886  qPrintable(d->getLCode()), d->nTc(), format_->listOfTcBlocks()->size()-1));
887  d->setNTc(format_->listOfTcBlocks()->size() - 1);
888  };
889  //
890  SgDbhTcBlock *tcBlock=format_->listOfTcBlocks()->at(d->nTc());
891  if (d->nTe()<0)
892  {
893  // find out a te block with smallest number of parameters
894  // (perhaps, later we could got other criteria)
895  int minSize, teMinSize;
896  minSize = tcBlock->listOfTeBlocks()->at(0)->listOfDescriptors()->size();
897  teMinSize = -1;
898  for (int teCount=0; teCount<tcBlock->listOfTeBlocks()->size(); teCount++)
899  if (minSize>=tcBlock->listOfTeBlocks()->at(teCount)->listOfDescriptors()->size())
900  {
901  minSize = tcBlock->listOfTeBlocks()->at(teCount)->listOfDescriptors()->size();
902  teMinSize = teCount;
903  };
904  d->setNTe(teMinSize);
905  }
906  else if (tcBlock->listOfTeBlocks()->size()<=d->nTe()) // check TE index
907  {
909  QString().sprintf(": addDescriptor(): the descriptor [%s] has wrong TE number %d",
910  qPrintable(d->getLCode()), d->nTe()));
911  return false;
912  };
913  //
914  // and offset will be calculated later
915  listOfNewDescriptors_.append(d);
916  return isOK;
917 };
918 
919 
920 
921 //
923 {
924  bool isOK = true;
926  {
928  ": delDescriptor(): called when the image is not in proper state");
929  return false;
930  };
931  if (!delDescr)
932  {
934  ": delDescriptor(): descriptor is NULL");
935  return false;
936  };
937 
938  // copy input info:
940  *d = *delDescr;
941  // check if it is already in the lists:
942  if (!descriptorByLCode_.contains(d->getLCode()))
943  {
945  QString().sprintf(": delDescriptor(): the descriptor [%s] is not a member of the list",
946  qPrintable(d->getLCode())));
947  return false;
948  };
949  if (d->nTc()>=0) // user specified the TOC number, check it:
950  {
951  if (format_->listOfTcBlocks()->size()<=d->nTc())
952  {
954  QString().sprintf(": delDescriptor(): the specified nTc (%d) is less than"
955  " the number of TOCs (%d) for the parameter [%s]",
956  d->nTc(), format_->listOfTcBlocks()->size(), qPrintable(d->getLCode())));
957  return false;
958  };
959  if (!format_->listOfTcBlocks()->at(d->nTc())->descriptorByLCode()->contains(d->getLCode()))
960  {
962  QString().sprintf(": delDescriptor(): the descriptor [%s] is not a member of the TOC#%d",
963  qPrintable(d->getLCode()), d->nTc()));
964  return false;
965  };
966  };
967 
968  listOfDeletedDescriptors_.append(d);
969  return isOK;
970 };
971 
972 
973 
974 //
976 {
977  *dumpStream_ << "== Format dumping:" << endl;
978  for (int tcIdx=0; tcIdx<format_->listOfTcBlocks()->size(); tcIdx++)
979  {
980  SgDbhTcBlock *tcBlock = format_->listOfTcBlocks()->at(tcIdx);
981  tcBlock->dump(*dumpStream_);
982  };
983  *dumpStream_ << "== Format dumped." << endl;
984 };
985 
986 
987 
988 //
990 {
991  // make start block correct for new version:
993  canonicalName_ + QString().sprintf("_V%03d", currentVersion_));
994  // for test purposes:
997  // revise the history:
998  while (history_.last()->getVersion() == currentVersion_)
999  delete history_.takeLast();
1000 };
1001 /*=====================================================================================================*/
1002 
1003 
1004 
1005 
1006 /*=======================================================================================================
1007 *
1008 * FRIENDS:
1009 *
1010 *======================================================================================================*/
1012 {
1013  SgDbhDatumDescriptor *d=NULL;
1014  SgDbhFormat &F=*image.format_;
1015  s.setByteOrder(QDataStream::BigEndian);
1016  //
1017  // initial block:
1018  s >> *image.startBlock_;
1019  if (!image.startBlock_->isOk())
1020  {
1022  "DBH I/O: the start block is wrong; ignoring file");
1023  return s;
1024  };
1025  if (image.dumpStream_)
1026  image.startBlock_->dump(*image.dumpStream_);
1027  //
1028  // history block:
1029  image.clearHistoryList();
1030  SgDbhHistoryEntry *historyEntry=new SgDbhHistoryEntry;
1031  if (image.dumpStream_)
1032  *image.dumpStream_ << "== History Block dump: ==" << endl;
1033  while (!historyEntry->isLast() && historyEntry->isOk())
1034  {
1035  s >> *historyEntry;
1036  if (historyEntry->isHistoryLine())
1037  {
1038  if (image.dumpStream_)
1039  historyEntry->dump(*image.dumpStream_);
1040  image.history_ << historyEntry;
1041  historyEntry = new SgDbhHistoryEntry;
1042  };
1043  };
1044  if (historyEntry->isLast() && image.dumpStream_)
1045  *image.dumpStream_ << "== End of dump ==" << endl;
1046  delete historyEntry;
1047 
1048  F.setDumpStream(image.dumpStream_);
1049  s >> F;
1050  if (image.dumpStream_ && F.isOk())
1051  F.dump(*image.dumpStream_);
1052  //
1053  // TOC #1: general stuff for the session:
1054  F.getBlock(s);
1055  // save it
1056  image.copyToc0Content();
1057  // get info about declared number of observations:
1058  int declaredNumberOfObservations=-1;
1059  d = image.lookupDescriptor("NUM4 OBS");
1060  if (d)
1061  declaredNumberOfObservations = image.getJ4(d, 0,0,0);
1062  else
1063  {
1064  d = image.lookupDescriptor("NUMB OBS");
1065  if (d)
1066  declaredNumberOfObservations = image.getI2(d, 0,0,0);
1067  };
1068  //
1069  int processedTOC=F.listOfTcBlocks()->size() + 1;
1070  int observationNumber=-1;
1071  SgDbhObservationEntry *obsEntry=NULL;
1072  while (!s.atEnd() && F.isOk())
1073  {
1074  // TOCs #2,3,..:
1075  F.getBlock(s);
1076  if (F.isOk())
1077  {
1078  if (processedTOC >= F.currentTcNumber()) // new obs
1079  {
1080  obsEntry = new SgDbhObservationEntry;
1081  observationNumber++;
1082  image.listOfObservations_.append(obsEntry);
1083  };
1084  obsEntry->saveDataBlocksFromTcBlock((processedTOC=F.currentTcNumber()), *F.currentTcBlock());
1085  };
1086  };
1087  //
1088  // general setups:
1091  image.currentVersion_ = image.startBlock_->version() + 1;
1092  image.canonicalName_ = image.startBlock_->dbName().left(9);
1093  // undo contentState flag:
1095  //
1096  // check what we have get and what expected:
1097  if (declaredNumberOfObservations>0 &&
1098  declaredNumberOfObservations!=image.listOfObservations_.size()) // complain:
1100  QString().sprintf("DBH I/O: The number of read observations (%d) differs from the"
1101  " the declared number in the TOC#0 (%d)",
1102  image.listOfObservations_.size(), declaredNumberOfObservations));
1103  else // either no information or the numbers are equal:
1105  QString().sprintf("DBH I/O: read %d observations",
1106  image.listOfObservations_.size()));
1107  return s;
1108 };
1109 
1110 
1111 
1112 //
1114 {
1115  SgDbhServiceRecordDr recDr;
1116  SgDbhServiceRecordDe recDe;
1117  SgDbhFormat &F=*image.format_;
1118  s.setByteOrder(QDataStream::BigEndian);
1119  recDr.setPrefix("DR");
1120  recDe.setPrefix("DE");
1121  recDr.reSize(24);
1122  recDe.reSize(24);
1123  //
1124  // initial block:
1125  s << *image.startBlock_;
1126  //
1127  // history block:
1128  SgDbhHistoryEntry *historyEntry;
1129  for (int i=0; i<image.history_.size(); i++)
1130  {
1131  historyEntry = image.history_.at(i);
1132  s << *historyEntry;
1133  };
1134  // the last is ZZ record:
1135  historyEntry = new SgDbhHistoryEntry;
1136  historyEntry->unsetOkFlag();
1137  s << *historyEntry;
1138  delete historyEntry;
1139  //
1140  // save format description:
1141  s << F;
1142  //
1143  // write data:
1144  // TOC#0:
1145  image.writeDataRecords(s, &image.listOfDataBlocksToc0_, 0);
1146  // Observations:
1147  for (int i=0; i<image.listOfObservations_.size(); i++)
1148  {
1150  for (int tcIdx=0; tcIdx<e->listOfTcsData().size(); tcIdx++)
1151  image.writeDataRecords(s, e->listOfTcsData().at(tcIdx), tcIdx+1);
1152  };
1153  //
1154  return s;
1155 };
1156 //
1157 
1158 
1159 
1160 
1161 
1162 
1163 /*=====================================================================================================*/
1164 //
1165 // aux functions:
1166 //
1167 
1168 
1169 // i/o:
1170 
1171 
1172 /*=====================================================================================================*/
1173 //
1174 // constants:
1175 //
1176 
1177 
1178 /*=====================================================================================================*/
SgDbhStream & operator<<(SgDbhStream &s, const SgDbhImage &image)
SgDbhStream & operator>>(SgDbhStream &s, SgDbhImage &image)
SgLogger * logger
Definition: SgLogger.cpp:231
QHash< int, SgDbhPhysicalRecord * > * recordByType()
Definition: SgDbhFormat.h:575
QList< SgDbhPhysicalRecord * > * listOfRecords()
Definition: SgDbhFormat.h:574
short nTe() const
Definition: SgDbhImage.h:97
static const QString typeNames_[6]
Definition: SgDbhImage.h:116
void setDescription(const QString &description)
Definition: SgDbhImage.cpp:63
int offset() const
Definition: SgDbhImage.h:98
short dim2() const
Definition: SgDbhImage.h:93
void setLCode(const QString &lCode)
Definition: SgDbhImage.cpp:55
const QString & getLCode() const
Definition: SgDbhImage.h:90
short nTc() const
Definition: SgDbhImage.h:96
void setNTe(int nTe)
Definition: SgDbhImage.h:108
Type type() const
Definition: SgDbhImage.h:99
SgDbhDatumDescriptor & operator=(const SgDbhDatumDescriptor &descriptor)
Definition: SgDbhImage.cpp:84
void setOffset(int offset)
Definition: SgDbhImage.h:109
short dim3() const
Definition: SgDbhImage.h:94
short dim1() const
Definition: SgDbhImage.h:92
void setModifiedAtVersion(int V)
Definition: SgDbhImage.h:106
void setNTc(int nTc)
Definition: SgDbhImage.h:107
short currentTcNumber()
Definition: SgDbhFormat.h:781
void setDumpStream(QTextStream *s)
Definition: SgDbhFormat.h:783
SgDbhTcBlock * currentTcBlock()
Definition: SgDbhFormat.h:797
bool isOk() const
Definition: SgDbhFormat.h:779
QList< SgDbhTcBlock * > * listOfTcBlocks()
Definition: SgDbhFormat.h:777
void dump(QTextStream &s)
Definition: SgDbhFormat.h:884
void getBlock(SgDbhStream &)
void setEvent(const QString &, const QString &, int, const SgMJD &)
bool isOk() const
Definition: SgDbhFormat.h:497
void dump(QTextStream &s) const
bool isLast() const
Definition: SgDbhFormat.h:499
void writeDataRecords(SgDbhStream &, const QList< SgDbhDataBlock * > *, int) const
Definition: SgDbhImage.cpp:782
const QString & fileName() const
Definition: SgDbhImage.cpp:178
FormatState formatState_
Definition: SgDbhImage.h:273
void updateDescriptorsParameters()
Definition: SgDbhImage.cpp:746
int fileVersion() const
Definition: SgDbhImage.cpp:170
QList< SgDbhHistoryEntry * > history_
Definition: SgDbhImage.h:281
const QString & sessionID() const
Definition: SgDbhImage.cpp:194
QString canonicalName_
Definition: SgDbhImage.h:275
void startFormatModifying()
Definition: SgDbhImage.cpp:508
double getR8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber=-1)
Definition: SgDbhImage.cpp:347
short getI2(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber=-1)
Definition: SgDbhImage.cpp:371
QList< SgDbhDataBlock * > listOfDataBlocksToc0_
Definition: SgDbhImage.h:287
C getData(const QString &, SgDbhDatumDescriptor *, int, int, int, int=-1)
Definition: SgDbhImage.cpp:332
void addHistoryEntry(const QString &text, const SgMJD &t=SgMJD::currentMJD().toUtc())
Definition: SgDbhImage.cpp:238
void setI2(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, short i2)
Definition: SgDbhImage.cpp:448
double getD8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber=-1)
Definition: SgDbhImage.cpp:355
void setJ4(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, int j4)
Definition: SgDbhImage.cpp:440
void setData(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, C r8)
Definition: SgDbhImage.cpp:402
ContentState contentState_
Definition: SgDbhImage.h:272
QString alterCode_
Definition: SgDbhImage.h:296
SgMJD fileCreationEpoch() const
Definition: SgDbhImage.cpp:162
QList< SgDbhDatumDescriptor * > listOfNewDescriptors_
Definition: SgDbhImage.h:291
SgDbhStartBlock * startBlock_
Definition: SgDbhImage.h:279
void dumpFormat()
Definition: SgDbhImage.cpp:975
void setD8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, double d8)
Definition: SgDbhImage.cpp:432
void setStr(SgDbhDatumDescriptor *d, int i, int j, int obsNumber, const QString &str)
Definition: SgDbhImage.cpp:379
void copyToc0Content()
Definition: SgDbhImage.cpp:456
QList< SgDbhDatumDescriptor * > listOfDeletedDescriptors_
Definition: SgDbhImage.h:292
void finisFormatModifying()
Definition: SgDbhImage.cpp:518
const QString & sessionDescription() const
Definition: SgDbhImage.cpp:186
QHash< QString, SgDbhDatumDescriptor * > descriptorByLCode_
Definition: SgDbhImage.h:285
QTextStream * dumpStream_
Definition: SgDbhImage.h:277
void clearListOfObservations()
Definition: SgDbhImage.cpp:228
const QString & previousFileName() const
Definition: SgDbhImage.cpp:202
bool delDescriptor(SgDbhDatumDescriptor *)
Definition: SgDbhImage.cpp:922
void clearHistoryList()
Definition: SgDbhImage.cpp:218
@ FS_FormatAltered
Definition: SgDbhImage.h:161
@ FS_FormatFromFile
Definition: SgDbhImage.h:159
@ FS_FormatAltering
Definition: SgDbhImage.h:160
@ CS_DataAltered
Definition: SgDbhImage.h:156
@ CS_DataFromFile
Definition: SgDbhImage.h:155
QList< SgDbhObservationEntry * > listOfObservations_
Definition: SgDbhImage.h:289
void setR8(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber, double r8)
Definition: SgDbhImage.cpp:424
SgDbhDatumDescriptor * lookupDescriptor(const char *tag)
Definition: SgDbhImage.h:341
SgDbhPhysicalRecord * properRecord(SgDbhDatumDescriptor *, int)
Definition: SgDbhImage.cpp:249
void updateDataRecords(QList< SgDbhDataBlock * > *, int)
Definition: SgDbhImage.cpp:638
bool addDescriptor(SgDbhDatumDescriptor *)
Definition: SgDbhImage.cpp:823
int currentVersion_
Definition: SgDbhImage.h:274
SgDbhFormat * format_
Definition: SgDbhImage.h:283
bool isSessionCodeAltered_
Definition: SgDbhImage.h:295
const QString & previousFileDescription() const
Definition: SgDbhImage.cpp:210
QString getStr(SgDbhDatumDescriptor *d, int i, int j, int obsNumber=-1)
Definition: SgDbhImage.cpp:318
int getJ4(SgDbhDatumDescriptor *d, int i, int j, int k, int obsNumber=-1)
Definition: SgDbhImage.cpp:363
void prepare2save()
Definition: SgDbhImage.cpp:989
const QString className() const
Definition: SgDbhImage.h:197
QList< SgDbhDatumDescriptor * > * listOfDescriptors()
Definition: SgDbhFormat.h:540
void saveDataBlocksFromTcBlock(int TocNumber, SgDbhTcBlock &tcBlock)
QList< QList< SgDbhDataBlock * > * > & listOfTcsData()
Definition: SgDbhFormat.h:733
QList< SgDbhDataBlock * > * dataBlocksFromTocI(int tocNumber) const
Definition: SgDbhFormat.h:734
virtual char * base()
Definition: SgDbhFormat.h:78
virtual void reSize(int length)
Definition: SgDbhFormat.cpp:90
void setNumOfD8(int num)
Definition: SgDbhFormat.h:417
void setNumOfR8(int num)
Definition: SgDbhFormat.h:414
void setNumOfJ4(int num)
Definition: SgDbhFormat.h:418
void setNumOfI2(int num)
Definition: SgDbhFormat.h:415
void setTeNo(int no)
Definition: SgDbhFormat.h:413
void setNumOfPhRecs(int num)
Definition: SgDbhFormat.h:419
void setNumOfA2(int num)
Definition: SgDbhFormat.h:416
void setTcNo(int no)
Definition: SgDbhFormat.h:369
void setNumOfTeBlocks(int num)
Definition: SgDbhFormat.h:370
void setPrefix(const char prefix[2])
Definition: SgDbhFormat.h:183
void rotateVersion(int newVersion, const QString &newFileName)
const QString & prevDescript() const
Definition: SgDbhFormat.h:466
const QString & prevDb() const
Definition: SgDbhFormat.h:465
void dump(QTextStream &) const
void alternateCode(const QString &)
bool isOk() const
Definition: SgDbhFormat.h:459
const QString & expDescript() const
Definition: SgDbhFormat.h:463
int version() const
Definition: SgDbhFormat.h:461
const QString & dbName() const
Definition: SgDbhFormat.h:462
const QString & sessionID() const
Definition: SgDbhFormat.h:464
SgMJD epoch() const
Definition: SgDbhFormat.h:460
QList< SgDbhTeBlock * > * listOfTeBlocks()
Definition: SgDbhFormat.h:685
QHash< QString, SgDbhDatumDescriptor * > * descriptorByLCode()
Definition: SgDbhFormat.h:686
void dump(QTextStream &s) const
const SgDbhServiceRecordTe & recTe()
Definition: SgDbhFormat.h:616
void setIsFormatModified(bool Is)
Definition: SgDbhFormat.h:615
bool isFormatModified() const
Definition: SgDbhFormat.h:614
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_DBH
Definition: SgLogger.h:67
Definition: SgMJD.h:59