10 #include "fnetorderstream.h"
16 class Array2dFileLabel
28 mutable string m_strDate;
30 static const int L_EMPTY = 0;
31 static const int L_HISTORY = 1;
32 static const int L_USER = 2;
36 Array2dFileLabel(const char* const str, double ctime = 0.);
38 Array2dFileLabel(const int type, const char* const str, double ctime = 0.);
42 const string& getLabelString (void) const
43 { return m_strLabel; }
45 kfloat64 getCalcTime (void) const
46 { return m_calcTime; }
48 kfloat64 getLabelType (void) const
49 { return m_labelType; }
51 string& setLabelString (const char* const str)
52 { m_strLabel = str; return (m_strLabel); }
54 string& setLabelString (const string& str)
55 { m_strLabel = str; return (m_strLabel); }
57 const string& getDateString () const;
61 Array2dFileLabel (const Array2dFileLabel&);
62 Array2dFileLabel& operator= (const Array2dFileLabel&);
72 bool headerWrite (void);
74 bool headerRead (void);
76 bool arrayDataRead (void);
78 bool labelSeek (unsigned int label_num);
80 Array2dFile (const Array2dFile& rhs); // copy constructor
81 Array2dFile& operator= (const Array2dFile&); // assignment operator
89 frnetorderstream *m_pFS;
94 kuint16 axis_increment_known;
95 kfloat64 mIncX, mIncY;
96 kuint16 axis_extent_known;
97 kfloat64 mMinX, mMaxX, mMinY, mMaxY;
98 kfloat64 mOffsetPV, mScalePV;
108 static const int INT8 = 1;
109 static const int UINT8 = 2;
110 static const int INT16 = 3;
111 static const int UINT16 = 4;
112 static const int INT32 = 5;
113 static const int UINT32 = 6;
114 static const int FLOAT32 = 7;
115 static const int FLOAT64 = 8;
117 Array2dFile (unsigned int nx, unsigned int ny);
118 Array2dFile (const char* const filename);
119 Array2dFile (const char* const filename, unsigned int nx, unsigned int ny);
122 unsigned int getNumLabels (void) const
123 { return num_labels; }
125 bool labelRead (Array2dFileLabel& label, unsigned int label_num);
127 void labelAdd (const Array2dFileLabel& label);
129 void labelAdd (const char* const m_strLabel, double calc_time=0.);
131 void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
133 void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
135 void fileClose (void);
137 void setPixelType (int type)
138 { mPixelType = type; }
140 kuint32 nx (void) const
143 kuint32 ny (void) const
146 void setAxisIncrement (double mIncX, double mIncY);
148 void setAxisExtent (double mMinX, double mMaxX, double mMinY, double mMaxY);
150 void getPixelValueRange (T& pvmin, T& pvmax) const;
152 void doPixelOffsetScale (double offset, double scale);
154 void printLabels (ostream& os);
156 T** getArray (void) const
157 { return (array.getArray()); }
159 bool arrayDataWrite (void);
161 void arrayDataClear (void);
163 bool fileRead (void);
165 bool fileCreate (void);
167 const string& GetFilename (void) const
173 Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
178 array.initSetSize(mNX, mNY);
182 Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
188 array.initSetSize(mNX, mNY);
192 Array2dFile<T>::Array2dFile (const char * const str)
200 Array2dFile<T>::init (void)
202 mPixelSize = sizeof(T);
203 signature = ('I' * 256 + 'F');
208 axis_increment_known = false;
209 axis_extent_known = false;
211 mMinX = mMaxX = mMinY = mMaxY = 0;
217 const type_info& t_id = typeid(T);
218 cout << t_id.name() << endl;
219 const type_info& comp_id = typeid(T);
222 mPixelType = FLOAT64;
223 else if (t_id == typeid(kfloat32))
224 mPixelType = FLOAT32;
225 else if (t_id == typeid(kint32))
227 else if (t_id == typeid(kuint32))
229 else if (t_id == typeid(kint16))
231 else if (t_id == typeid(kuint16))
233 else if (t_id == typeid(kint8))
235 else if (t_id == typeid(kuint8))
241 bHeaderWritten = false;
242 bDataWritten = false;
246 Array2dFile<T>::~Array2dFile (void)
254 Array2dFile<T>::fileClose (void)
265 Array2dFile<T>::fileCreate (void)
267 m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::trunc | ios::binary);
269 sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str());
278 Array2dFile<T>::fileRead (void)
280 m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::binary | ios::nocreate);
282 sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str());
289 array.initSetSize(mNX, mNY);
298 Array2dFile<T>::setAxisIncrement (double incX, double incY)
300 axis_increment_known = true;
307 Array2dFile<T>::setAxisExtent (double minX, double maxX, double minY, double maxY)
309 axis_extent_known = true;
318 Array2dFile<T>::getPixelValueRange (T& pvmin, T& pvmax) const
320 T** da = array.getArray();
322 pvmax = pvmin = da[0][0];
323 for (int ix = 0; ix < mNX; ix++)
324 for (int iy = 0; iy < mNY; iy++)
325 if (pvmax < da[ix][iy])
327 else if (pvmin > da[ix][iy])
334 Array2dFile<T>::doPixelOffsetScale (double offset, double scale)
336 T** ad = array.getArray();
341 for (unsigned int ix = 0; ix < mNX; ix++)
342 for (unsigned int iy = 0; iy < mNY; iy++)
343 ad[ix][iy] = (ad[ix][iy] - offset) * scale;
349 Array2dFile<T>::headerRead (void)
352 sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
357 kuint16 file_signature;
358 kuint16 file_mPixelSize;
359 kuint16 file_mPixelType;
361 m_pFS->readInt16 (headersize);
362 m_pFS->readInt16 (file_signature);
363 m_pFS->readInt16 (num_labels);
364 m_pFS->readInt16 (file_mPixelType);
365 m_pFS->readInt16 (file_mPixelSize);
366 m_pFS->readInt32 (mNX);
367 m_pFS->readInt32 (mNY);
368 m_pFS->readInt16 (axis_increment_known);
369 m_pFS->readFloat64 (mIncX);
370 m_pFS->readFloat64 (mIncY);
371 m_pFS->readInt16 (axis_extent_known);
372 m_pFS->readFloat64 (mMinX);
373 m_pFS->readFloat64 (mMaxX);
374 m_pFS->readFloat64 (mMinY);
375 m_pFS->readFloat64 (mMaxY);
376 m_pFS->readFloat64 (mOffsetPV);
377 m_pFS->readFloat64 (mScalePV);
379 int read_headersize = m_pFS->tellg();
380 if (read_headersize != headersize) {
381 sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize);
384 if (file_signature != signature) {
385 sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature);
388 if (file_mPixelType != mPixelType) {
389 sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType);
392 if (file_mPixelSize != mPixelSize) {
393 sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize);
402 Array2dFile<T>::headerWrite (void)
405 sys_error (ERR_WARNING, "Tried to write header with file closed");
410 m_pFS->writeInt16 (headersize);
411 m_pFS->writeInt16 (signature);
412 m_pFS->writeInt16 (num_labels);
413 m_pFS->writeInt16 (mPixelType);
414 m_pFS->writeInt16 (mPixelSize);
415 m_pFS->writeInt32 (mNX);
416 m_pFS->writeInt32 (mNY);
417 m_pFS->writeInt16 (axis_increment_known);
418 m_pFS->writeFloat64 (mIncX);
419 m_pFS->writeFloat64 (mIncY);
420 m_pFS->writeInt16 (axis_extent_known);
421 m_pFS->writeFloat64 (mMinX);
422 m_pFS->writeFloat64 (mMaxX);
423 m_pFS->writeFloat64 (mMinY);
424 m_pFS->writeFloat64 (mMaxY);
425 m_pFS->writeFloat64 (mOffsetPV);
426 m_pFS->writeFloat64 (mScalePV);
428 headersize = m_pFS->tellp();
429 m_pFS->writeInt16 (headersize);
436 Array2dFile<T>::arrayDataWrite (void)
439 sys_error (ERR_WARNING, "Tried to arrayDataWrite with !m_pFS");
443 T** da = array.getArray();
447 m_pFS->seekp (headersize);
448 for (unsigned int ix = 0; ix < mNX; ix++) {
449 if (NativeBigEndian()) {
450 for (unsigned int iy = 0; iy < mNY; iy++) {
451 T value = da[ix][iy];
452 ConvertReverseNetworkOrder (&value, sizeof(T));
453 m_pFS->write (&value, mPixelSize);
456 m_pFS->write (da[ix], sizeof(T) * mNY);
464 Array2dFile<T>::arrayDataRead (void)
467 sys_error (ERR_WARNING, "Tried to arrayDataRead with !m_pFS");
471 T** da = array.getArray();
475 m_pFS->seekg (headersize);
477 for (int ix = 0; ix < mNX; ix++) {
478 if (NativeBigEndian()) {
479 for (unsigned int iy = 0; iy < mNY; iy++) {
480 m_pFS->read (&pixelBuffer, mPixelSize);
481 ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T));
482 da[ix][iy] = pixelBuffer;
485 m_pFS->read (da[ix], sizeof(T) * mNY);
494 Array2dFile<T>::labelSeek (unsigned int label_num)
496 if (label_num > num_labels) {
497 sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]");
501 if (array.getArray() == NULL) { // Could not have written data if array not allocated
502 sys_error (ERR_WARNING, "array == NULL [labelSeek]");
506 off_t pos = headersize + array.sizeofArray();
509 for (int i = 0; i < label_num; i++)
511 pos += 22; // Skip to string length
515 m_pFS->readInt16 (strlength);
516 pos += 2 + strlength; // Skip label string length + data
528 Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
530 if (label_num >= num_labels) {
531 sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]");
535 if (! labelSeek (label_num)) {
536 sys_error (ERR_WARNING, "Error calling labelSeek");
540 m_pFS->readInt16 (label.m_labelType);
541 m_pFS->readInt16 (label.m_year);
542 m_pFS->readInt16 (label.m_month);
543 m_pFS->readInt16 (label.m_day);
544 m_pFS->readInt16 (label.m_hour);
545 m_pFS->readInt16 (label.m_minute);
546 m_pFS->readInt16 (label.m_second);
547 m_pFS->readFloat64 (label.m_calcTime);
550 m_pFS->readInt16 (strlength);
551 char str [strlength+1];
552 m_pFS->read (str, strlength);
554 label.m_strLabel = str;
562 Array2dFile<T>::labelAdd (const char* const lstr, double calc_time=0.)
564 labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
569 Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
571 Array2dFileLabel label (type, lstr, calc_time);
578 Array2dFile<T>::labelAdd (const Array2dFileLabel& label)
580 labelSeek (num_labels);
582 m_pFS->writeInt16 (label.m_labelType);
583 m_pFS->writeInt16 (label.m_year);
584 m_pFS->writeInt16 (label.m_month);
585 m_pFS->writeInt16 (label.m_day);
586 m_pFS->writeInt16 (label.m_hour);
587 m_pFS->writeInt16 (label.m_minute);
588 m_pFS->writeInt16 (label.m_second);
589 m_pFS->writeFloat64 (label.m_calcTime);
590 kuint16 strlength = label.m_strLabel.length();
591 m_pFS->writeInt16 (strlength);
592 m_pFS->write (label.m_strLabel.c_str(), strlength);
601 Array2dFile<T>::labelsCopy (Array2dFile& copyFile, const char* const idStr)
604 for (int i = 0; i < copyFile.getNumLabels(); i++) {
606 copyFile.labelRead (l, i);
607 string lstr = l.getLabelString();
609 l.setLabelString (lstr);
616 Array2dFile<T>::arrayDataClear (void)
618 T** v = array.getArray();
620 for (unsigned int ix = 0; ix < mNX; ix++)
621 for (unsigned int iy = 0; iy < mNY; iy++)
628 Array2dFile<T>::printLabels (ostream& os)
630 int nlabels = getNumLabels();
632 for (int i = 0; i < nlabels; i++) {
633 Array2dFileLabel label;
634 labelRead (label, i);
636 if (label.getLabelType() == Array2dFileLabel::L_HISTORY) {
637 os << "History: " << endl;
638 os << " " << label.getLabelString() << endl;
639 os << " calc time = " << label.getCalcTime() << " secs" << endl;
640 os << " Timestamp = " << label.getDateString() << endl;
641 } else if (label.getLabelType() == Array2dFileLabel::L_USER) {
642 os << "Note: " << label.getLabelString() << endl;
643 os << " Timestamp = %s" << label.getDateString() << endl;
653 class F32Image : public Array2dFile<kfloat32>
656 F32Image (const char* const fname, unsigned int nx, unsigned int ny)
657 : Array2dFile<kfloat32>::Array2dFile (fname, nx, ny)
659 setPixelType (FLOAT32);
662 F32Image (unsigned int nx, unsigned int ny)
663 : Array2dFile<kfloat32>::Array2dFile (nx, ny)
665 setPixelType (FLOAT32);
668 F32Image (const char* const fname)
669 : Array2dFile<kfloat32>::Array2dFile (fname)
671 setPixelType (FLOAT32);
675 MPI::Datatype getMPIDataType (void) const
676 { return MPI::FLOAT; }
680 F32Image (const F32Image& rhs); //copy constructor
681 F32Image& operator= (const F32Image& rhs); // assignment operator
685 class F64Image : public Array2dFile<kfloat64>
689 F64Image (const char* const fname, unsigned int nx, unsigned int ny)
690 : Array2dFile<kfloat64>::Array2dFile (fname, nx, ny)
692 setPixelType (FLOAT64);
695 F64Image (unsigned int nx, unsigned int ny)
696 : Array2dFile<kfloat64>::Array2dFile (nx, ny)
698 setPixelType (FLOAT64);
701 F64Image (const char* const fname)
702 : Array2dFile<kfloat64>::Array2dFile (fname)
704 setPixelType (FLOAT64);
708 MPI::Datatype getMPIDataType (void) const
709 { return MPI::DOUBLE; }
712 F64Image (const F64Image& rhs); //copy constructor
713 F64Image& operator= (const F64Image& rhs); // assignment operator
716 #undef IMAGEFILE_64_BITS
717 #ifdef IMAGEFILE_64_BITS
718 typedef F64Image ImageFileBase;
719 typedef kfloat64 ImageFileValue;
720 typedef kfloat64* ImageFileColumn;
721 typedef kfloat64** ImageFileArray;
723 typedef F32Image ImageFileBase;
724 typedef kfloat32 ImageFileValue;
725 typedef kfloat32* ImageFileColumn;
726 typedef kfloat32** ImageFileArray;
730 class ImageFile : public ImageFileBase
733 ImageFile (const char* const fname, unsigned int nx, unsigned int ny)
734 : ImageFileBase (fname, nx, ny)
737 ImageFile (unsigned int nx, unsigned int ny)
738 : ImageFileBase (nx, ny)
741 ImageFile (const char* const fname)
742 : ImageFileBase (fname)
745 void filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param);
747 void statistics (double& min, double& max, double& mean, double& mode, double& median, double& stddev) const;
749 void printStatistics (ostream& os) const;
751 bool comparativeStatistics (const ImageFile& imComp, double& d, double& r, double& e) const;
753 bool printComparativeStatistics (const ImageFile& imComp, ostream& os) const;
757 int displayScaling (const int scaleFactor, ImageFileValue pmin, ImageFileValue pmax);