USGS

Isis 3.0 Object Programmers' Reference

Home

ProcessMosaic.cpp
Go to the documentation of this file.
1 
22 #include "Preference.h"
23 
24 #include "Application.h"
25 #include "IException.h"
26 #include "IString.h"
27 #include "Portal.h"
28 #include "ProcessMosaic.h"
29 #include "Pvl.h"
30 #include "SerialNumber.h"
31 #include "SpecialPixel.h"
32 #include "Table.h"
33 
34 using namespace std;
35 
36 namespace Isis {
40  const char *ProcessMosaic::TRACKING_TABLE_NAME = "InputImages";
41 
47  ProcessMosaic::ProcessMosaic() {
48  // Set the BandBin Match
49  SetBandBinMatch(true);
50 
51  // Initialize the structure Track Info
52  m_trackingEnabled = false;
53  m_createOutputMosaic = false;
54  m_bandPriorityBandNumber = 0;
55  m_bandPriorityKeyName = "";
56  m_bandPriorityKeyValue = "";
57  m_bandPriorityUseMaxValue = false;
58 
59  // Initialize the Special Pixel Flags
60  m_placeHighSatPixels = false;
61  m_placeLowSatPixels = false;
62  m_placeNullPixels = false;
63 
64  // Default Priority OnTop
65  m_imageOverlay = PlaceImagesOnTop;
66 
67  m_enforceMatchDEM = false;
68 
69  // Initialize the data members
70  m_iss = -1;
71  m_isl = -1;
72  m_isb = -1;
73  m_ins = -1;
74  m_inl = -1;
75  m_inb = -1;
76  m_oss = -1;
77  m_osl = -1;
78  m_osb = -1;
79  m_onb = -1;
80  }
81 
82 
84  ProcessMosaic::~ProcessMosaic() {
85  }
86 
87 
114  void ProcessMosaic::StartProcess(const int &os, const int &ol, const int &ob) {
115  // Error checks ... there must be one input and one output
116  if ((OutputCubes.size() != 1) || (InputCubes.size() != 1)) {
117  QString m = "You must specify exactly one input and one output cube";
118  throw IException(IException::Programmer, m, _FILEINFO_);
119  }
120 
121  bool bTrackExists = false;
122  if (!m_createOutputMosaic) {
123  bTrackExists = GetTrackStatus();
124  }
125 
126  int ins = m_ins;
127  int inl = m_inl;
128  int inb = m_inb;
129  int iss = m_iss;
130  int isl = m_isl;
131  int isb = m_isb;
132 
133  if (ins == -1)
134  ins = (int)InputCubes[0]->sampleCount();
135 
136  if (inl == -1)
137  inl = (int)InputCubes[0]->lineCount();
138 
139  if (inb == -1)
140  inb = (int)InputCubes[0]->bandCount();
141 
142  // Adjust the input sub-area if it overlaps any edge of the output cube
143  m_oss = os;
144  m_osl = ol;
145  m_osb = ob;
146 
147  // Left edge
148  if (m_oss < 1) {
149  iss = iss - m_oss + 1;
150  ins = ins + m_oss - 1;
151  m_oss = 1;
152  }
153  // Top edge
154  if (m_osl < 1) {
155  isl = isl - m_osl + 1;
156  inl = inl + m_osl - 1;
157  m_osl = 1;
158  }
159  // Right edge
160  if ((m_oss + ins - 1) > OutputCubes[0]->sampleCount()) {
161  ins = OutputCubes[0]->sampleCount() - m_oss + 1;
162  }
163  // Bottom edge
164  if ((m_osl + inl - 1) > OutputCubes[0]->lineCount()) {
165  inl = OutputCubes[0]->lineCount() - m_osl + 1;
166  }
167 
168  PvlGroup imgPosition("ImageLocation");
169  imgPosition += PvlKeyword("File", InputCubes[0]->fileName());
170  imgPosition += PvlKeyword("StartSample", toString(m_oss));
171  imgPosition += PvlKeyword("StartLine", toString(m_osl));
172  m_imagePositions += imgPosition;
173 
174  // Tests for completly off the mosaic
175  if ((ins < 1) || (inl < 1)) {
176  QString m = "The input cube does not overlap the mosaic";
177  throw IException(IException::User, m, _FILEINFO_);
178  }
179 
180  // Band Adjustments
181  if (m_osb < 1) {
182  isb = isb - m_osb + 1;
183  inb = inb + m_osb - 1;
184  m_osb = 1;
185  }
186 
187  p_progress->SetMaximumSteps(
188  (int)InputCubes[0]->lineCount() * (int)InputCubes[0]->bandCount());
189  p_progress->CheckStatus();
190 
191  // Tracking is done for:
192  // (1) Band priority,
193  // (2) Ontop and Beneath priority with number of bands equal to 1,
194  // (3) Ontop priority with all the special pixel flags set to true
195  if (m_trackingEnabled) {
196  if (!(m_imageOverlay == UseBandPlacementCriteria ||
197  ((m_imageOverlay == PlaceImagesOnTop || m_imageOverlay == PlaceImagesBeneath) &&
198  // tracking band was already created for Tracking=true
199  (OutputCubes[0]->bandCount()-1) == 1) ||
200  (m_imageOverlay == PlaceImagesOnTop && m_placeHighSatPixels && m_placeLowSatPixels &&
201  m_placeNullPixels)) ){
202  QString m = "Tracking cannot be True for multi-band Mosaic with ontop or beneath priority";
203  throw IException(IException::Programmer, m, _FILEINFO_);
204  }
205  }
206 
207  // *******************************************************************************
208 
209  Pvl *inLab = InputCubes[0]->label();
210  // Create / Match DEM Shape Model if bMatchDEM Flag is enabled
211  if (m_enforceMatchDEM){
212  MatchDEMShapeModel();
213  }
214 
215  // Check to make sure the bandbins match if necessary
216  if (m_enforceBandBinMatch) {
217  Pvl *outLab = OutputCubes[0]->label();
218 
219  if (inLab->findObject("IsisCube").hasGroup("BandBin")) {
220  // Check to make sure the output cube has a bandbin group & make sure it
221  // matches the input cube bandbin group
222  if (!m_createOutputMosaic && outLab->findObject("IsisCube").hasGroup("BandBin")) {
223  MatchBandBinGroup(isb, inb);
224  }
225  // Otherwise copy the input cube bandbin to the output file
226  else {
227  AddBandBinGroup(isb);
228  }
229  }
230  // BandBin group is not found
231  else {
232  QString m = "Match BandBin cannot be True when the Image does not have the BandBin group";
233  throw IException(IException::Programmer, m, _FILEINFO_);
234  }
235  }
236  // Match BandBin set to false and CREATE and TRACKING is true
237  else {
238  if (m_createOutputMosaic) {
239  if (inLab->findObject("IsisCube").hasGroup("BandBin")) {
240  AddBandBinGroup(isb);
241  }
242  else {
243  AddDefaultBandBinGroup();
244  }
245  }
246  }
247 
248  // Even if the track flag is off, if the track table exists continue tracking
249  if (bTrackExists) {
250  m_trackingEnabled = true;
251  }
252 
253  int iOriginBand = 0, iChanged = 0;
254 
255  // Do this before SetMosaicOrigin as we don't want to set the filename
256  // in the table unless the band info is valid
257  int bandPriorityInputBandNumber = -1;
258  int bandPriorityOutputBandNumber = -1;
259  if (m_imageOverlay == UseBandPlacementCriteria ) {
260  bandPriorityInputBandNumber = GetBandIndex(true);
261  bandPriorityOutputBandNumber = GetBandIndex(false);
262  }
263 
264  // Image name into the table & Get the index for this input file
265  int iIndex = GetIndexOffsetByPixelType();
266 
267  // Set the Mosaic Origin is Tracking is enabled
268  if (m_trackingEnabled) {
269  SetMosaicOrigin(iIndex);
270  }
271  else if (m_imageOverlay == AverageImageWithMosaic && m_createOutputMosaic) {
272  ResetCountBands();
273  }
274 
275  m_onb = OutputCubes[0]->bandCount();
276 
277  if (m_trackingEnabled) {
278  //Get the last band set aside for "Origin" 1 based
279  iOriginBand = OutputCubes[0]->bandCount();
280  iChanged = 0;
281 
282  // For mosaic creation, the input is copied onto mosaic by default
283  if (m_imageOverlay == UseBandPlacementCriteria && !m_createOutputMosaic) {
284  BandComparison(iss, isl, isb, ins, inl, inb,
285  bandPriorityInputBandNumber, bandPriorityOutputBandNumber, iIndex);
286  }
287  }
288  else if (m_imageOverlay == AverageImageWithMosaic) {
289  m_onb /= 2;
290  if (m_onb < 1) {
291  QString msg = "The mosaic cube needs a count band.";
292  throw IException(IException::Unknown, msg, _FILEINFO_);
293  }
294  }
295 
296 
297  // Process Band Priority with no tracking
298  if (m_imageOverlay == UseBandPlacementCriteria && !m_trackingEnabled ) {
299  BandPriorityWithNoTracking(iss, isl, isb, ins, inl, inb, bandPriorityInputBandNumber,
300  bandPriorityOutputBandNumber);
301  }
302  else {
303  // Create portal buffers for the input and output files
304  Portal iPortal(ins, 1, InputCubes[0]->pixelType());
305  Portal oPortal(ins, 1, OutputCubes[0]->pixelType());
306  Portal origPortal(ins, 1, OutputCubes[0]->pixelType());
307 
308  for (int ib = isb, ob = m_osb; ib < (isb + inb) && ob <= m_onb; ib++, ob++) {
309  for (int il = isl, ol = m_osl; il < isl + inl; il++, ol++) {
310  // Set the position of the portals in the input and output cubes
311  iPortal.SetPosition(iss, il, ib);
312  InputCubes[0]->read(iPortal);
313 
314  oPortal.SetPosition(m_oss, ol, ob);
315  OutputCubes[0]->read(oPortal);
316 
317  if (m_trackingEnabled) {
318  origPortal.SetPosition(m_oss, ol, iOriginBand);
319  OutputCubes[0]->read(origPortal);
320  }
321  else if (m_imageOverlay == AverageImageWithMosaic) {
322  origPortal.SetPosition(m_oss, ol, (ob+m_onb));
323  OutputCubes[0]->read(origPortal);
324  }
325 
326  bool bChanged = false;
327  // Move the input data to the output
328  for (int pixel = 0; pixel < oPortal.size(); pixel++) {
329  // Creating Mosaic, copy the input onto mosaic
330  // regardless of the priority
331  if (m_createOutputMosaic) {
332  oPortal[pixel] = iPortal[pixel];
333  if (m_trackingEnabled) {
334  origPortal[pixel] = iIndex;
335  bChanged = true;
336  }
337  else if (m_imageOverlay == AverageImageWithMosaic) {
338  if (IsValidPixel(iPortal[pixel])) {
339  origPortal[pixel]=1;
340  bChanged = true;
341  }
342  }
343  iChanged++;
344  }
345  // Band Priority
346  else if (m_trackingEnabled && m_imageOverlay == UseBandPlacementCriteria) {
347  int iPixelOrigin = qRound(origPortal[pixel]);
348 
349  Portal iComparePortal( ins, 1, InputCubes[0]->pixelType() );
350  Portal oComparePortal( ins, 1, OutputCubes[0]->pixelType() );
351  iComparePortal.SetPosition(iss, il, bandPriorityInputBandNumber);
352  InputCubes[0]->read(iComparePortal);
353  oComparePortal.SetPosition(m_oss, ol, bandPriorityOutputBandNumber);
354  OutputCubes[0]->read(oComparePortal);
355 
356  if (iPixelOrigin == iIndex) {
357  if ( ( IsValidPixel(iComparePortal[pixel]) &&
358  IsValidPixel(oComparePortal[pixel]) ) &&
359  ( (!m_bandPriorityUseMaxValue &&
360  iComparePortal[pixel] < oComparePortal[pixel]) ||
361  (m_bandPriorityUseMaxValue &&
362  iComparePortal[pixel] > oComparePortal[pixel]) ) ) {
363 
364  if ( IsValidPixel(iPortal[pixel]) ||
365  ( m_placeHighSatPixels && IsHighPixel(iPortal[pixel]) ) ||
366  ( m_placeLowSatPixels && IsLowPixel (iPortal[pixel]) ) ||
367  ( m_placeNullPixels && IsNullPixel(iPortal[pixel]) ) ){
368  oPortal[pixel] = iPortal[pixel];
369  iChanged++;
370  bChanged = true;
371  }
372  }
373  else { //bad comparison
374  if ( ( IsValidPixel(iPortal[pixel]) && !IsValidPixel(oPortal[pixel]) ) ||
375  ( m_placeHighSatPixels && IsHighPixel(iPortal[pixel]) ) ||
376  ( m_placeLowSatPixels && IsLowPixel (iPortal[pixel]) ) ||
377  ( m_placeNullPixels && IsNullPixel(iPortal[pixel]) ) ) {
378  oPortal[pixel] = iPortal[pixel];
379  iChanged++;
380  bChanged = true;
381  }
382  }
383  }
384  }
385  // OnTop/Input Priority
386  else if (m_imageOverlay == PlaceImagesOnTop) {
387  if (IsNullPixel(oPortal[pixel]) ||
388  IsValidPixel(iPortal[pixel]) ||
389  (m_placeHighSatPixels && IsHighPixel(iPortal[pixel])) ||
390  (m_placeLowSatPixels && IsLowPixel(iPortal[pixel])) ||
391  (m_placeNullPixels && IsNullPixel(iPortal[pixel]))) {
392  oPortal[pixel] = iPortal[pixel];
393  if (m_trackingEnabled) {
394  origPortal[pixel] = iIndex;
395  bChanged = true;
396  }
397  iChanged++;
398  }
399  }
400  // AverageImageWithMosaic priority
401  else if (m_imageOverlay == AverageImageWithMosaic) {
402  bChanged |= ProcessAveragePriority(pixel, iPortal, oPortal, origPortal);
403  }
404  // Beneath/Mosaic Priority
405  else if (m_imageOverlay == PlaceImagesBeneath) {
406  if (IsNullPixel(oPortal[pixel])) {
407  oPortal[pixel] = iPortal[pixel];
408  // Set the origin if number of input bands equal to 1
409  // and if the track flag was set
410  if (m_trackingEnabled) {
411  origPortal[pixel] = iIndex;
412  bChanged = true;
413  }
414  iChanged++;
415  }
416  }
417  } // End sample loop
418  if (bChanged) {
419  if (m_trackingEnabled || m_imageOverlay == AverageImageWithMosaic) {
420  OutputCubes[0]->write(origPortal);
421  }
422  }
423  OutputCubes[0]->write(oPortal);
424  p_progress->CheckStatus();
425  } // End line loop
426  } // End band loop
427  }
428  } // End StartProcess
429 
430 
436  PvlObject ProcessMosaic::imagePositions() {
437  return m_imagePositions;
438  }
439 
440 
478  Cube *ProcessMosaic::SetInputCube(const QString &parameter,
479  const int ss, const int sl, const int sb,
480  const int ns, const int nl, const int nb) {
481 
482  // Make sure only one input is active at a time
483  if (InputCubes.size() > 0) {
484  QString m = "You must specify exactly one input cube";
485  throw IException(IException::Programmer, m, _FILEINFO_);
486  }
487 
488  m_iss = ss;
489  m_isl = sl;
490  m_isb = sb;
491  m_ins = ns;
492  m_inl = nl;
493  m_inb = nb;
494 
495  Cube *cInCube = Process::SetInputCube(parameter);
496 
497  //get the output label
498  Pvl *cInPvl = InputCubes[0]->label();
499  if (cInPvl->findGroup("Dimensions", Pvl::Traverse).hasKeyword("Bands")) {
500  PvlKeyword &cBandKey = cInPvl->findGroup("Dimensions", Pvl::Traverse).findKeyword("Bands");
501  QString sStr(cBandKey[0]);
502  if (toInt(sStr) < nb) {
503  QString m = "The parameter number of input bands exceeds the actual number of bands in the "
504  "input cube";
505  throw IException(IException::Programmer, m, _FILEINFO_);
506  }
507  }
508  return cInCube;
509  }
510 
511 
548  Cube *ProcessMosaic::SetInputCube(const QString &fname,
549  CubeAttributeInput &att,
550  const int ss, const int sl, const int sb,
551  const int ns, const int nl, const int nb) {
552 
553  // Make sure only one input is active at a time
554  if (InputCubes.size() > 0) {
555  QString m = "You must specify exactly one input cube";
556  throw IException(IException::Programmer, m, _FILEINFO_);
557  }
558 
559  m_iss = ss;
560  m_isl = sl;
561  m_isb = sb;
562  m_ins = ns;
563  m_inl = nl;
564  m_inb = nb;
565 
566  Cube *cInCube = Process::SetInputCube(fname, att);
567 
568  //check if the number of bands specified is not greater than the actual number of bands in the input
569  Pvl *cInPvl = InputCubes[0]->label();
570  if (cInPvl->findGroup("Dimensions", Pvl::Traverse).hasKeyword("Bands")) {
571  PvlKeyword &cBandKey = cInPvl->findGroup("Dimensions", Pvl::Traverse).findKeyword("Bands");
572  QString sStr(cBandKey[0]);
573  if (toInt(sStr) < nb) {
574  QString m = "The parameter number of input bands exceeds the actual number of bands in the input cube";
575  throw IException(IException::Programmer, m, _FILEINFO_);
576  }
577  }
578  return cInCube;
579  }
580 
581 
596  Cube *ProcessMosaic::SetOutputCube(const QString &psParameter) {
597 
598  // Make sure there is only one output cube
599  if (OutputCubes.size() > 0) {
600  QString m = "You must specify exactly one output cube";
601  throw IException(IException::Programmer, m, _FILEINFO_);
602  }
603 
604  // Attempt to open a cube ... get the filename from the user parameter
605  // (e.g., "TO") and the cube size from an input cube
606  Cube *cube = new Cube;
607  try {
608  QString fname = Application::GetUserInterface().GetFileName(psParameter);
609  cube->open(fname, "rw");
610  }
611  catch (IException &) {
612  delete cube;
613  throw;
614  }
615 
616  if (m_createOutputMosaic) {
617  Pvl *outLab = cube->label();
618  if (outLab->findObject("IsisCube").hasGroup("BandBin")) {
619  outLab->findObject("IsisCube").deleteGroup("BandBin");
620  }
621  }
622 
623  // Everything is fine so save the cube on the stack
624  AddOutputCube(cube);
625  return cube;
626  }
627 
628 
632  void ProcessMosaic::SetBandBinMatch(bool enforceBandBinMatch) {
633  m_enforceBandBinMatch = enforceBandBinMatch;
634  }
635 
636 
657  void ProcessMosaic::SetMosaicOrigin(int &index) {
658  // Get only the file name
659  QString sInputFile = FileName(InputCubes[0]->fileName()).name();
660  QString sTableName = TRACKING_TABLE_NAME;
661 
662  // Get the serial number
663  QString sSerialNumber = SerialNumber::Compose(*(InputCubes[0]));
664  int iFileNameLen = sInputFile.length();
665  int iSerialNumLen = sSerialNumber.length();
666  int iFieldLength = iSerialNumLen;
667  if (iFileNameLen > iSerialNumLen) {
668  iFieldLength = iFileNameLen;
669  }
670 
671  // Get output file name
672  QString sOutputFile = FileName(OutputCubes[0]->fileName()).name();
673 
674  Pvl *cPvlOut = OutputCubes[0]->label();
675 
676  // Create a table record with the new image file name and serial number info
677  TableRecord cFileRecord;
678 
679  // Populate with File Name
680  TableField cFileField("FileName", TableField::Text, iFieldLength);
681  cFileField = sInputFile;
682  cFileRecord += cFileField;
683 
684  // Populate with Serial Number
685  TableField cSNField("SerialNumber", TableField::Text, iFieldLength);
686  cSNField = sSerialNumber;
687  cFileRecord += cSNField;
688 
689  int iNumObjs = cPvlOut->objects();
690  PvlObject cPvlObj;
691 
692  // Check if the Table exists
693  if (cPvlOut->hasObject("Table")) {
694  for (int i = 0; i < iNumObjs; i++) {
695  cPvlObj = cPvlOut->object(i);
696  if (cPvlObj.hasKeyword("Name", Pvl::Traverse)) {
697  PvlKeyword cNameKey = cPvlObj.findKeyword("Name", Pvl::Traverse);
698  if (cNameKey[0] == sTableName) {
699  PvlKeyword cFieldKey = cPvlObj.findGroup("Field").findKeyword("Size");
700 
701  //set the tracker flag to true as the tracking table exists
702  m_trackingEnabled = true;
703 
704  // Create a new blank table
705  Table cFileTable(sTableName);
706 
707  // Read and make a copy of the existing tracking table
708  Table cFileTable_Copy = Table(sTableName);
709  OutputCubes[0]->read(cFileTable_Copy);
710 
711  // Records count
712  int iRecs = cFileTable_Copy.Records();
713 
714  // Check if the image index can be accomadated in the pixel size
715  bool bFull = false;
716  switch (sizeof(OutputCubes[0]->pixelType())) {
717  case 1:
718  // Index is 1 based as 0=Null invalid value
719  if (iRecs >= (VALID_MAX1 - 1))
720  bFull = true;
721  break;
722  case 2:
723  // Signed 16bits with some special pixels
724  if (iRecs > (VALID_MAX2 - VALID_MIN2 + 1))
725  bFull = true;
726  break;
727 
728  case 4:
729  // Max float mantissa
730  if (iRecs > (FLOAT_STORE_INT_PRECISELY_MAX_VALUE -
731  FLOAT_STORE_INT_PRECISELY_MIN_VALUE + 1))
732  bFull = true;
733  break;
734  }
735 
736  if (bFull) {
737  QString msg = "The number of images in the Mosaic exceeds the pixel size";
738  throw IException(IException::Programmer, msg, _FILEINFO_);
739  }
740 
741  for (int i = 0; i < iRecs; i++) {
742  // Get the file name and trim out the characters filled due to resizing
743  QString sTableFile = QString(QString(cFileTable_Copy[i][0]).toAscii().data());
744  int found = sTableFile.lastIndexOf(".cub");
745  if (found != -1) {
746  // clear the packing characters - get only the file name
747  sTableFile.remove(found + 4);
748  }
749 
750  if (sTableFile == sInputFile) {
751  index += i;
752  return;
753  }
754 
755  // To initialize the new table, on the first file name comparison, check the size of
756  // the existing table record with the size of the new record being added
757  if (!i) {
758  if (toInt(QString(cFieldKey[0])) < iFieldLength) {
759  TableRecord cFileRecordUpdate;
760  TableField cFileFieldUpdate("FileName", TableField::Text, iFieldLength);
761  cFileFieldUpdate = (QString)cFileTable_Copy[i][0];
762  cFileRecordUpdate += cFileFieldUpdate;
763 
764  // Populate with Serial Number
765  TableField cSNFieldUpdate("SerialNumber", TableField::Text, iFieldLength);
766  cSNFieldUpdate = (QString)cFileTable_Copy[i][1];
767  cFileRecordUpdate += cSNFieldUpdate;
768  // add new record and set the size for all the other records
769  cFileTable = Table(sTableName, cFileRecordUpdate);
770  }
771  else {
772  cFileTable = Table(sTableName, cFileTable_Copy[i]);
773  }
774  }
775 
776  // Add the existing records into the new table
777  cFileTable += cFileTable_Copy[i]; // what if record size was resized above??? new record does not match table record size
778  }
779  // Get the current image file index
780  index += iRecs;
781 
782  // Add the current input image record to the new table
783  cFileTable += cFileRecord;
784 
785  // Copy the new table to the output Mosaic
786  OutputCubes[0]->write(cFileTable);
787  break; //break while loop
788  }
789  }
790  }//end for loop
791  }
792 
793  //creating new table if track flag is true
794  if (m_createOutputMosaic && m_trackingEnabled) {
795  Table cFileTable(sTableName, cFileRecord);
796  cFileTable += cFileRecord;
797  OutputCubes[0]->write(cFileTable);
798  //reset the origin band based on pixel type
799  ResetOriginBand();
800  }
801  }
802 
803 
807  void ProcessMosaic::SetBandKeyword(QString bandPriorityKeyName, QString bandPriorityKeyValue) {
808  m_bandPriorityKeyName = bandPriorityKeyName;
809  m_bandPriorityKeyValue = bandPriorityKeyValue;
810  }
811 
812 
816  void ProcessMosaic::SetBandNumber(int bandPriorityBandNumber) {
817  m_bandPriorityBandNumber = bandPriorityBandNumber;
818  }
819 
820 
825  void ProcessMosaic::SetBandUseMaxValue(bool useMax) {
826  m_bandPriorityUseMaxValue = useMax;
827  }
828 
829 
838  void ProcessMosaic::SetCreateFlag(bool createOutputMosaic) {
839  m_createOutputMosaic = createOutputMosaic;
840  }
841 
842 
847  void ProcessMosaic::SetHighSaturationFlag(bool placeHighSatPixels) {
848  m_placeHighSatPixels = placeHighSatPixels;
849  }
850 
851 
852  void ProcessMosaic::SetImageOverlay(ImageOverlay placement) {
853  m_imageOverlay = placement;
854  }
855 
856 
861  void ProcessMosaic::SetLowSaturationFlag(bool placeLowSatPixels) {
862  m_placeLowSatPixels = placeLowSatPixels;
863  }
864 
869  void ProcessMosaic::SetMatchDEM(bool matchDEM) {
870  m_enforceMatchDEM = matchDEM;
871  }
872 
873 
878  void ProcessMosaic::SetNullFlag(bool placeNullPixels) {
879  m_placeNullPixels = placeNullPixels;
880  }
881 
882 
883  void ProcessMosaic::SetTrackFlag(bool trackingEnabled) {
884  m_trackingEnabled = trackingEnabled;
885  }
886 
887 
891  bool ProcessMosaic::GetHighSaturationFlag() const {
892  return m_placeHighSatPixels;
893  }
894 
895 
899  ProcessMosaic::ImageOverlay ProcessMosaic::GetImageOverlay() const {
900  return m_imageOverlay;
901  }
902 
903 
907  bool ProcessMosaic::GetLowSaturationFlag() const {
908  return m_placeLowSatPixels;
909  }
910 
911 
915  bool ProcessMosaic::GetNullFlag() const {
916  return m_placeNullPixels;
917  }
918 
919 
923  bool ProcessMosaic::GetTrackFlag() const {
924  return m_trackingEnabled;
925  }
926 
927 
931  int ProcessMosaic::GetInputStartLineInMosaic() const {
932  return m_osl;
933  }
934 
935 
939  int ProcessMosaic::GetInputStartSampleInMosaic() const {
940  return m_oss;
941  }
942 
943 
947  int ProcessMosaic::GetInputStartBandInMosaic() const {
948  return m_osb;
949  }
950 
951 
956  QString ProcessMosaic::OverlayToString(ImageOverlay imageOverlay) {
957  QString result;
958 
959  switch (imageOverlay) {
960  case PlaceImagesOnTop:
961  result = "OnTop";
962  break;
963 
964  case PlaceImagesBeneath:
965  result = "Beneath";
966  break;
967 
968  case UseBandPlacementCriteria:
969  result = "Band";
970  break;
971 
972  case AverageImageWithMosaic:
973  result = "Average";
974  break;
975 
976  case NumImageOverlayOptions:
977  break;
978  }
979 
980  if (result == "") {
981  throw IException(IException::Unknown,
982  "Cannot convert overlay [" + toString((int)imageOverlay) + "] to a string",
983  _FILEINFO_);
984  }
985 
986  return result;
987  }
988 
989 
994  ProcessMosaic::ImageOverlay ProcessMosaic::StringToOverlay(QString imageOverlayString) {
995  QString imageOverlayStringUpper = imageOverlayString.toUpper();
996  for (int i = 0; i < NumImageOverlayOptions; i++) {
997  if (OverlayToString((ImageOverlay)i).toUpper() == imageOverlayStringUpper)
998  return (ImageOverlay)i;
999  }
1000 
1001  throw IException(IException::Unknown,
1002  "The text [" + imageOverlayString + "] does not correspond to any known "
1003  "image overlay modes (mosaic priorities)",
1004  _FILEINFO_);
1005  }
1006 
1007 
1015  void ProcessMosaic::MatchDEMShapeModel() {
1016  Pvl* inLabel = InputCubes[0]->label();
1017  Pvl* outLabel = OutputCubes[0]->label();
1018 
1019  if (outLabel->findObject("IsisCube").hasGroup("Mosaic")) {
1020  PvlGroup outMosaicGrp = outLabel->findObject("IsisCube").findGroup("Mosaic");
1021  if (outMosaicGrp.hasKeyword("ShapeModel")) {
1022  if (inLabel->findObject("IsisCube").hasGroup("Kernels")) {
1023  PvlGroup inMosaicGrp = inLabel->findObject("IsisCube").findGroup("Kernels");
1024  if (outMosaicGrp.hasKeyword("ShapeModel") && inMosaicGrp.hasKeyword("ShapeModel")) {
1025  PvlKeyword outShapeModelKey = outMosaicGrp.findKeyword("ShapeModel");
1026  QString sShapeModel = inMosaicGrp.findKeyword("ShapeModel")[0];
1027  int found = sShapeModel.lastIndexOf("/");
1028  if (found != -1) {
1029  sShapeModel.remove(0, found + 1);
1030  }
1031  if (sShapeModel == outShapeModelKey[0]) {
1032  return;
1033  }
1034  }
1035  }
1036  QString sErrMsg = "Input and Mosaic DEM Shape Model do not match";
1037  throw IException(IException::User, sErrMsg, _FILEINFO_);
1038  }
1039  }
1040  else {
1041  if (m_createOutputMosaic) {
1042  if (inLabel->findObject("IsisCube").hasGroup("Kernels")) {
1043  QString sShapeModel =
1044  inLabel->findObject("IsisCube").findGroup("Kernels").findKeyword("ShapeModel")[0];
1045  int found = sShapeModel.lastIndexOf("/");
1046  if (found != -1){
1047  sShapeModel.remove(0, found+1);
1048  }
1049  PvlObject & outIsisCubeObj = outLabel->findObject("IsisCube");
1050  PvlGroup mosaicGrp("Mosaic");
1051  PvlKeyword shapeModelKey("ShapeModel");
1052  shapeModelKey += sShapeModel;
1053  mosaicGrp += shapeModelKey;
1054  outIsisCubeObj += mosaicGrp;
1055  }
1056  }
1057  }
1058  }
1059 
1060 
1066  void ProcessMosaic::ResetCountBands()
1067  {
1068  int iBand = OutputCubes[0]->bandCount();
1069  int iLines = OutputCubes[0]->lineCount();
1070  int iSample = OutputCubes[0]->sampleCount();
1071 
1072  Portal origPortal(iSample, 1, OutputCubes[0]->pixelType());
1073  int iStartCountBand = iBand/2 + 1;
1074 
1075  for (int band=iStartCountBand; band<=iBand; band++) {
1076  for (int i = 1; i <= iLines; i++) {
1077  origPortal.SetPosition(1, i, band); //sample, line, band position
1078  OutputCubes[0]->read(origPortal);
1079  for (int iPixel = 0; iPixel < origPortal.size(); iPixel++) {
1080  origPortal[iPixel] = 0;
1081  }
1082  OutputCubes[0]->write(origPortal);
1083  }
1084  }
1085  }
1086 
1087 
1101  bool ProcessMosaic::ProcessAveragePriority(int piPixel, Portal& piPortal, Portal& poPortal,
1102  Portal& porigPortal)
1103  {
1104  bool bChanged=false;
1105  if (IsValidPixel(piPortal[piPixel]) && IsValidPixel(poPortal[piPixel])) {
1106  int iCount = (int)porigPortal[piPixel];
1107  double dNewDN = (poPortal[piPixel] * iCount + piPortal[piPixel]) / (iCount + 1);
1108  poPortal[piPixel] = dNewDN;
1109  porigPortal[piPixel] =iCount +1;
1110  bChanged = true;
1111  }
1112  // Input-Valid, Mosaic-Special
1113  else if (IsValidPixel(piPortal[piPixel])) {
1114  poPortal[piPixel] = piPortal[piPixel];
1115  porigPortal[piPixel] = 1;
1116  bChanged = true;
1117  }
1118  // Input-Special, Flags-True
1119  else if (IsSpecial(piPortal[piPixel])) {
1120  if ((m_placeHighSatPixels && IsHighPixel(piPortal[piPixel])) ||
1121  (m_placeLowSatPixels && IsLowPixel (piPortal[piPixel])) ||
1122  (m_placeNullPixels && IsNullPixel(piPortal[piPixel]))) {
1123  poPortal[piPixel] = piPortal[piPixel];
1124  porigPortal[piPixel] = 0;
1125  bChanged = true;
1126  }
1127  }
1128  return bChanged;
1129  }
1130 
1131 
1143  void ProcessMosaic::MatchBandBinGroup(int origIsb, int &inb) {
1144  Pvl *inLab = InputCubes[0]->label();
1145  Pvl *outLab = OutputCubes[0]->label();
1146 
1147  PvlGroup &inBin = inLab->findGroup("BandBin", Pvl::Traverse);
1148  PvlGroup &outBin = outLab->findGroup("BandBin", Pvl::Traverse);
1149  if (inBin.keywords() != outBin.keywords()) {
1150  QString msg = "Pvl Group [BandBin] does not match between the input and output cubes";
1151  throw IException(IException::User, msg, _FILEINFO_);
1152  }
1153 
1154  //pvl - zero based
1155  int isb = (origIsb - 1);
1156  int osb = (m_osb - 1);
1157  int iOutBandsHalf = OutputCubes[0]->bandCount()/2;
1158 
1159  for (int i = 0; i < outBin.keywords(); i++) {
1160  PvlKeyword &outKey = outBin[i];
1161  QString sOutName = outKey.name();
1162  if (inBin.hasKeyword(sOutName)) {
1163  PvlKeyword &inKey = inBin[sOutName];
1164  for (int j = osb, k = isb; j < outKey.size() && k < inKey.size(); j++, k++) {
1165  if (outKey[j] == "NA") {
1166  outKey[j] = inKey[k];
1167  if (m_imageOverlay == AverageImageWithMosaic) {
1168  if (sOutName.contains("Filter") ||
1169  sOutName.contains("Name")) {
1170  outKey[j+iOutBandsHalf] = inKey[k] + "_Count";
1171  }
1172  else {
1173  outKey[j+iOutBandsHalf] = "Avg_Count";
1174  }
1175  }
1176  }
1177  else if (outKey[j] != inKey[k]) {
1178  QString msg = "Pvl Group [BandBin] in Key[" + outKey.name() + "] In value" + inKey[k] +
1179  "and Out value=" + outKey[j] + " do not match";
1180  throw IException(IException::User, msg, _FILEINFO_);
1181  }
1182  }
1183  }
1184  else {
1185  QString msg = "Pvl Group [BandBin] In Keyword[" + inBin[i].name() + "] and Out Keyword[" +
1186  outBin[i].name() + "] does not match";
1187  throw IException(IException::User, msg, _FILEINFO_);
1188  }
1189  }
1190 
1191  int inputRange = InputCubes[0]->bandCount() - isb;
1192  int outputRange = OutputCubes[0]->bandCount() - osb;
1193  inb = min(inputRange, outputRange);
1194  }
1195 
1196 
1208  void ProcessMosaic::AddBandBinGroup(int origIsb) {
1209  Pvl *inLab = InputCubes[0]->label();
1210  Pvl *outLab = OutputCubes[0]->label();
1211 
1212  int iOutBands = OutputCubes[0]->bandCount();
1213 
1214  if (m_trackingEnabled) {
1215  iOutBands -= 1; // leave tracking band
1216  }
1217  else if (m_imageOverlay == AverageImageWithMosaic) {
1218  iOutBands /= 2;
1219  }
1220 
1221  int isb = origIsb - 1; // array zero based
1222  int osb = m_osb - 1;
1223 
1224  PvlGroup &cInBin = inLab->findGroup("BandBin", Pvl::Traverse);
1225  PvlGroup cOutBin("BandBin");
1226 
1227  int iInBands = InputCubes[0]->bandCount();
1228 
1229  for (int i = 0; i < cInBin.keywords(); i++) {
1230  PvlKeyword &cInKey = cInBin[i];
1231  int iInKeySize = cInKey.size();
1232  PvlKeyword cOutKey(cInKey.name());
1233 
1234  for (int b = 0; b < osb; b++) {
1235  cOutKey += "NA";
1236  }
1237  for (int b = osb; b < iOutBands; b++) {
1238  if (isb < iInKeySize) {
1239  cOutKey += cInKey[isb++];
1240  }
1241  else {
1242  cOutKey += "NA";
1243  }
1244  }
1245 
1246  // Add the "TRACKING" band to the Keyword if the flag is set and also if the number of
1247  // input cube bands is same as the the keysize of the keyword in the BandBin group.
1248  if (m_trackingEnabled && iInBands == iInKeySize) {
1249  cOutKey += "TRACKING"; // for the origin band
1250  }
1251 
1252  // Tag the Count Bands if priority is AverageImageWithMosaic.
1253  else if (m_imageOverlay == AverageImageWithMosaic) {
1254  int iTotalOutBands = OutputCubes[0]->bandCount();
1255  isb = origIsb - 1; // reset the input starting band
1256  int iOutStartBand = iOutBands + osb;
1257  QString sKeyName = cInKey.name();
1258  bool bFilterKey = false;
1259  if (sKeyName.contains("Filter") ||
1260  sKeyName.contains("Original") ||
1261  sKeyName.contains("Name")) {
1262  bFilterKey = true;
1263  }
1264  for (int ob=iOutBands; ob<iTotalOutBands; ob++) {
1265  if (isb < iInKeySize && ob >= iOutStartBand) {
1266  if (bFilterKey) {
1267  cOutKey += cInKey[isb++] + "_Count";
1268  }
1269  else {
1270  cOutKey += 0;
1271  isb++;
1272  }
1273  }
1274  else {
1275  cOutKey += 0;
1276  }
1277  }
1278  }
1279 
1280  // Check for units and make sure output keyword units value is set to input
1281  // keyword units value
1282  if (cOutKey.unit() != cInKey.unit()) {
1283  cOutKey.setUnits((QString)(cInKey.unit()));
1284  }
1285 
1286  cOutBin += cOutKey;
1287  isb = origIsb - 1; // reinitialize the input starting band
1288  }
1289  outLab->findObject("IsisCube").addGroup(cOutBin);
1290  }
1291 
1292 
1302  void ProcessMosaic::AddDefaultBandBinGroup() {
1303  Pvl *outLab = OutputCubes[0]->label();
1304 
1305  PvlGroup cOutBin("BandBin");
1306 
1307  int iOutBands = OutputCubes[0]->bandCount();
1308  int iOutBandsTotal = iOutBands;
1309 
1310  if (m_trackingEnabled) {
1311  iOutBands--; // Leave tracking band
1312  }
1313  else if (m_imageOverlay == AverageImageWithMosaic) {
1314  iOutBands /= 2;
1315  }
1316 
1317  PvlKeyword cOutKey("FilterName");
1318 
1319  for (int i=0; i<iOutBands; i++) {
1320  cOutKey += "NA";
1321  }
1322 
1323  if (m_imageOverlay == AverageImageWithMosaic) {
1324  for (int i=iOutBands; i<iOutBandsTotal; i++) {
1325  cOutKey += "NA_Count";
1326  }
1327  }
1328 
1329  if (m_trackingEnabled) {
1330  cOutKey += "TRACKING";
1331  }
1332 
1333  cOutBin += cOutKey;
1334 
1335  outLab->findObject("IsisCube").addGroup(cOutBin);
1336  }
1337 
1338 
1342  int ProcessMosaic::GetBandIndex(bool inputFile) {
1343  bool bFound = false;
1344  int iBandIndex = 0;
1345 
1346  Pvl cPvlLabel;
1347 
1348  if (inputFile) {
1349  cPvlLabel = *(InputCubes[0]->label());
1350  if (m_bandPriorityBandNumber <= InputCubes[0]->bandCount() &&
1351  m_bandPriorityBandNumber > 0) {
1352  iBandIndex = m_bandPriorityBandNumber;
1353  bFound = true;
1354  }
1355  }
1356  else {
1357  cPvlLabel = *(OutputCubes[0]->label());
1358  if (m_bandPriorityBandNumber <= OutputCubes[0]->bandCount() &&
1359  m_bandPriorityBandNumber > 0) {
1360  iBandIndex = m_bandPriorityBandNumber;
1361  bFound = true;
1362  }
1363  }
1364 // qDebug() << "Band Index:" << iBandIndex;
1365 // qDebug() << "Priority Band:" << m_bandPriorityBandNumber;
1366 // qDebug() << "Input Bands:" << InputCubes[0]->bandCount();
1367 // qDebug() << "output Bands:" << OutputCubes[0]->bandCount();
1368 // qDebug();
1369 
1370  //if non-zero integer, must be original band #, 1 based
1371 // if (m_bandPriorityBandNumber <= InputCubes[0]->bandCount() &&
1372 // m_bandPriorityBandNumber > 0) {
1373 // PvlKeyword cKeyOrigBand;
1374 // if (cPvlLabel.findGroup("BandBin", Pvl::Traverse).hasKeyword("OriginalBand")) {
1375 // cKeyOrigBand = cPvlLabel.findGroup("BandBin", Pvl::Traverse).findKeyword("OriginalBand");
1376 // }
1377 // int iSize = cKeyOrigBand.size();
1378 // QString buff = toString(m_bandPriorityBandNumber);
1379 // for (int i = 0; i < iSize; i++) {
1380 // if (buff == cKeyOrigBand[i]) {
1381 // iBandIndex = m_bandPriorityBandNumber;//i + 1; //1 based get band index
1382 // bFound = true;
1383 // break;
1384 // }
1385 // }
1386 // }
1387  //key name
1388  if (!m_bandPriorityBandNumber) {
1389  PvlKeyword cKeyName;
1390  if (cPvlLabel.findGroup("BandBin", Pvl::Traverse).hasKeyword(m_bandPriorityKeyName)) {
1391  cKeyName = cPvlLabel.findGroup("BandBin", Pvl::Traverse).findKeyword(m_bandPriorityKeyName);
1392  }
1393  int iSize = cKeyName.size();
1394  for (int i = 0; i < iSize; i++) {
1395  if (m_bandPriorityKeyValue.toUpper() == cKeyName[i].toUpper()) {
1396  iBandIndex = i + 1; //1 based get key value index
1397  bFound = true;
1398  break;
1399  }
1400  }
1401  }
1402 // qDebug() << "Band Index:" << iBandIndex;
1403 // qDebug();
1404  if (!bFound) {
1405  QString msg = "Invalid Band / Key Name, Value ";
1406  throw IException(IException::User, msg, _FILEINFO_);
1407  }
1408  return iBandIndex;
1409  }
1410 
1411 
1426  void ProcessMosaic::BandComparison(int iss, int isl, int isb, int ins, int inl, int inb,
1427  int bandPriorityInputBandNumber, int bandPriorityOutputBandNumber, int index) {
1428  //
1429  // Create portal buffers for the input and output files
1430  Portal cIportal(ins, 1, InputCubes[0]->pixelType());
1431  Portal cOportal(ins, 1, OutputCubes[0]->pixelType());
1432  Portal origPortal(ins, 1, OutputCubes[0]->pixelType());
1433 
1434  //Get the last band set aside for "Origin"
1435  int iOriginBand = OutputCubes[0]->bandCount();
1436 
1437  for (int iIL = isl, iOL = m_osl; iIL < isl + inl; iIL++, iOL++) {
1438  // Set the position of the portals in the input and output cubes
1439  cIportal.SetPosition(iss, iIL, bandPriorityInputBandNumber);
1440  InputCubes[0]->read(cIportal);
1441 
1442  cOportal.SetPosition(m_oss, iOL, bandPriorityOutputBandNumber);
1443  OutputCubes[0]->read(cOportal);
1444 
1445  origPortal.SetPosition(m_oss, iOL, iOriginBand);
1446  OutputCubes[0]->read(origPortal);
1447 
1448  // Move the input data to the output
1449  for (int iPixel = 0; iPixel < cOportal.size(); iPixel++) {
1450  if (IsNullPixel(origPortal[iPixel]) ||
1451  (m_placeHighSatPixels && IsHighPixel(cIportal[iPixel])) ||
1452  (m_placeLowSatPixels && IsLowPixel(cIportal[iPixel])) ||
1453  (m_placeNullPixels && IsNullPixel(cIportal[iPixel]))) {
1454  origPortal[iPixel] = index;
1455  }
1456  else {
1457  if (IsValidPixel(cIportal[iPixel])) {
1458  if (IsSpecial(cOportal[iPixel]) ||
1459  (m_bandPriorityUseMaxValue == false && cIportal[iPixel] < cOportal[iPixel]) ||
1460  (m_bandPriorityUseMaxValue == true && cIportal[iPixel] > cOportal[iPixel])) {
1461  origPortal[iPixel] = index;
1462  }
1463  }
1464  }
1465  }
1466  OutputCubes[0]->write(origPortal);
1467  }
1468  }
1469 
1470 
1476 void ProcessMosaic::BandPriorityWithNoTracking(int iss, int isl, int isb, int ins, int inl,
1477  int inb, int bandPriorityInputBandNumber,
1478  int bandPriorityOutputBandNumber) {
1479  /*
1480  * specified band for comparison
1481  * Create portal buffers for the input and output files pointing to the
1482  */
1483  Portal iComparePortal( ins, 1, InputCubes[0]->pixelType() );
1484  Portal oComparePortal( ins, 1, OutputCubes[0]->pixelType() );
1485  Portal resultsPortal ( ins, 1, OutputCubes[0]->pixelType() );
1486 
1487  // Create portal buffers for the input and output files
1488  Portal iPortal( ins, 1, InputCubes[0]->pixelType() );
1489  Portal oPortal( ins, 1, OutputCubes[0]->pixelType() );
1490 
1491  for (int inLine = isl, outLine = m_osl; inLine < isl + inl; inLine++, outLine++) {
1492 // Set the position of the portals in the input and output cubes
1493  iComparePortal.SetPosition(iss, inLine, bandPriorityInputBandNumber);
1494  InputCubes[0]->read(iComparePortal);
1495 
1496  oComparePortal.SetPosition(m_oss, outLine, bandPriorityOutputBandNumber);
1497  OutputCubes[0]->read(oComparePortal);
1498 
1499  Portal iPortal( ins, 1, InputCubes[0]->pixelType() );
1500  Portal oPortal( ins, 1, OutputCubes[0]->pixelType() );
1501 
1502  bool inCopy = false;
1503 // Move the input data to the output
1504  for (int iPixel = 0; iPixel < ins; iPixel++) {
1505  resultsPortal[iPixel] = false;
1506  if (m_createOutputMosaic) {
1507  resultsPortal[iPixel] = true;
1508  inCopy = true;
1509  }
1510  else if ( IsValidPixel(iComparePortal[iPixel]) && IsValidPixel(oComparePortal[iPixel]) ) {
1511  if ( (m_bandPriorityUseMaxValue == false &&
1512  iComparePortal[iPixel] < oComparePortal[iPixel]) ||
1513  (m_bandPriorityUseMaxValue == true &&
1514  iComparePortal[iPixel] > oComparePortal[iPixel]) ) {
1515  resultsPortal[iPixel] = true;
1516  inCopy = true;
1517  }
1518  }
1519  else if (IsValidPixel(iComparePortal[iPixel]) && !IsValidPixel(oComparePortal[iPixel]) ) {
1520  resultsPortal[iPixel] = true;
1521  inCopy = true;
1522  }
1523  }
1524  if (inCopy) {
1525  for (int ib = isb, ob = m_osb; ib < (isb + inb) && ob <= m_onb; ib++, ob++) {
1526 // Set the position of the portals in the input and output cubes
1527  iPortal.SetPosition(iss, inLine, ib);
1528  InputCubes[0]->read(iPortal);
1529 
1530  oPortal.SetPosition(m_oss, outLine, ob);
1531  OutputCubes[0]->read(oPortal);
1532 
1533  for (int iPixel = 0; iPixel < ins; iPixel++) {
1534  if (resultsPortal[iPixel]) {
1535  if (m_createOutputMosaic) {
1536  oPortal[iPixel] = iPortal[iPixel];
1537  }
1538  else if ( IsValidPixel(iPortal[iPixel]) ||
1539  (m_placeHighSatPixels && IsHighPixel(iPortal[iPixel]) ) ||
1540  (m_placeLowSatPixels && IsLowPixel (iPortal[iPixel]) ) ||
1541  (m_placeNullPixels && IsNullPixel(iPortal[iPixel]) ) ) {
1542  oPortal[iPixel] = iPortal[iPixel];
1543  }
1544  }
1545  else if ( IsValidPixel(iPortal[iPixel]) && !IsValidPixel(oPortal[iPixel]) ) {
1546  oPortal[iPixel] = iPortal[iPixel];
1547  }
1548  }
1549  OutputCubes[0]->write(oPortal);
1550  }
1551  }
1552  }
1553  }
1554 
1555 
1556 
1567  int ProcessMosaic::GetIndexOffsetByPixelType() {
1568  int iOffset = 0;
1569 
1570  switch (SizeOf(OutputCubes[0]->pixelType())) {
1571  case 1:
1572  iOffset = VALID_MIN1;
1573  break;
1574 
1575  case 2:
1576  iOffset = VALID_MIN2;
1577  break;
1578 
1579  case 4:
1580  iOffset = FLOAT_STORE_INT_PRECISELY_MIN_VALUE;
1581  break;
1582  }
1583  return iOffset;
1584  }
1585 
1586 
1599  int ProcessMosaic::GetOriginDefaultByPixelType() {
1600  int iDefault;
1601 
1602  switch (SizeOf(OutputCubes[0]->pixelType())) {
1603  case 1:
1604  iDefault = NULL1;
1605  break;
1606 
1607  case 2:
1608  iDefault = NULL2;
1609  break;
1610 
1611  case 4:
1612  iDefault = INULL4;
1613  break;
1614 
1615  default:
1616  QString msg = "ProcessMosaic::GetOriginDefaultByPixelType - Invalid Pixel Type";
1617  throw IException(IException::Programmer, msg, _FILEINFO_);
1618  }
1619 
1620  return iDefault;
1621  }
1622 
1623 
1632  void ProcessMosaic::ResetOriginBand() {
1633  int iBand = OutputCubes[0]->bandCount();
1634  int iLines = OutputCubes[0]->lineCount();
1635  int iSample = OutputCubes[0]->sampleCount();
1636 
1637  int iDefault = GetOriginDefaultByPixelType();
1638 
1639  Portal origPortal(iSample, 1, OutputCubes[0]->pixelType());
1640 
1641  for (int i = 1; i <= iLines; i++) {
1642  origPortal.SetPosition(1, i, iBand); //sample, line, band position
1643  OutputCubes[0]->read(origPortal);
1644  for (int iPixel = 0; iPixel < origPortal.size(); iPixel++) {
1645  origPortal[iPixel] = (float)(iDefault);
1646  }
1647  OutputCubes[0]->write(origPortal);
1648  }
1649  //Test();
1650  }
1651 
1652 
1662  bool ProcessMosaic::GetTrackStatus() {
1663  //get the output label
1664  Pvl *cPvlOut = OutputCubes[0]->label();
1665 
1666  bool bTableExists = false;
1667  int iNumObjs = cPvlOut->objects();
1668  PvlObject cPvlObj;
1669 
1670  //Check if table already exists
1671  if (cPvlOut->hasObject("Table")) {
1672  for (int i = 0; i < iNumObjs; i++) {
1673  cPvlObj = cPvlOut->object(i);
1674  if (cPvlObj.hasKeyword("Name", Pvl::Traverse)) {
1675  PvlKeyword cNameKey = cPvlObj.findKeyword("Name", Pvl::Traverse);
1676  if (cNameKey[0] == TRACKING_TABLE_NAME) {
1677  bTableExists = true;
1678  }
1679  }
1680  }
1681  }
1682 
1683  return bTableExists;
1684  }
1685 
1686 }