Isis 3.0 Programmer Reference
Back | 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 the name of the file to be added
659  QString inputFileName = FileName(InputCubes[0]->fileName()).name();
660  QString tableName = TRACKING_TABLE_NAME;
661  int inputFileNameLength = inputFileName.length();
662 
663  // Get the serial number
664  QString inputFileSerialNumber = SerialNumber::Compose(*(InputCubes[0]));
665  int inputFileSerialNumberLength = inputFileSerialNumber.length();
666 
667  // the fields will be equal length, so choose the larger value
668  int fieldLength = inputFileSerialNumberLength;
669  if (inputFileNameLength > inputFileSerialNumberLength) {
670  fieldLength = inputFileNameLength;
671  }
672 
673  // Get output file name
674  QString sOutputFile = FileName(OutputCubes[0]->fileName()).name();
675 
676  Pvl *cPvlOut = OutputCubes[0]->label();
677 
678  // Create a table record with the new image file name and serial number info
679  TableRecord cFileRecord;
680 
681  // Populate with File Name
682  TableField cFileField("FileName", TableField::Text, fieldLength);
683  cFileField = inputFileName;
684  cFileRecord += cFileField;
685 
686  // Populate with Serial Number
687  TableField cSNField("SerialNumber", TableField::Text, fieldLength);
688  cSNField = inputFileSerialNumber;
689  cFileRecord += cSNField;
690 
691  int iNumObjs = cPvlOut->objects();
692  PvlObject cPvlObj;
693 
694  // Check if a Table exists in the mosaic cube
695  if (cPvlOut->hasObject("Table")) {
696  for (int i = 0; i < iNumObjs; i++) {
697  cPvlObj = cPvlOut->object(i);
698  if (cPvlObj.hasKeyword("Name", Pvl::Traverse)) {
699  PvlKeyword cNameKey = cPvlObj.findKeyword("Name", Pvl::Traverse);
700  if (cNameKey[0] == tableName) {
701  int existingTableFieldLength = toInt(QString(cPvlObj.findGroup("Field")
702  .findKeyword("Size")));
703 
704  //set the tracker flag to true as the tracking table exists
705  m_trackingEnabled = true;
706 
707  // Create a new blank table
708  Table cFileTable(tableName);
709 
710  // Read and make a copy of the existing tracking table
711  Table cFileTable_Copy = Table(tableName);
712  OutputCubes[0]->read(cFileTable_Copy);
713  // Records count
714  int existingTableRecords = cFileTable_Copy.Records();
715 
716  // Check if the image index can be accomadated in the pixel size
717  bool bFull = false;
718  switch (sizeof(OutputCubes[0]->pixelType())) {
719  case 1:
720  // Index is 1 based as 0=Null invalid value
721  if (existingTableRecords >= (VALID_MAX1 - 1)) bFull = true;
722  break;
723  case 2:
724  // Signed 16bits with some special pixels
725  if (existingTableRecords > (VALID_MAX2 - VALID_MIN2 + 1)) bFull = true;
726  break;
727 
728  case 4:
729  // Max float mantissa
730  if (existingTableRecords > (FLOAT_STORE_INT_PRECISELY_MAX_VALUE -
731  FLOAT_STORE_INT_PRECISELY_MIN_VALUE + 1)) bFull = true;
732  break;
733  }
734 
735  if (bFull) {
736  QString msg = "The number of images in the Mosaic exceeds the pixel size";
737  throw IException(IException::Programmer, msg, _FILEINFO_);
738  }
739 
740  for (int i = 0;i < existingTableRecords;i++) {
741  // Get the file name and trim out the characters filled due to resizing
742  QString sTableFile = QString(QString(cFileTable_Copy[i][0]).toLatin1().data());
743  int found = sTableFile.lastIndexOf(".cub");
744  if (found != -1) {
745  // clear the packing characters - get only the file name
746  sTableFile.remove(found + 4);
747  }
748 
749  if (sTableFile == inputFileName) {
750  index += i;
751  return;
752  }
753 
754 
755  // compare the length of the fields in the current table to the length of the fields
756  // in the record to be added to the table, then create the new record to be added
757  TableRecord record;
758  if (existingTableFieldLength < fieldLength) {
759  // if the new field length is larger, create the new record to be added
760  // from the updated field size (i.e. resize each record in the exisiting
761  // table)
762  TableField cFileFieldUpdate("FileName", TableField::Text, fieldLength);
763  cFileFieldUpdate = (QString)cFileTable_Copy[i][0];
764  record += cFileFieldUpdate;
765 
766  // Populate with Serial Number
767  TableField cSNFieldUpdate("SerialNumber", TableField::Text, fieldLength);
768  cSNFieldUpdate = (QString)cFileTable_Copy[i][1];
769  record += cSNFieldUpdate;
770  }
771  else {
772  // otherwise, keep the original record size
773  record = cFileTable_Copy[i];
774  }
775 
776  // if this is the first record, initialize the new table with by adding the record
777  // created above (this will also set the appropriate record size)
778  if (i == 0) {
779  cFileTable = Table(tableName, record);
780  cFileTable += record;
781  }
782  else {
783  // Add all other records from the existing table into the new table
784  cFileTable += record;
785  }
786  }
787  // Get the current image file index
788  index += existingTableRecords;
789 
790  // if we kept the original table record size and this record is smaller, then we
791  // need to resize
792  if (cFileRecord.RecordSize() < cFileTable.RecordSize()) { // fieldLength < existingTableFieldLength
793  TableRecord updateNewRecord;
794  TableField cFileFieldUpdate("FileName", TableField::Text, existingTableFieldLength);
795  cFileFieldUpdate = (QString)cFileRecord[0];
796  updateNewRecord += cFileFieldUpdate;
797 
798  // Populate with Serial Number
799  TableField cSNFieldUpdate("SerialNumber", TableField::Text, existingTableFieldLength);
800  cSNFieldUpdate = (QString)cFileRecord[1];
801  updateNewRecord += cSNFieldUpdate;
802  cFileTable += updateNewRecord;
803  }
804  else {
805  // Add the current input image record to the new table
806  cFileTable += cFileRecord;
807  }
808 
809  // Copy the new table to the output Mosaic
810  OutputCubes[0]->write(cFileTable);
811  break; //break while loop
812  }
813  }
814  } //end for loop
815  }
816 
817  //creating new table if track flag is true
818  if (m_createOutputMosaic && m_trackingEnabled) {
819  Table cFileTable(tableName, cFileRecord);
820  cFileTable += cFileRecord;
821  OutputCubes[0]->write(cFileTable);
822  //reset the origin band based on pixel type
823  ResetOriginBand();
824  }
825  }
826 
827 
831  void ProcessMosaic::SetBandKeyword(QString bandPriorityKeyName, QString bandPriorityKeyValue) {
832  m_bandPriorityKeyName = bandPriorityKeyName;
833  m_bandPriorityKeyValue = bandPriorityKeyValue;
834  }
835 
836 
840  void ProcessMosaic::SetBandNumber(int bandPriorityBandNumber) {
841  m_bandPriorityBandNumber = bandPriorityBandNumber;
842  }
843 
844 
849  void ProcessMosaic::SetBandUseMaxValue(bool useMax) {
850  m_bandPriorityUseMaxValue = useMax;
851  }
852 
853 
862  void ProcessMosaic::SetCreateFlag(bool createOutputMosaic) {
863  m_createOutputMosaic = createOutputMosaic;
864  }
865 
866 
871  void ProcessMosaic::SetHighSaturationFlag(bool placeHighSatPixels) {
872  m_placeHighSatPixels = placeHighSatPixels;
873  }
874 
875 
876  void ProcessMosaic::SetImageOverlay(ImageOverlay placement) {
877  m_imageOverlay = placement;
878  }
879 
880 
885  void ProcessMosaic::SetLowSaturationFlag(bool placeLowSatPixels) {
886  m_placeLowSatPixels = placeLowSatPixels;
887  }
888 
893  void ProcessMosaic::SetMatchDEM(bool matchDEM) {
894  m_enforceMatchDEM = matchDEM;
895  }
896 
897 
902  void ProcessMosaic::SetNullFlag(bool placeNullPixels) {
903  m_placeNullPixels = placeNullPixels;
904  }
905 
906 
907  void ProcessMosaic::SetTrackFlag(bool trackingEnabled) {
908  m_trackingEnabled = trackingEnabled;
909  }
910 
911 
915  bool ProcessMosaic::GetHighSaturationFlag() const {
916  return m_placeHighSatPixels;
917  }
918 
919 
923  ProcessMosaic::ImageOverlay ProcessMosaic::GetImageOverlay() const {
924  return m_imageOverlay;
925  }
926 
927 
931  bool ProcessMosaic::GetLowSaturationFlag() const {
932  return m_placeLowSatPixels;
933  }
934 
935 
939  bool ProcessMosaic::GetNullFlag() const {
940  return m_placeNullPixels;
941  }
942 
943 
947  bool ProcessMosaic::GetTrackFlag() const {
948  return m_trackingEnabled;
949  }
950 
951 
955  int ProcessMosaic::GetInputStartLineInMosaic() const {
956  return m_osl;
957  }
958 
959 
963  int ProcessMosaic::GetInputStartSampleInMosaic() const {
964  return m_oss;
965  }
966 
967 
971  int ProcessMosaic::GetInputStartBandInMosaic() const {
972  return m_osb;
973  }
974 
975 
980  QString ProcessMosaic::OverlayToString(ImageOverlay imageOverlay) {
981  QString result;
982 
983  switch (imageOverlay) {
984  case PlaceImagesOnTop:
985  result = "OnTop";
986  break;
987 
988  case PlaceImagesBeneath:
989  result = "Beneath";
990  break;
991 
992  case UseBandPlacementCriteria:
993  result = "Band";
994  break;
995 
996  case AverageImageWithMosaic:
997  result = "Average";
998  break;
999 
1000  case NumImageOverlayOptions:
1001  break;
1002  }
1003 
1004  if (result == "") {
1005  throw IException(IException::Unknown,
1006  "Cannot convert overlay [" + toString((int)imageOverlay) + "] to a string",
1007  _FILEINFO_);
1008  }
1009 
1010  return result;
1011  }
1012 
1013 
1018  ProcessMosaic::ImageOverlay ProcessMosaic::StringToOverlay(QString imageOverlayString) {
1019  QString imageOverlayStringUpper = imageOverlayString.toUpper();
1020  for (int i = 0; i < NumImageOverlayOptions; i++) {
1021  if (OverlayToString((ImageOverlay)i).toUpper() == imageOverlayStringUpper)
1022  return (ImageOverlay)i;
1023  }
1024 
1025  throw IException(IException::Unknown,
1026  "The text [" + imageOverlayString + "] does not correspond to any known "
1027  "image overlay modes (mosaic priorities)",
1028  _FILEINFO_);
1029  }
1030 
1031 
1039  void ProcessMosaic::MatchDEMShapeModel() {
1040  Pvl* inLabel = InputCubes[0]->label();
1041  Pvl* outLabel = OutputCubes[0]->label();
1042 
1043  if (outLabel->findObject("IsisCube").hasGroup("Mosaic")) {
1044  PvlGroup outMosaicGrp = outLabel->findObject("IsisCube").findGroup("Mosaic");
1045  if (outMosaicGrp.hasKeyword("ShapeModel")) {
1046  if (inLabel->findObject("IsisCube").hasGroup("Kernels")) {
1047  PvlGroup inMosaicGrp = inLabel->findObject("IsisCube").findGroup("Kernels");
1048  if (outMosaicGrp.hasKeyword("ShapeModel") && inMosaicGrp.hasKeyword("ShapeModel")) {
1049  PvlKeyword outShapeModelKey = outMosaicGrp.findKeyword("ShapeModel");
1050  QString sShapeModel = inMosaicGrp.findKeyword("ShapeModel")[0];
1051  int found = sShapeModel.lastIndexOf("/");
1052  if (found != -1) {
1053  sShapeModel.remove(0, found + 1);
1054  }
1055  if (sShapeModel == outShapeModelKey[0]) {
1056  return;
1057  }
1058  }
1059  }
1060  QString sErrMsg = "Input and Mosaic DEM Shape Model do not match";
1061  throw IException(IException::User, sErrMsg, _FILEINFO_);
1062  }
1063  }
1064  else {
1065  if (m_createOutputMosaic) {
1066  if (inLabel->findObject("IsisCube").hasGroup("Kernels")) {
1067  QString sShapeModel =
1068  inLabel->findObject("IsisCube").findGroup("Kernels").findKeyword("ShapeModel")[0];
1069  int found = sShapeModel.lastIndexOf("/");
1070  if (found != -1){
1071  sShapeModel.remove(0, found+1);
1072  }
1073  PvlObject & outIsisCubeObj = outLabel->findObject("IsisCube");
1074  PvlGroup mosaicGrp("Mosaic");
1075  PvlKeyword shapeModelKey("ShapeModel");
1076  shapeModelKey += sShapeModel;
1077  mosaicGrp += shapeModelKey;
1078  outIsisCubeObj += mosaicGrp;
1079  }
1080  }
1081  }
1082  }
1083 
1084 
1090  void ProcessMosaic::ResetCountBands()
1091  {
1092  int iBand = OutputCubes[0]->bandCount();
1093  int iLines = OutputCubes[0]->lineCount();
1094  int iSample = OutputCubes[0]->sampleCount();
1095 
1096  Portal origPortal(iSample, 1, OutputCubes[0]->pixelType());
1097  int iStartCountBand = iBand/2 + 1;
1098 
1099  for (int band=iStartCountBand; band<=iBand; band++) {
1100  for (int i = 1; i <= iLines; i++) {
1101  origPortal.SetPosition(1, i, band); //sample, line, band position
1102  OutputCubes[0]->read(origPortal);
1103  for (int iPixel = 0; iPixel < origPortal.size(); iPixel++) {
1104  origPortal[iPixel] = 0;
1105  }
1106  OutputCubes[0]->write(origPortal);
1107  }
1108  }
1109  }
1110 
1111 
1125  bool ProcessMosaic::ProcessAveragePriority(int piPixel, Portal& piPortal, Portal& poPortal,
1126  Portal& porigPortal)
1127  {
1128  bool bChanged=false;
1129  if (IsValidPixel(piPortal[piPixel]) && IsValidPixel(poPortal[piPixel])) {
1130  int iCount = (int)porigPortal[piPixel];
1131  double dNewDN = (poPortal[piPixel] * iCount + piPortal[piPixel]) / (iCount + 1);
1132  poPortal[piPixel] = dNewDN;
1133  porigPortal[piPixel] =iCount +1;
1134  bChanged = true;
1135  }
1136  // Input-Valid, Mosaic-Special
1137  else if (IsValidPixel(piPortal[piPixel])) {
1138  poPortal[piPixel] = piPortal[piPixel];
1139  porigPortal[piPixel] = 1;
1140  bChanged = true;
1141  }
1142  // Input-Special, Flags-True
1143  else if (IsSpecial(piPortal[piPixel])) {
1144  if ((m_placeHighSatPixels && IsHighPixel(piPortal[piPixel])) ||
1145  (m_placeLowSatPixels && IsLowPixel (piPortal[piPixel])) ||
1146  (m_placeNullPixels && IsNullPixel(piPortal[piPixel]))) {
1147  poPortal[piPixel] = piPortal[piPixel];
1148  porigPortal[piPixel] = 0;
1149  bChanged = true;
1150  }
1151  }
1152  return bChanged;
1153  }
1154 
1155 
1167  void ProcessMosaic::MatchBandBinGroup(int origIsb, int &inb) {
1168  Pvl *inLab = InputCubes[0]->label();
1169  Pvl *outLab = OutputCubes[0]->label();
1170 
1171  PvlGroup &inBin = inLab->findGroup("BandBin", Pvl::Traverse);
1172  PvlGroup &outBin = outLab->findGroup("BandBin", Pvl::Traverse);
1173  if (inBin.keywords() != outBin.keywords()) {
1174  QString msg = "Pvl Group [BandBin] does not match between the input and output cubes";
1175  throw IException(IException::User, msg, _FILEINFO_);
1176  }
1177 
1178  //pvl - zero based
1179  int isb = (origIsb - 1);
1180  int osb = (m_osb - 1);
1181  int iOutBandsHalf = OutputCubes[0]->bandCount()/2;
1182 
1183  for (int i = 0; i < outBin.keywords(); i++) {
1184  PvlKeyword &outKey = outBin[i];
1185  QString sOutName = outKey.name();
1186  if (inBin.hasKeyword(sOutName)) {
1187  PvlKeyword &inKey = inBin[sOutName];
1188  for (int j = osb, k = isb; j < outKey.size() && k < inKey.size(); j++, k++) {
1189  if (outKey[j] == "NA") {
1190  outKey[j] = inKey[k];
1191  if (m_imageOverlay == AverageImageWithMosaic) {
1192  if (sOutName.contains("Filter") ||
1193  sOutName.contains("Name")) {
1194  outKey[j+iOutBandsHalf] = inKey[k] + "_Count";
1195  }
1196  else {
1197  outKey[j+iOutBandsHalf] = "Avg_Count";
1198  }
1199  }
1200  }
1201  else if (outKey[j] != inKey[k]) {
1202  QString msg = "Pvl Group [BandBin] in Key[" + outKey.name() + "] In value" + inKey[k] +
1203  "and Out value=" + outKey[j] + " do not match";
1204  throw IException(IException::User, msg, _FILEINFO_);
1205  }
1206  }
1207  }
1208  else {
1209  QString msg = "Pvl Group [BandBin] In Keyword[" + inBin[i].name() + "] and Out Keyword[" +
1210  outBin[i].name() + "] does not match";
1211  throw IException(IException::User, msg, _FILEINFO_);
1212  }
1213  }
1214 
1215  int inputRange = InputCubes[0]->bandCount() - isb;
1216  int outputRange = OutputCubes[0]->bandCount() - osb;
1217  inb = min(inputRange, outputRange);
1218  }
1219 
1220 
1232  void ProcessMosaic::AddBandBinGroup(int origIsb) {
1233  Pvl *inLab = InputCubes[0]->label();
1234  Pvl *outLab = OutputCubes[0]->label();
1235 
1236  int iOutBands = OutputCubes[0]->bandCount();
1237 
1238  if (m_trackingEnabled) {
1239  iOutBands -= 1; // leave tracking band
1240  }
1241  else if (m_imageOverlay == AverageImageWithMosaic) {
1242  iOutBands /= 2;
1243  }
1244 
1245  int isb = origIsb - 1; // array zero based
1246  int osb = m_osb - 1;
1247 
1248  PvlGroup &cInBin = inLab->findGroup("BandBin", Pvl::Traverse);
1249  PvlGroup cOutBin("BandBin");
1250 
1251  int iInBands = InputCubes[0]->bandCount();
1252 
1253  for (int i = 0; i < cInBin.keywords(); i++) {
1254  PvlKeyword &cInKey = cInBin[i];
1255  int iInKeySize = cInKey.size();
1256  PvlKeyword cOutKey(cInKey.name());
1257 
1258  for (int b = 0; b < osb; b++) {
1259  cOutKey += "NA";
1260  }
1261  for (int b = osb; b < iOutBands; b++) {
1262  if (isb < iInKeySize) {
1263  cOutKey += cInKey[isb++];
1264  }
1265  else {
1266  cOutKey += "NA";
1267  }
1268  }
1269 
1270  // Add the "TRACKING" band to the Keyword if the flag is set and also if the number of
1271  // input cube bands is same as the the keysize of the keyword in the BandBin group.
1272  if (m_trackingEnabled && iInBands == iInKeySize) {
1273  cOutKey += "TRACKING"; // for the origin band
1274  }
1275 
1276  // Tag the Count Bands if priority is AverageImageWithMosaic.
1277  else if (m_imageOverlay == AverageImageWithMosaic) {
1278  int iTotalOutBands = OutputCubes[0]->bandCount();
1279  isb = origIsb - 1; // reset the input starting band
1280  int iOutStartBand = iOutBands + osb;
1281  QString sKeyName = cInKey.name();
1282  bool bFilterKey = false;
1283  if (sKeyName.contains("Filter") ||
1284  sKeyName.contains("Original") ||
1285  sKeyName.contains("Name")) {
1286  bFilterKey = true;
1287  }
1288  for (int ob=iOutBands; ob<iTotalOutBands; ob++) {
1289  if (isb < iInKeySize && ob >= iOutStartBand) {
1290  if (bFilterKey) {
1291  cOutKey += cInKey[isb++] + "_Count";
1292  }
1293  else {
1294  cOutKey += 0;
1295  isb++;
1296  }
1297  }
1298  else {
1299  cOutKey += 0;
1300  }
1301  }
1302  }
1303 
1304  // Check for units and make sure output keyword units value is set to input
1305  // keyword units value
1306  if (cOutKey.unit() != cInKey.unit()) {
1307  cOutKey.setUnits((QString)(cInKey.unit()));
1308  }
1309 
1310  cOutBin += cOutKey;
1311  isb = origIsb - 1; // reinitialize the input starting band
1312  }
1313  outLab->findObject("IsisCube").addGroup(cOutBin);
1314  }
1315 
1316 
1326  void ProcessMosaic::AddDefaultBandBinGroup() {
1327  Pvl *outLab = OutputCubes[0]->label();
1328 
1329  PvlGroup cOutBin("BandBin");
1330 
1331  int iOutBands = OutputCubes[0]->bandCount();
1332  int iOutBandsTotal = iOutBands;
1333 
1334  if (m_trackingEnabled) {
1335  iOutBands--; // Leave tracking band
1336  }
1337  else if (m_imageOverlay == AverageImageWithMosaic) {
1338  iOutBands /= 2;
1339  }
1340 
1341  PvlKeyword cOutKey("FilterName");
1342 
1343  for (int i=0; i<iOutBands; i++) {
1344  cOutKey += "NA";
1345  }
1346 
1347  if (m_imageOverlay == AverageImageWithMosaic) {
1348  for (int i=iOutBands; i<iOutBandsTotal; i++) {
1349  cOutKey += "NA_Count";
1350  }
1351  }
1352 
1353  if (m_trackingEnabled) {
1354  cOutKey += "TRACKING";
1355  }
1356 
1357  cOutBin += cOutKey;
1358 
1359  outLab->findObject("IsisCube").addGroup(cOutBin);
1360  }
1361 
1362 
1366  int ProcessMosaic::GetBandIndex(bool inputFile) {
1367  bool bFound = false;
1368  int iBandIndex = 0;
1369 
1370  Pvl cPvlLabel;
1371 
1372  if (inputFile) {
1373  cPvlLabel = *(InputCubes[0]->label());
1374  if (m_bandPriorityBandNumber <= InputCubes[0]->bandCount() &&
1375  m_bandPriorityBandNumber > 0) {
1376  iBandIndex = m_bandPriorityBandNumber;
1377  bFound = true;
1378  }
1379  }
1380  else {
1381  cPvlLabel = *(OutputCubes[0]->label());
1382  if (m_bandPriorityBandNumber <= OutputCubes[0]->bandCount() &&
1383  m_bandPriorityBandNumber > 0) {
1384  iBandIndex = m_bandPriorityBandNumber;
1385  bFound = true;
1386  }
1387  }
1388 // qDebug() << "Band Index:" << iBandIndex;
1389 // qDebug() << "Priority Band:" << m_bandPriorityBandNumber;
1390 // qDebug() << "Input Bands:" << InputCubes[0]->bandCount();
1391 // qDebug() << "output Bands:" << OutputCubes[0]->bandCount();
1392 // qDebug();
1393 
1394  //if non-zero integer, must be original band #, 1 based
1395 // if (m_bandPriorityBandNumber <= InputCubes[0]->bandCount() &&
1396 // m_bandPriorityBandNumber > 0) {
1397 // PvlKeyword cKeyOrigBand;
1398 // if (cPvlLabel.findGroup("BandBin", Pvl::Traverse).hasKeyword("OriginalBand")) {
1399 // cKeyOrigBand = cPvlLabel.findGroup("BandBin", Pvl::Traverse).findKeyword("OriginalBand");
1400 // }
1401 // int iSize = cKeyOrigBand.size();
1402 // QString buff = toString(m_bandPriorityBandNumber);
1403 // for (int i = 0; i < iSize; i++) {
1404 // if (buff == cKeyOrigBand[i]) {
1405 // iBandIndex = m_bandPriorityBandNumber;//i + 1; //1 based get band index
1406 // bFound = true;
1407 // break;
1408 // }
1409 // }
1410 // }
1411  //key name
1412  if (!m_bandPriorityBandNumber) {
1413  PvlKeyword cKeyName;
1414  if (cPvlLabel.findGroup("BandBin", Pvl::Traverse).hasKeyword(m_bandPriorityKeyName)) {
1415  cKeyName = cPvlLabel.findGroup("BandBin", Pvl::Traverse).findKeyword(m_bandPriorityKeyName);
1416  }
1417  int iSize = cKeyName.size();
1418  for (int i = 0; i < iSize; i++) {
1419  if (m_bandPriorityKeyValue.toUpper() == cKeyName[i].toUpper()) {
1420  iBandIndex = i + 1; //1 based get key value index
1421  bFound = true;
1422  break;
1423  }
1424  }
1425  }
1426 // qDebug() << "Band Index:" << iBandIndex;
1427 // qDebug();
1428  if (!bFound) {
1429  QString msg = "Invalid Band / Key Name, Value ";
1430  throw IException(IException::User, msg, _FILEINFO_);
1431  }
1432  return iBandIndex;
1433  }
1434 
1435 
1450  void ProcessMosaic::BandComparison(int iss, int isl, int isb, int ins, int inl, int inb,
1451  int bandPriorityInputBandNumber, int bandPriorityOutputBandNumber, int index) {
1452  //
1453  // Create portal buffers for the input and output files
1454  Portal cIportal(ins, 1, InputCubes[0]->pixelType());
1455  Portal cOportal(ins, 1, OutputCubes[0]->pixelType());
1456  Portal origPortal(ins, 1, OutputCubes[0]->pixelType());
1457 
1458  //Get the last band set aside for "Origin"
1459  int iOriginBand = OutputCubes[0]->bandCount();
1460 
1461  for (int iIL = isl, iOL = m_osl; iIL < isl + inl; iIL++, iOL++) {
1462  // Set the position of the portals in the input and output cubes
1463  cIportal.SetPosition(iss, iIL, bandPriorityInputBandNumber);
1464  InputCubes[0]->read(cIportal);
1465 
1466  cOportal.SetPosition(m_oss, iOL, bandPriorityOutputBandNumber);
1467  OutputCubes[0]->read(cOportal);
1468 
1469  origPortal.SetPosition(m_oss, iOL, iOriginBand);
1470  OutputCubes[0]->read(origPortal);
1471 
1472  // Move the input data to the output
1473  for (int iPixel = 0; iPixel < cOportal.size(); iPixel++) {
1474  if (IsNullPixel(origPortal[iPixel]) ||
1475  (m_placeHighSatPixels && IsHighPixel(cIportal[iPixel])) ||
1476  (m_placeLowSatPixels && IsLowPixel(cIportal[iPixel])) ||
1477  (m_placeNullPixels && IsNullPixel(cIportal[iPixel]))) {
1478  origPortal[iPixel] = index;
1479  }
1480  else {
1481  if (IsValidPixel(cIportal[iPixel])) {
1482  if (IsSpecial(cOportal[iPixel]) ||
1483  (m_bandPriorityUseMaxValue == false && cIportal[iPixel] < cOportal[iPixel]) ||
1484  (m_bandPriorityUseMaxValue == true && cIportal[iPixel] > cOportal[iPixel])) {
1485  origPortal[iPixel] = index;
1486  }
1487  }
1488  }
1489  }
1490  OutputCubes[0]->write(origPortal);
1491  }
1492  }
1493 
1494 
1500 void ProcessMosaic::BandPriorityWithNoTracking(int iss, int isl, int isb, int ins, int inl,
1501  int inb, int bandPriorityInputBandNumber,
1502  int bandPriorityOutputBandNumber) {
1503  /*
1504  * specified band for comparison
1505  * Create portal buffers for the input and output files pointing to the
1506  */
1507  Portal iComparePortal( ins, 1, InputCubes[0]->pixelType() );
1508  Portal oComparePortal( ins, 1, OutputCubes[0]->pixelType() );
1509  Portal resultsPortal ( ins, 1, OutputCubes[0]->pixelType() );
1510 
1511  // Create portal buffers for the input and output files
1512  Portal iPortal( ins, 1, InputCubes[0]->pixelType() );
1513  Portal oPortal( ins, 1, OutputCubes[0]->pixelType() );
1514 
1515  for (int inLine = isl, outLine = m_osl; inLine < isl + inl; inLine++, outLine++) {
1516 // Set the position of the portals in the input and output cubes
1517  iComparePortal.SetPosition(iss, inLine, bandPriorityInputBandNumber);
1518  InputCubes[0]->read(iComparePortal);
1519 
1520  oComparePortal.SetPosition(m_oss, outLine, bandPriorityOutputBandNumber);
1521  OutputCubes[0]->read(oComparePortal);
1522 
1523  Portal iPortal( ins, 1, InputCubes[0]->pixelType() );
1524  Portal oPortal( ins, 1, OutputCubes[0]->pixelType() );
1525 
1526  bool inCopy = false;
1527 // Move the input data to the output
1528  for (int iPixel = 0; iPixel < ins; iPixel++) {
1529  resultsPortal[iPixel] = false;
1530  if (m_createOutputMosaic) {
1531  resultsPortal[iPixel] = true;
1532  inCopy = true;
1533  }
1534  else if ( IsValidPixel(iComparePortal[iPixel]) && IsValidPixel(oComparePortal[iPixel]) ) {
1535  if ( (m_bandPriorityUseMaxValue == false &&
1536  iComparePortal[iPixel] < oComparePortal[iPixel]) ||
1537  (m_bandPriorityUseMaxValue == true &&
1538  iComparePortal[iPixel] > oComparePortal[iPixel]) ) {
1539  resultsPortal[iPixel] = true;
1540  inCopy = true;
1541  }
1542  }
1543  else if (IsValidPixel(iComparePortal[iPixel]) && !IsValidPixel(oComparePortal[iPixel]) ) {
1544  resultsPortal[iPixel] = true;
1545  inCopy = true;
1546  }
1547  }
1548  if (inCopy) {
1549  for (int ib = isb, ob = m_osb; ib < (isb + inb) && ob <= m_onb; ib++, ob++) {
1550 // Set the position of the portals in the input and output cubes
1551  iPortal.SetPosition(iss, inLine, ib);
1552  InputCubes[0]->read(iPortal);
1553 
1554  oPortal.SetPosition(m_oss, outLine, ob);
1555  OutputCubes[0]->read(oPortal);
1556 
1557  for (int iPixel = 0; iPixel < ins; iPixel++) {
1558  if (resultsPortal[iPixel]) {
1559  if (m_createOutputMosaic) {
1560  oPortal[iPixel] = iPortal[iPixel];
1561  }
1562  else if ( IsValidPixel(iPortal[iPixel]) ||
1563  (m_placeHighSatPixels && IsHighPixel(iPortal[iPixel]) ) ||
1564  (m_placeLowSatPixels && IsLowPixel (iPortal[iPixel]) ) ||
1565  (m_placeNullPixels && IsNullPixel(iPortal[iPixel]) ) ) {
1566  oPortal[iPixel] = iPortal[iPixel];
1567  }
1568  }
1569  else if ( IsValidPixel(iPortal[iPixel]) && !IsValidPixel(oPortal[iPixel]) ) {
1570  oPortal[iPixel] = iPortal[iPixel];
1571  }
1572  }
1573  OutputCubes[0]->write(oPortal);
1574  }
1575  }
1576  }
1577  }
1578 
1579 
1580 
1591  int ProcessMosaic::GetIndexOffsetByPixelType() {
1592  int iOffset = 0;
1593 
1594  switch (SizeOf(OutputCubes[0]->pixelType())) {
1595  case 1:
1596  iOffset = VALID_MIN1;
1597  break;
1598 
1599  case 2:
1600  iOffset = VALID_MIN2;
1601  break;
1602 
1603  case 4:
1604  iOffset = FLOAT_STORE_INT_PRECISELY_MIN_VALUE;
1605  break;
1606  }
1607  return iOffset;
1608  }
1609 
1610 
1623  int ProcessMosaic::GetOriginDefaultByPixelType() {
1624  int iDefault;
1625 
1626  switch (SizeOf(OutputCubes[0]->pixelType())) {
1627  case 1:
1628  iDefault = NULL1;
1629  break;
1630 
1631  case 2:
1632  iDefault = NULL2;
1633  break;
1634 
1635  case 4:
1636  iDefault = INULL4;
1637  break;
1638 
1639  default:
1640  QString msg = "ProcessMosaic::GetOriginDefaultByPixelType - Invalid Pixel Type";
1641  throw IException(IException::Programmer, msg, _FILEINFO_);
1642  }
1643 
1644  return iDefault;
1645  }
1646 
1647 
1656  void ProcessMosaic::ResetOriginBand() {
1657  int iBand = OutputCubes[0]->bandCount();
1658  int iLines = OutputCubes[0]->lineCount();
1659  int iSample = OutputCubes[0]->sampleCount();
1660 
1661  int iDefault = GetOriginDefaultByPixelType();
1662 
1663  Portal origPortal(iSample, 1, OutputCubes[0]->pixelType());
1664 
1665  for (int i = 1; i <= iLines; i++) {
1666  origPortal.SetPosition(1, i, iBand); //sample, line, band position
1667  OutputCubes[0]->read(origPortal);
1668  for (int iPixel = 0; iPixel < origPortal.size(); iPixel++) {
1669  origPortal[iPixel] = (float)(iDefault);
1670  }
1671  OutputCubes[0]->write(origPortal);
1672  }
1673  //Test();
1674  }
1675 
1676 
1686  bool ProcessMosaic::GetTrackStatus() {
1687  //get the output label
1688  Pvl *cPvlOut = OutputCubes[0]->label();
1689 
1690  bool bTableExists = false;
1691  int iNumObjs = cPvlOut->objects();
1692  PvlObject cPvlObj;
1693 
1694  //Check if table already exists
1695  if (cPvlOut->hasObject("Table")) {
1696  for (int i = 0; i < iNumObjs; i++) {
1697  cPvlObj = cPvlOut->object(i);
1698  if (cPvlObj.hasKeyword("Name", Pvl::Traverse)) {
1699  PvlKeyword cNameKey = cPvlObj.findKeyword("Name", Pvl::Traverse);
1700  if (cNameKey[0] == TRACKING_TABLE_NAME) {
1701  bTableExists = true;
1702  }
1703  }
1704  }
1705  }
1706 
1707  return bTableExists;
1708  }
1709 
1710 }
PvlObject & object(const int index)
Return the object at the specified index.
Definition: PvlObject.cpp:460
Manipulate and parse attributes of input cube filenames.
int Records() const
Returns the number of records.
Definition: Table.cpp:224
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
File name manipulation and expansion.
Definition: FileName.h:111
Buffer for containing a two dimensional section of an image.
Definition: Portal.h:52
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
bool IsLowPixel(const double d)
Returns if the input pixel is one of the low saturation types.
Definition: SpecialPixel.h:261
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1298
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:101
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition: PixelType.h:62
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:108
ImageOverlay
Enumeration for different Mosaic priorities (input, mosaic, band)
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
bool IsValidPixel(const double d)
Returns if the input pixel is valid.
Definition: SpecialPixel.h:225
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Definition: PvlObject.cpp:207
int RecordSize() const
Returns the number of bytes per record.
Definition: Table.cpp:242
int RecordSize() const
Returns the number of bytes per record.
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Definition: PvlObject.cpp:148
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
QString name() const
Returns the keyword name.
Definition: PvlKeyword.h:114
int objects() const
Returns the number of objects.
Definition: PvlObject.h:231
A single keyword-value pair.
Definition: PvlKeyword.h:98
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
Definition: PvlKeyword.cpp:373
bool IsSpecial(const double d)
Returns if the input pixel is special.
Definition: SpecialPixel.h:199
void open(const QString &cfile, QString access="r")
This method will open an isis cube for reading or reading/writing.
Definition: Cube.cpp:509
Container for cube-like labels.
Definition: Pvl.h:135
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
Definition: Portal.h:109
void setUnits(QString units)
Sets the unit of measure for all current values if any exist.
Definition: PvlKeyword.cpp:182
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not...
Definition: PvlObject.h:335
Class for storing Table blobs information.
Definition: Table.h:74
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:112
bool IsHighPixel(const double d)
Returns if the input pixel is one of the high saturation types.
Definition: SpecialPixel.h:249
Isis exception class.
Definition: IException.h:99
bool IsNullPixel(const double d)
Returns if the input pixel is null.
Definition: SpecialPixel.h:237
Class for storing an Isis::Table&#39;s field information.
Definition: TableField.h:63
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString name() const
Returns the container name.
Definition: PvlContainer.h:78
IO Handler for Isis Cubes.
Definition: Cube.h:158

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:26:32