Isis 3 Developer 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 
108 
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 
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>
335  class ProcessCubeInPlaceFunctor :
336  public std::unary_function<const int &, void *> {
337  public:
353  ProcessCubeInPlaceFunctor(Cube *cube,
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 
370  ProcessCubeInPlaceFunctor(const ProcessCubeInPlaceFunctor &other) :
371  m_cube(other.m_cube),
372  m_templateBrick(other.m_templateBrick),
373  m_readInput(other.m_readInput),
374  m_writeOutput(other.m_writeOutput),
375  m_processingFunctor(other.m_processingFunctor) {
376  }
377 
378 
382  virtual ~ProcessCubeInPlaceFunctor() {
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 
417  ProcessCubeInPlaceFunctor &operator=(
418  const ProcessCubeInPlaceFunctor &rhs) {
419  m_cube = rhs.m_cube;
420  m_templateBrick = rhs.m_templateBrick;
421 
422  m_readInput = rhs.m_readInput;
423  m_writeOutput = rhs.m_writeOutput;
424 
425  m_processingFunctor = rhs.m_processingFunctor;
426 
427  return *this;
428  }
429 
430  private:
432  Cube *m_cube;
434  const Brick *m_templateBrick;
436  bool m_readInput;
438  bool m_writeOutput;
439 
441  const T &m_processingFunctor;
442  };
443 
444 
458  template <typename T>
459  class ProcessCubeFunctor :
460  public std::unary_function<const int &, void *> {
461  public:
477  ProcessCubeFunctor(Cube *inputCube,
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 
495  ProcessCubeFunctor(const ProcessCubeFunctor &other) :
496  m_inputCube(other.m_inputCube),
497  m_inputTemplateBrick(other.m_inputTemplateBrick),
498  m_outputCube(other.m_outputCube),
499  m_outputTemplateBrick(other.m_outputTemplateBrick),
500  m_processingFunctor(other.m_processingFunctor) {
501  }
502 
503 
507  virtual ~ProcessCubeFunctor() {
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 
543  ProcessCubeFunctor &operator=(const ProcessCubeFunctor &rhs) {
544  m_inputCube = rhs.m_inputCube;
545  m_inputTemplateBrick = rhs.m_inputTemplateBrick;
546 
547  m_outputCube = rhs.m_outputCube;
548  m_outputTemplateBrick = rhs.m_outputTemplateBrick;
549 
550  m_processingFunctor = rhs.m_processingFunctor;
551 
552  return *this;
553  }
554 
555  private:
557  Cube *m_inputCube;
559  const Brick *m_inputTemplateBrick;
560 
562  Cube *m_outputCube;
564  const Brick *m_outputTemplateBrick;
565 
567  const T &m_processingFunctor;
568  };
569 
570 
585  template <typename T>
586  class ProcessCubesFunctor :
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 
628  ProcessCubesFunctor(const ProcessCubesFunctor &other) :
629  m_inputCubes(other.m_inputCubes),
630  m_inputTemplateBricks(other.m_inputTemplateBricks),
631  m_outputCubes(other.m_outputCubes),
632  m_outputTemplateBricks(other.m_outputTemplateBricks),
633  m_wraps(other.m_wraps),
634  m_processingFunctor(other.m_processingFunctor) {
635  }
636 
637 
641  virtual ~ProcessCubesFunctor() {
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 
705  ProcessCubesFunctor &operator=(const ProcessCubesFunctor &rhs) {
706  m_inputCubes = rhs.m_inputCubes;
707  m_inputTemplateBricks = rhs.m_inputTemplateBricks;
708 
709  m_outputCubes = rhs.m_outputCubes;
710  m_outputTemplateBricks = rhs.m_outputTemplateBricks;
711 
712  m_wraps = rhs.m_wraps;
713 
714  m_processingFunctor = rhs.m_processingFunctor;
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 
740  const T &m_processingFunctor;
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 
770  ProcessIterator &operator++();
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 
809  ProcessIterator &operator=(const ProcessIterator &rhs) {
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:
826  int m_currentPosition;
827  };
828 
829  private:
830  bool p_reverse;
833  bool p_wrapOption;
834  bool p_inputBrickSizeSet;
836  bool p_outputBrickSizeSet;
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
Buffer for reading and writing cube data.
Definition: Buffer.h:69
Manipulate and parse attributes of input cube filenames.
Definition: CubeAttribute.h:397
void SetBrickSize(int ns, int nl, int nb)
Sets the input and output bricks sizes to the given number of samples, lines, and bands...
Definition: ProcessByBrick.cpp:241
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
Definition: ProcessByBrick.cpp:685
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:101
Definition: ProcessByBrick.h:111
Definition: ProcessByBrick.h:106
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
Definition: ProcessByBrick.cpp:136
IOCubes
Definition: ProcessByBrick.h:105
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
Definition: ProcessByBrick.cpp:51
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition: Process.h:206
Definition: ProcessByBrick.h:105
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
Definition: ProcessByBrick.cpp:380
virtual void StartProcess(void funct(Buffer &in))
Starts the systematic processing of the input cube by moving an arbitrary shaped brick through the cu...
Definition: ProcessByBrick.cpp:453
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:61
Definition: ProcessByBrick.h:110
void ProcessCubes(const Functor &functor, bool threaded=true)
Operate over an arbitrary number of input cubes given an arbitrary number of output cubes...
Definition: ProcessByBrick.h:255
ProcessingDirection
Definition: ProcessByBrick.h:109
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
Definition: ProcessByBrick.cpp:257
Definition: ProcessByBrick.h:107
Angle operator*(double mult, Angle angle)
Multiply this angle by a double and return the resulting angle.
Definition: Angle.cpp:185
Cube * SetInputCube(const QString &parameter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
Definition: ProcessByBrick.cpp:74
virtual void SetBricks(IOCubes cn)
Definition: ProcessByBrick.cpp:118
Process cubes by brick.
Definition: ProcessByBrick.h:97
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:121
virtual void StartProcess(void funct())
In the base class, this method will invoked a user-specified function exactly one time...
Definition: Process.h:228
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
Definition: ProcessByBrick.h:179
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 Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:184
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.
Definition: CubeAttribute.h:489
virtual Isis::Cube * SetOutputCube(const QString &parameter)
Allocates a user-specified output cube whose size matches the first input cube.
Definition: Process.cpp:266
void ProcessCube(const Functor &functor, bool threaded=true)
Operate over a single input cube creating a separate output cube.
Definition: ProcessByBrick.h:216
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...
Definition: ProcessByBrick.cpp:409
void SetProcessingDirection(ProcessingDirection direction)
Set the direction the data will be read, either all lines in a single band proceeding to the next ban...
Definition: ProcessByBrick.cpp:396
void SetOutputRequirements(int outputRequirements)
Definition: ProcessByBrick.cpp:111
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Definition: CubeIoHandler.h:39
ProcessByBrick()
Constructs a ProcessByBrick object.
Definition: ProcessByBrick.cpp:32
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
Definition: ProcessByBrick.cpp:425
void Finalize()
Cleans up by closing cubes and freeing memory.
Definition: ProcessByBrick.cpp:695
Base class for all cube processing derivatives.
Definition: Process.h:158
bool Wraps()
Returns true if the wrapping option is enabled.
Definition: ProcessByBrick.cpp:435
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
Definition: ProcessByBrick.cpp:316
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