Isis 3 Programmer Reference
ProcessByBrick.h
Go to the documentation of this file.
1 #ifndef ProcessByBrick_h
2 #define ProcessByBrick_h
3 
25 #include <functional>
26 #include <QtConcurrentMap>
27 #include <QTime>
28 
29 #include "Brick.h"
30 #include "Buffer.h"
31 #include "Cube.h"
32 #include "Process.h"
33 #include "Progress.h"
34 
35 namespace Isis {
97  class ProcessByBrick : public Process {
98  public:
100  ProcessByBrick();
101 
103  virtual ~ProcessByBrick();
104 
105  enum IOCubes{InPlace,
106  InputOutput,
107  InputOutputList};
108 
109  enum ProcessingDirection {
110  LinesFirst,
111  BandsFirst
112  };
113 
114  using Process::SetInputCube;
115  Cube *SetInputCube(const QString &parameter,
116  int requirements = 0);
117 
118  Cube *SetInputCube(const QString &fname,
119  const CubeAttributeInput &att,
120  int requirements = 0);
121 
122  virtual void SetBricks(IOCubes cn);
123  void VerifyCubes(IOCubes cn);
124 
125  void SetBrickSize(int ns, int nl, int nb);
126 
127  void SetInputBrickSize(int ns, int nl, int nb);
128  void SetInputBrickSize(int ns, int nl, int nb, int cube);
129 
130  void SetOutputBrickSize(int ns, int nl, int nb);
131  void SetOutputBrickSize(int ns, int nl, int nb, int cube);
132 
133  // Overload the SetOutputCube() method to allow the user to pass in the
134  // file name and attributes without the lines and samples.
135  // Any other calls to this method will use the prototypes found in the
136  //process class due to the using statement below.
138  virtual Cube *SetOutputCube(const QString &fname,
139  const CubeAttributeOutput &att);
140 
141  void SetProcessingDirection(ProcessingDirection direction);
142  ProcessingDirection GetProcessingDirection();
143 
144  void SetOutputRequirements(int outputRequirements);
145  void SetWrap(bool wrap);
146  bool Wraps();
147 
148  using Isis::Process::StartProcess; // make parents virtual function visable
149  virtual void StartProcess(void funct(Buffer &in));
150  virtual void StartProcess(std::function<void(Buffer &in)> funct );
151  virtual void StartProcess(std::function<void(Buffer &in, Buffer &out)> funct);
152  virtual void StartProcess(void funct(Buffer &in, Buffer &out));
153  virtual void StartProcess(void funct(std::vector<Buffer *> &in,
154  std::vector<Buffer *> &out));
155  void EndProcess();// Depricated. Please use Finalize
156  void Finalize();
157 
158 
179  template <typename Functor> void ProcessCubeInPlace(
180  const Functor & functor, bool threaded = true) {
181  Cube *cube = NULL;
182  Brick *brick = NULL;
183 
184  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
185  bool writeOutput = (!haveInput) || (cube->isReadWrite());
186 
187  ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
188  cube, brick, haveInput, writeOutput, functor);
189 
190  RunProcess(wrapperFunctor, brick->Bricks(), threaded);
191 
192  delete brick;
193  }
194 
195 
216  template <typename Functor> void ProcessCube(const Functor & functor,
217  bool threaded = true) {
218  Brick *inputCubeData = NULL;
219  Brick *outputCubeData = NULL;
220 
221  int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
222 
223  ProcessCubeFunctor<Functor> wrapperFunctor(InputCubes[0], inputCubeData,
224  OutputCubes[0], outputCubeData, functor);
225 
226  RunProcess(wrapperFunctor, numBricks, threaded);
227 
228  delete inputCubeData;
229  delete outputCubeData;
230  }
231 
232 
255  template <typename Functor> void ProcessCubes(const Functor & functor,
256  bool threaded = true) {
257  std::vector<Brick *> inputCubeData;
258  std::vector<Brick *> outputCubeData;
259 
260  std::vector<Buffer *> inputCubeDataParents;
261  std::vector<Buffer *> outputCubeDataParents;
262 
263  int numBricks = PrepProcessCubes(
264  inputCubeDataParents, outputCubeDataParents,
265  inputCubeData, outputCubeData);
266 
267  ProcessCubesFunctor<Functor> wrapperFunctor(InputCubes, inputCubeData,
268  OutputCubes, outputCubeData, Wraps(), functor);
269 
270  RunProcess(wrapperFunctor, numBricks, threaded);
271 
272  for(unsigned int i = 0; i < inputCubeData.size(); i++) {
273  delete inputCubeData[i];
274  }
275 
276  for(unsigned int i = 0; i < outputCubeData.size(); i++) {
277  delete outputCubeData[i];
278  }
279  }
280 
281 
282  private:
295  template <typename Functor>
296  void RunProcess(const Functor &wrapperFunctor,
297  int numSteps, bool threaded) {
298  ProcessIterator begin(0);
299  ProcessIterator end(numSteps);
300 
301  p_progress->SetMaximumSteps(numSteps);
303 
304  int threadCount = QThreadPool::globalInstance()->maxThreadCount();
305  if (threaded && threadCount > 1) {
306  QFuture<void> result = QtConcurrent::mapped(begin, end,
307  wrapperFunctor);
308  BlockingReportProgress(result);
309  }
310  else {
311  while (begin != end) {
312  wrapperFunctor(*begin);
313  ++begin;
315  }
316  }
317  }
318 
319 
334  template <typename T>
336  public std::unary_function<const int &, void *> {
337  public:
354  const Brick *templateBrick,
355  bool readInput, bool writeOutput,
356  const T &processingFunctor) :
357  m_cube(cube),
358  m_templateBrick(templateBrick),
359  m_readInput(readInput),
360  m_writeOutput(writeOutput),
361  m_processingFunctor(processingFunctor) {
362  }
363 
364 
371  m_cube(other.m_cube),
373  m_readInput(other.m_readInput),
376  }
377 
378 
383  m_cube = NULL;
384  m_templateBrick = NULL;
385  }
386 
387 
394  void *operator()(const int &brickPosition) const {
395  Brick cubeData(*m_templateBrick);
396  cubeData.setpos(brickPosition);
397 
398  if (m_readInput)
399  m_cube->read(cubeData);
400 
401  m_processingFunctor(cubeData);
402 
403  if (m_writeOutput)
404  m_cube->write(cubeData);
405 
406  return NULL;
407  }
408 
409 
418  const ProcessCubeInPlaceFunctor &rhs) {
419  m_cube = rhs.m_cube;
421 
422  m_readInput = rhs.m_readInput;
424 
426 
427  return *this;
428  }
429 
430  private:
439 
442  };
443 
444 
458  template <typename T>
460  public std::unary_function<const int &, void *> {
461  public:
478  const Brick *inputTemplateBrick,
479  Cube *outputCube,
480  const Brick *outputTemplateBrick,
481  const T &processingFunctor) :
482  m_inputCube(inputCube),
483  m_inputTemplateBrick(inputTemplateBrick),
484  m_outputCube(outputCube),
485  m_outputTemplateBrick(outputTemplateBrick),
486  m_processingFunctor(processingFunctor) {
487  }
488 
489 
496  m_inputCube(other.m_inputCube),
498  m_outputCube(other.m_outputCube),
501  }
502 
503 
508  m_inputTemplateBrick = NULL;
509  m_outputTemplateBrick = NULL;
510  }
511 
512 
519  void *operator()(const int &brickPosition) const {
520  Brick inputCubeData(*m_inputTemplateBrick);
521  Brick outputCubeData(*m_outputTemplateBrick);
522 
523  inputCubeData.setpos(brickPosition);
524  outputCubeData.setpos(brickPosition);
525 
526  m_inputCube->read(inputCubeData);
527 
528  m_processingFunctor(inputCubeData, outputCubeData);
529 
530  m_outputCube->write(outputCubeData);
531 
532  return NULL;
533  }
534 
535 
544  m_inputCube = rhs.m_inputCube;
546 
549 
551 
552  return *this;
553  }
554 
555  private:
560 
565 
568  };
569 
570 
585  template <typename T>
587  public std::unary_function<const int &, void *> {
588  public:
608  ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
609  std::vector<Brick *> &inputTemplateBricks,
610  std::vector<Cube *> &outputCubes,
611  std::vector<Brick *> &outputTemplateBricks,
612  bool wraps,
613  const T &processingFunctor) :
614  m_inputCubes(inputCubes),
615  m_inputTemplateBricks(inputTemplateBricks),
616  m_outputCubes(outputCubes),
617  m_outputTemplateBricks(outputTemplateBricks),
618  m_wraps(wraps),
619  m_processingFunctor(processingFunctor) {
620  }
621 
622 
629  m_inputCubes(other.m_inputCubes),
633  m_wraps(other.m_wraps),
635  }
636 
637 
642  }
643 
644 
651  void *operator()(const int &brickPosition) const {
652  QPair< std::vector<Buffer *>, std::vector<Buffer *> > functorBricks;
653 
654  for (int i = 0; i < (int)m_inputTemplateBricks.size(); i++) {
655  Brick *inputBrick = new Brick(*m_inputTemplateBricks[i]);
656  functorBricks.first.push_back(inputBrick);
657 
658  if (m_wraps) {
659  inputBrick->setpos(brickPosition % inputBrick->Bricks());
660  }
661  else {
662  inputBrick->setpos(brickPosition);
663  }
664 
665  if (i != 0 &&
666  functorBricks.first.size() &&
667  inputBrick->Band() != functorBricks.first[0]->Band() &&
668  m_inputCubes[i]->bandCount() != 1) {
669  inputBrick->SetBaseBand(functorBricks.first[0]->Band());
670  }
671 
672  m_inputCubes[i]->read(*inputBrick);
673  }
674 
675  for (int i = 0; i < (int)m_outputTemplateBricks.size(); i++) {
676  Brick *outputBrick = new Brick(*m_outputTemplateBricks[i]);
677  functorBricks.second.push_back(outputBrick);
678  outputBrick->setpos(brickPosition);
679  }
680 
681  // Pass them to the application function
682  m_processingFunctor(functorBricks.first, functorBricks.second);
683 
684  // And copy them into the output cubes
685  for (int i = 0; i < (int)functorBricks.second.size(); i++) {
686  m_outputCubes[i]->write(*functorBricks.second[i]);
687  delete functorBricks.second[i];
688  }
689 
690  for (int i = 0; i < (int)functorBricks.first.size(); i++) {
691  delete functorBricks.first[i];
692  }
693 
694  return NULL;
695  }
696 
697 
708 
711 
712  m_wraps = rhs.m_wraps;
713 
715 
716  return *this;
717  }
718 
719  private:
721  std::vector<Cube *> m_inputCubes;
726  std::vector<Brick *> &m_inputTemplateBricks;
727 
729  std::vector<Cube *> m_outputCubes;
734  std::vector<Brick *> &m_outputTemplateBricks;
735 
737  bool m_wraps;
738 
741  };
742 
743 
744  void BlockingReportProgress(QFuture<void> &future);
745  std::vector<int> CalculateMaxDimensions(std::vector<Cube *> cubes) const;
746  bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks);
747  int PrepProcessCube(Brick **ibrick, Brick **obrick);
748  int PrepProcessCubes(std::vector<Buffer *> & ibufs,
749  std::vector<Buffer *> & obufs,
750  std::vector<Brick *> & imgrs,
751  std::vector<Brick *> & omgrs);
752 
753 
763  class ProcessIterator : public std::iterator<
764  std::forward_iterator_tag, int> {
765  public:
766  ProcessIterator(int position);
767  ProcessIterator(const ProcessIterator &other);
768  virtual ~ProcessIterator();
769 
771 
778  bool operator==(const ProcessIterator &rhs) {
779  return (m_currentPosition == rhs.m_currentPosition);
780  }
781 
788  bool operator!=(const ProcessIterator &rhs) {
789  return !(*this == rhs);
790  }
791 
792 
798  void swap(ProcessIterator &other) {
799  std::swap(m_currentPosition, other.m_currentPosition);
800  }
801 
802 
810  ProcessIterator copy(rhs);
811  swap(copy);
812  return *this;
813  }
814 
815 
820  int operator*() const {
821  return m_currentPosition;
822  }
823 
824  private:
827  };
828 
829  private:
830  bool p_reverse;
839  int p_outputRequirements;
840 
841 
842  std::vector<int> p_inputBrickSamples;
844  std::vector<int> p_inputBrickLines;
846  std::vector<int> p_inputBrickBands;
848  std::vector<int> p_outputBrickSamples;
850  std::vector<int> p_outputBrickLines;
852  std::vector<int> p_outputBrickBands;
858  };
859 
860 };
861 
862 #endif
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
Buffer for reading and writing cube data.
Definition: Buffer.h:69
Manipulate and parse attributes of input cube filenames.
void SetBrickSize(int ns, int nl, int nb)
Sets the input and output bricks sizes to the given number of samples, lines, and bands...
int m_currentPosition
The current iterator&#39;s position/value.
std::vector< int > p_outputBrickBands
Number of bands in the output bricks.
Cube * m_outputCube
The cube to write to with the output of m_processingFunctor.
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
Create an arbitrary number of output cubes given an arbitrary number of input cubes (these counts can...
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:101
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
Definition: Buffer.cpp:178
This class is designed to iterate over all brick positions in a cube.
std::vector< int > CalculateMaxDimensions(std::vector< Cube *> cubes) const
Calculates the maximum dimensions of all the cubes and returns them in a vector where position 0 is t...
std::vector< Brick * > & m_outputTemplateBricks
Template bricks for writing output data.
void BlockingReportProgress(QFuture< void > &future)
This method blocks until the future reports that it is finished.
ProcessCubeFunctor(const ProcessCubeFunctor &other)
Copy construction of these objects is fully supported.
ProcessCubeInPlaceFunctor(const ProcessCubeInPlaceFunctor &other)
Copy construction of these objects is fully supported.
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
ProcessCubeInPlaceFunctor & operator=(const ProcessCubeInPlaceFunctor &rhs)
Assignment of these objects is fully supported.
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition: Process.h:206
int PrepProcessCube(Brick **ibrick, Brick **obrick)
Prepare and check to run "function" parameter for StartProcess(void funct(Buffer &in, Buffer &out)) and StartProcessIO(Functor funct)
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
void swap(ProcessIterator &other)
Exception-safe swap method.
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
virtual void StartProcess(void funct(Buffer &in))
Starts the systematic processing of the input cube by moving an arbitrary shaped brick through the cu...
bool m_readInput
Should we read from the cube before processing.
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:61
void ProcessCubes(const Functor &functor, bool threaded=true)
Operate over an arbitrary number of input cubes given an arbitrary number of output cubes...
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
std::vector< int > p_outputBrickLines
Number of lines in the output bricks.
bool p_wrapOption
Indicates whether the brick manager will wrap.
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
Cube * SetInputCube(const QString &parameter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
ProcessCubesFunctor(std::vector< Cube *> &inputCubes, std::vector< Brick *> &inputTemplateBricks, std::vector< Cube *> &outputCubes, std::vector< Brick *> &outputTemplateBricks, bool wraps, const T &processingFunctor)
Construct a ProcessCubesFunctor.
ProcessIterator & operator++()
Increment the process iterator to the next position.
Cube * m_inputCube
The cube to read from for the input brick data.
Process cubes by brick.
ProcessCubeInPlaceFunctor(Cube *cube, const Brick *templateBrick, bool readInput, bool writeOutput, const T &processingFunctor)
Construct a ProcessCubeInPlaceFunctor.
std::vector< int > p_inputBrickLines
Number of lines in the input bricks.
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:121
std::vector< Cube * > m_inputCubes
The input cubes for reading data from.
bool p_reverse
Use the reverse option for constructing the Buffer objects when the Processing Direction is changed f...
virtual void StartProcess(void funct())
In the base class, this method will invoked a user-specified function exactly one time...
Definition: Process.h:228
std::vector< int > p_inputBrickBands
Number of bands in the input bricks.
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
bool isReadWrite() const
Test if the opened cube is read-write, that is read and write operations should succeed if this is tr...
Definition: Cube.cpp:152
int operator*() const
Convert this iterator into a position.
void SetBaseBand(const int start_band)
This method is used to set the base band position of the shape buffer.
Definition: Brick.h:164
int PrepProcessCubes(std::vector< Buffer *> &ibufs, std::vector< Buffer *> &obufs, std::vector< Brick *> &imgrs, std::vector< Brick *> &omgrs)
Prepare and check to run "function" parameter for StartProcess(void funct(vector<Buffer *> &in...
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:184
Process a cube in place (one input/zero output or zero input/one output or one cube that acts both as...
virtual Isis::Cube * SetInputCube(const QString &parameter, const int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
Definition: Process.cpp:243
Manipulate and parse attributes of output cube filenames.
void RunProcess(const Functor &wrapperFunctor, int numSteps, bool threaded)
This method runs the given wrapper functor numSteps times with or without threading, reporting progress in both cases.
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:724
std::vector< int > p_inputBrickSamples
Number of samples in the input bricks.
Create an output cube given one input cube.
bool setpos(BigInt map)
Sets the position of the shape in the cube.
virtual Isis::Cube * SetOutputCube(const QString &parameter)
Allocates a user-specified output cube whose size matches the first input cube.
Definition: Process.cpp:266
const Brick * m_templateBrick
A brick with the right dimensions, pixel type, etc. for processing.
bool operator==(const ProcessIterator &rhs)
Compare equality of two iterator positions.
void ProcessCube(const Functor &functor, bool threaded=true)
Operate over a single input cube creating a separate output cube.
bool m_wraps
Wrap smaller cubes back to the beginning?
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
Isis::Progress * p_progress
Pointer to a Progress object.
Definition: Process.h:160
ProcessingDirection GetProcessingDirection()
Returns the direction the data will be read, either all lines in a single band proceeding to the next...
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
void write(Blob &blob)
This method will write a blob of data (e.g.
Definition: Cube.cpp:763
ProcessIterator(int position)
Initialize a process iterator given a position.
void SetProcessingDirection(ProcessingDirection direction)
Set the direction the data will be read, either all lines in a single band proceeding to the next ban...
ProcessCubeFunctor & operator=(const ProcessCubeFunctor &rhs)
Assignment of these objects is fully supported.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool p_outputBrickSizeSet
Indicates whether the brick size has been set.
bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks)
Prepare and check to run "function" parameter for StartProcess(void funct(Buffer &in)) and StartProce...
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
const Brick * m_inputTemplateBrick
An example brick for the input parameter to m_processingFunctor.
bool m_writeOutput
Should we write to the output cube after processing.
ProcessIterator & operator=(const ProcessIterator &rhs)
Assignment of these iterators is fully supported.
ProcessByBrick()
Constructs a ProcessByBrick object.
ProcessCubesFunctor(const ProcessCubesFunctor &other)
Copy construction of these objects is fully supported.
Cube * m_cube
The cube we&#39;re I/O&#39;ing on.
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
void Finalize()
Cleans up by closing cubes and freeing memory.
bool p_inputBrickSizeSet
Indicates whether the brick size has been set.
Base class for all cube processing derivatives.
Definition: Process.h:158
std::vector< Brick * > & m_inputTemplateBricks
Template bricks for reading input data.
std::vector< Cube * > m_outputCubes
The output cubes for writing data to.
ProcessCubeFunctor(Cube *inputCube, const Brick *inputTemplateBrick, Cube *outputCube, const Brick *outputTemplateBrick, const T &processingFunctor)
Construct a ProcessCubeFunctor.
bool Wraps()
Returns true if the wrapping option is enabled.
ProcessCubesFunctor & operator=(const ProcessCubesFunctor &rhs)
Assignment of these objects is fully supported.
std::vector< int > p_outputBrickSamples
Number of samples in the output bricks.
const Brick * m_outputTemplateBrick
An example brick for the output parameter to m_processingFunctor.
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
bool operator!=(const ProcessIterator &rhs)
Compare inequality of two iterator positions.
std::vector< Isis::Cube * > InputCubes
A vector of pointers to opened Cube objects.
Definition: Process.h:200
IO Handler for Isis Cubes.
Definition: Cube.h:170