Commit 214ad229 authored by Kim Oyama's avatar Kim Oyama
Browse files

In CubeIoHandler, modified the findCubeChunks, writeIntoDouble, and...

In CubeIoHandler, modified the findCubeChunks, writeIntoDouble, and writeIntoRaw methods to handle repeating virtual bands. In cubeatt, added an app test for repeating virtual band input. Fixes #1927.

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@5764 41f8697f-d340-4b68-9986-7bafba869bb8
parent 5d141dda
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@
        http://isis.astrogeology.usgs.gov/documents/CommandLine/CommandLine.html
      for an explanation of Cube Attributes.
    </change>
    <change name="Kimberly Oyama" date="2014-04-07">
      Added an app test for repeating virtual band input. References #1927.
    </change>
  </history>

  <groups>
+7 −0
Original line number Diff line number Diff line
APPNAME = cubeatt

include $(ISISROOT)/make/isismake.tsts

commands:
	$(APPNAME) from=$(INPUT)/crop5by5_peaks.cub+3,2,4,2,1,5,7,6,4 \
	  to=$(OUTPUT)/bands324215764.cub > /dev/null;
+9 −4
Original line number Diff line number Diff line
@@ -173,10 +173,11 @@ Lbytes = 6563

Testing reading past cube boundaries ... 
Constructing cube ... 

File   = IsisCube_boundary.cub
Samps  = 10
Lines  = 10
Bands  = 2
Bands  = 4
Base   = 0
Mult   = 1
Type   = 7
@@ -189,16 +190,20 @@ Lbytes = 65536

Reading completely within cube boundaries ... 
	Comparing results ... 

Reading completely outside band boundaries ... 
	Comparing results ... 

Reading partially within band boundaries ... 
	 Reading bands 0 (should be null) and 1 (should be 1.0)... 
		 Comparing results ... 
	 Reading bands 4 (should be 1.0) and 5 (should be null)... 
		 Comparing results ... 

Testing reading past cube boundaries with virtual bands ... 
Testing reading past cube boundaries with virtual bands (2, 1, 3, 4, 2)... 
Reading completely outside virtual band boundaries ... 
Comparing results ... 
	Comparing results starting at band 6... 
	Comparing results starting at band 1000... 
	Comparing results starting at band -1... 

Reading partially within virtual band boundaries ... 
Comparing results ... 
+35 −19
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <cmath>
#include <iomanip>

#include <QDebug>
#include <QFile>
#include <QList>
#include <QListIterator>
@@ -264,6 +265,7 @@ namespace Isis {

    // NON-THREADED CUBE READ
    QList<RawCubeChunk *> cubeChunks;
    QList<int > chunkBands;

    int bufferSampleCount = bufferToFill.SampleDimension();
    int bufferLineCount = bufferToFill.LineDimension();
@@ -302,6 +304,7 @@ namespace Isis {
          chunkEndLine == bufferEndLine &&
          chunkEndBand == bufferEndBand) {
        cubeChunks.append(getChunk(expectedChunkIndex, true));
      chunkBands.append(cubeChunks.last()->getStartBand());
      }
    }

@@ -312,15 +315,17 @@ namespace Isis {
        bufferToFill[i] = Null;
      }

      cubeChunks = findCubeChunks(
    QPair< QList<RawCubeChunk *>, QList<int> > chunkInfo;
      chunkInfo = findCubeChunks(
          bufferToFill.Sample(), bufferToFill.SampleDimension(),
          bufferToFill.Line(), bufferToFill.LineDimension(),
          bufferToFill.Band(), bufferToFill.BandDimension());
      cubeChunks = chunkInfo.first;
      chunkBands = chunkInfo.second;
    }

    RawCubeChunk * fileData;
    foreach (fileData, cubeChunks) {
      writeIntoDouble(*fileData, bufferToFill);
    for (int i = 0; i < cubeChunks.size(); i++) {
      writeIntoDouble(*cubeChunks[i], bufferToFill, chunkBands[i]);
    }

    // Minimize the cache if it changed in size
@@ -752,13 +757,16 @@ namespace Isis {
   * @param numBands The number of bands of cube data
   * @return The cube chunks that correspond to the given cube area
   */
  QList<RawCubeChunk *> CubeIoHandler::findCubeChunks(int startSample,
  QPair< QList<RawCubeChunk *>, QList<int> > CubeIoHandler::findCubeChunks(int startSample,
      int numSamples, int startLine, int numLines, int startBand,
      int numBands) const {
    QList<RawCubeChunk *> results;

    int lastBand = min(startBand + numBands - 1,
                       bandCount());
    QList<int> resultBands;
/************************************************************************CHANGED THIS!!!!!!!!******/
    int lastBand = startBand + numBands - 1;
//     int lastBand = min(startBand + numBands - 1,
//                        bandCount());
/************************************************************************CHANGED THIS!!!!!!!!******/

    QRect areaInBand(
        QPoint(max(startSample, 1),
@@ -783,7 +791,6 @@ namespace Isis {
        else
          actualBand = (m_virtualBands->at(band - 1) - 1) / m_bandsInChunk + 1;
      }

      // We will be consuming areaLeftInBand until we've got all of the area
      //   requested.
      while(!areaLeftInBand.isEmpty()) {
@@ -842,6 +849,7 @@ namespace Isis {
        int initialChunkZPos = (actualBand - 1) / m_bandsInChunk;
        int initialChunkBand = initialChunkZPos * m_bandsInChunk + 1;
        

        QRect chunkRect(initialChunkXPos * m_samplesInChunk + 1,
                      initialChunkYPos * m_linesInChunk + 1,
                      m_samplesInChunk, m_linesInChunk);
@@ -864,6 +872,7 @@ namespace Isis {
          RawCubeChunk * newChunk = getChunk(chunkIndex, true);

          results.append(newChunk);
          resultBands.append(band);

          chunkRect.moveLeft(chunkRect.right() + 1);
        }
@@ -872,7 +881,7 @@ namespace Isis {
      }
    }

    return results;
    return QPair< QList<RawCubeChunk *>, QList<int> >(results, resultBands);
  }


@@ -1188,7 +1197,7 @@ namespace Isis {
        nullBuffer[i] = Null;
      }

      writeIntoRaw(nullBuffer, *result);
      writeIntoRaw(nullBuffer, *result, result->getStartBand());
      m_nullChunkData = new QByteArray(result->getRawData());
    }
    else {
@@ -1260,6 +1269,7 @@ namespace Isis {
   */
  void CubeIoHandler::synchronousWrite(const Buffer &bufferToWrite) {
    QList<RawCubeChunk *> cubeChunks;
    QList<int> cubeChunkBands;

    int bufferSampleCount = bufferToWrite.SampleDimension();
    int bufferLineCount = bufferToWrite.LineDimension();
@@ -1291,6 +1301,9 @@ namespace Isis {
           bufferBand >= chunkStartBand &&
           bufferBand <= chunkStartBand + chunkBands - 1) {
          cubeChunks = *m_lastProcessByLineChunks;
          for (int i = 0; i < cubeChunks.size(); i++) {
            cubeChunkBands.append( cubeChunks[i]->getStartBand() );
          }
        }
      }
    }
@@ -1328,14 +1341,18 @@ namespace Isis {
          chunkEndLine == bufferEndLine &&
          chunkEndBand == bufferEndBand) {
        cubeChunks.append(getChunk(expectedChunkIndex, true));
        cubeChunkBands.append(cubeChunks.last()->getStartBand());
      }
    }

    QPair< QList<RawCubeChunk *>, QList<int> > chunkInfo;
    if(cubeChunks.empty()) {
      cubeChunks = findCubeChunks(
      chunkInfo = findCubeChunks(
         bufferToWrite.Sample(), bufferSampleCount,
         bufferToWrite.Line(), bufferLineCount,
         bufferToWrite.Band(), bufferBandCount);
      cubeChunks = chunkInfo.first;
      cubeChunkBands = chunkInfo.second;
    }

    // process by line optimization
@@ -1351,7 +1368,7 @@ namespace Isis {
    }

    for(int i = 0; i < cubeChunks.size(); i++) {
      writeIntoRaw(bufferToWrite, *cubeChunks[i]);
      writeIntoRaw(bufferToWrite, *cubeChunks[i], cubeChunkBands[i]);
    }

    minimizeCache(cubeChunks, bufferToWrite);
@@ -1365,7 +1382,7 @@ namespace Isis {
   * @param output The data destination
   */
  void CubeIoHandler::writeIntoDouble(const RawCubeChunk &chunk,
                                      Buffer &output) const {
                                      Buffer &output, int index) const {
    // The code in this method is highly optimized. Even the order of the if
    //   statements will have a significant impact on performance if changed.
    //   Also, there is a lot of duplicate code in both writeIntoDouble(...) and
@@ -1398,9 +1415,7 @@ namespace Isis {
      const int &bandIntoChunk = z - chunkStartBand;
      int virtualBand = z;

      if(m_virtualBands) {
        virtualBand = m_virtualBands->indexOf(virtualBand) + 1;
      }
      virtualBand = index;

      if(virtualBand != 0 && virtualBand >= bufferBand &&
         virtualBand <= bufferBand + bufferBands - 1) {
@@ -1498,7 +1513,7 @@ namespace Isis {
   * @param buffer The data source
   * @param output The data destination
   */
  void CubeIoHandler::writeIntoRaw(const Buffer &buffer, RawCubeChunk &output)
  void CubeIoHandler::writeIntoRaw(const Buffer &buffer, RawCubeChunk &output, int index)
      const {
    // The code in this method is highly optimized. Even the order of the if
    //   statements will have a significant impact on performance if changed.
@@ -1529,7 +1544,8 @@ namespace Isis {

    for(int z = startZ; z <= endZ; z++) {
      const int &bandIntoChunk = z - outputStartBand;
      int virtualBand = z;
      int virtualBand = index;

      
      if(m_virtualBands) {
        virtualBand = m_virtualBands->indexOf(virtualBand) + 1;
+9 −6
Original line number Diff line number Diff line
@@ -96,7 +96,6 @@ namespace Isis {
   *                           were run before the adaptive cache flush size was
   *                           added, which improved performance further.
   *                           References #727.
   * 
   *   @history 2012-06-06 Jeff Anderson - The read() method was modified to
   *                           improve the speed for small buffer sizes as seen
   *                           in ProcessByBoxcar and ProcessRubbersheet.  The
@@ -104,6 +103,10 @@ namespace Isis {
   *                           which is slow for every read.  Now the cache is
   *                           only mimimized if it changed in size.  
   *                           Reference #894.
   *    @history 2014-04-07 Kimberly Oyama and Stuart Sides - Modified the findCubeChunks,
   *                            writeIntoDouble, and writeIntoRaw methods to handle
   *                            repeating virtual bands. Fixes #1927.
   *   
   */
  class CubeIoHandler {
    public:
@@ -227,9 +230,9 @@ namespace Isis {

      static bool bufferLessThan(Buffer * const &lhs, Buffer * const &rhs);

      QList<RawCubeChunk *> findCubeChunks(int startSample,
          int numSamples, int startLine, int numLines, int startBand,
          int numBands) const;
      QPair< QList<RawCubeChunk *>, QList<int> > findCubeChunks(int startSample, int numSamples,
                                                                int startLine, int numLines,
                                                                int startBand, int numBands) const;

      void findIntersection(const RawCubeChunk &cube1,
          const Buffer &cube2, int &startX, int &startY, int &startZ,
@@ -254,9 +257,9 @@ namespace Isis {

      void synchronousWrite(const Buffer &bufferToWrite);

      void writeIntoDouble(const RawCubeChunk &chunk, Buffer &output) const;
      void writeIntoDouble(const RawCubeChunk &chunk, Buffer &output, int startIndex) const;

      void writeIntoRaw(const Buffer &buffer, RawCubeChunk &output) const;
      void writeIntoRaw(const Buffer &buffer, RawCubeChunk &output, int index) const;

      void writeNullDataToDisk() const;

Loading