Isis 3.0
Back | Home
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 {
94  class ProcessByBrick : public Process {
95  public:
98 
100  virtual ~ProcessByBrick();
101 
105 
109  };
110 
111  using Process::SetInputCube;
112  Cube *SetInputCube(const QString &parameter,
113  int requirements = 0);
114 
115  Cube *SetInputCube(const QString &fname,
116  const CubeAttributeInput &att,
117  int requirements = 0);
118 
119  virtual void SetBricks(IOCubes cn);
120  void VerifyCubes(IOCubes cn);
121 
122  void SetBrickSize(int ns, int nl, int nb);
123 
124  void SetInputBrickSize(int ns, int nl, int nb);
125  void SetInputBrickSize(int ns, int nl, int nb, int cube);
126 
127  void SetOutputBrickSize(int ns, int nl, int nb);
128  void SetOutputBrickSize(int ns, int nl, int nb, int cube);
129 
130  // Overload the SetOutputCube() method to allow the user to pass in the
131  // file name and attributes without the lines and samples.
132  // Any other calls to this method will use the prototypes found in the
133  //process class due to the using statement below.
135  virtual Cube *SetOutputCube(const QString &fname,
136  const CubeAttributeOutput &att);
137 
140 
141  void SetOutputRequirements(int outputRequirements);
142  void SetWrap(bool wrap);
143  bool Wraps();
144 
145  using Isis::Process::StartProcess; // make parents virtual function visable
146  virtual void StartProcess(void funct(Buffer &in));
147  virtual void StartProcess(void funct(Buffer &in, Buffer &out));
148  virtual void StartProcess(void funct(std::vector<Buffer *> &in,
149  std::vector<Buffer *> &out));
150  void EndProcess();// Depricated. Please use Finalize
151  void Finalize();
152 
153 
174  template <typename Functor> void ProcessCubeInPlace(
175  const Functor & functor, bool threaded = true) {
176  Cube *cube = NULL;
177  Brick *brick = NULL;
178 
179  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
180  bool writeOutput = (!haveInput) || (cube->isReadWrite());
181 
182  ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
183  cube, brick, haveInput, writeOutput, functor);
184 
185  RunProcess(wrapperFunctor, brick->Bricks(), threaded);
186 
187  delete brick;
188  }
189 
190 
211  template <typename Functor> void ProcessCube(const Functor & functor,
212  bool threaded = true) {
213  Brick *inputCubeData = NULL;
214  Brick *outputCubeData = NULL;
215 
216  int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
217 
218  ProcessCubeFunctor<Functor> wrapperFunctor(InputCubes[0], inputCubeData,
219  OutputCubes[0], outputCubeData, functor);
220 
221  RunProcess(wrapperFunctor, numBricks, threaded);
222 
223  delete inputCubeData;
224  delete outputCubeData;
225  }
226 
227 
250  template <typename Functor> void ProcessCubes(const Functor & functor,
251  bool threaded = true) {
252  std::vector<Brick *> inputCubeData;
253  std::vector<Brick *> outputCubeData;
254 
255  std::vector<Buffer *> inputCubeDataParents;
256  std::vector<Buffer *> outputCubeDataParents;
257 
258  int numBricks = PrepProcessCubes(
259  inputCubeDataParents, outputCubeDataParents,
260  inputCubeData, outputCubeData);
261 
262  ProcessCubesFunctor<Functor> wrapperFunctor(InputCubes, inputCubeData,
263  OutputCubes, outputCubeData, Wraps(), functor);
264 
265  RunProcess(wrapperFunctor, numBricks, threaded);
266 
267  for(unsigned int i = 0; i < inputCubeData.size(); i++) {
268  delete inputCubeData[i];
269  }
270 
271  for(unsigned int i = 0; i < outputCubeData.size(); i++) {
272  delete outputCubeData[i];
273  }
274  }
275 
276 
277  private:
290  template <typename Functor>
291  void RunProcess(const Functor &wrapperFunctor,
292  int numSteps, bool threaded) {
293  ProcessIterator begin(0);
294  ProcessIterator end(numSteps);
295 
296  p_progress->SetMaximumSteps(numSteps);
298 
299  int threadCount = QThreadPool::globalInstance()->maxThreadCount();
300  if (threaded && threadCount > 1) {
301  QFuture<void> result = QtConcurrent::mapped(begin, end,
302  wrapperFunctor);
303  BlockingReportProgress(result);
304  }
305  else {
306  while (begin != end) {
307  wrapperFunctor(*begin);
308  ++begin;
310  }
311  }
312  }
313 
314 
329  template <typename T>
330  class ProcessCubeInPlaceFunctor :
331  public std::unary_function<const int &, void *> {
332  public:
348  ProcessCubeInPlaceFunctor(Cube *cube,
349  const Brick *templateBrick,
350  bool readInput, bool writeOutput,
351  const T &processingFunctor) :
352  m_cube(cube),
353  m_templateBrick(templateBrick),
354  m_readInput(readInput),
355  m_writeOutput(writeOutput),
356  m_processingFunctor(processingFunctor) {
357  }
358 
359 
365  ProcessCubeInPlaceFunctor(const ProcessCubeInPlaceFunctor &other) :
366  m_cube(other.m_cube),
367  m_templateBrick(other.m_templateBrick),
368  m_readInput(other.m_readInput),
369  m_writeOutput(other.m_writeOutput),
370  m_processingFunctor(other.m_processingFunctor) {
371  }
372 
373 
377  virtual ~ProcessCubeInPlaceFunctor() {
378  m_cube = NULL;
379  m_templateBrick = NULL;
380  }
381 
382 
389  void *operator()(const int &brickPosition) const {
390  Brick cubeData(*m_templateBrick);
391  cubeData.setpos(brickPosition);
392 
393  if (m_readInput)
394  m_cube->read(cubeData);
395 
396  m_processingFunctor(cubeData);
397 
398  if (m_writeOutput)
399  m_cube->write(cubeData);
400 
401  return NULL;
402  }
403 
404 
412  ProcessCubeInPlaceFunctor &operator=(
413  const ProcessCubeInPlaceFunctor &rhs) {
414  m_cube = rhs.m_cube;
415  m_templateBrick = rhs.m_templateBrick;
416 
417  m_readInput = rhs.m_readInput;
418  m_writeOutput = rhs.m_writeOutput;
419 
420  m_processingFunctor = rhs.m_processingFunctor;
421 
422  return *this;
423  }
424 
425  private:
427  Cube *m_cube;
429  const Brick *m_templateBrick;
431  bool m_readInput;
433  bool m_writeOutput;
434 
436  const T &m_processingFunctor;
437  };
438 
439 
453  template <typename T>
454  class ProcessCubeFunctor :
455  public std::unary_function<const int &, void *> {
456  public:
472  ProcessCubeFunctor(Cube *inputCube,
473  const Brick *inputTemplateBrick,
474  Cube *outputCube,
475  const Brick *outputTemplateBrick,
476  const T &processingFunctor) :
477  m_inputCube(inputCube),
478  m_inputTemplateBrick(inputTemplateBrick),
479  m_outputCube(outputCube),
480  m_outputTemplateBrick(outputTemplateBrick),
481  m_processingFunctor(processingFunctor) {
482  }
483 
484 
490  ProcessCubeFunctor(const ProcessCubeFunctor &other) :
491  m_inputCube(other.m_inputCube),
492  m_inputTemplateBrick(other.m_inputTemplateBrick),
493  m_outputCube(other.m_outputCube),
494  m_outputTemplateBrick(other.m_outputTemplateBrick),
495  m_processingFunctor(other.m_processingFunctor) {
496  }
497 
498 
502  virtual ~ProcessCubeFunctor() {
503  m_inputTemplateBrick = NULL;
504  m_outputTemplateBrick = NULL;
505  }
506 
507 
514  void *operator()(const int &brickPosition) const {
515  Brick inputCubeData(*m_inputTemplateBrick);
516  Brick outputCubeData(*m_outputTemplateBrick);
517 
518  inputCubeData.setpos(brickPosition);
519  outputCubeData.setpos(brickPosition);
520 
521  m_inputCube->read(inputCubeData);
522 
523  m_processingFunctor(inputCubeData, outputCubeData);
524 
525  m_outputCube->write(outputCubeData);
526 
527  return NULL;
528  }
529 
530 
538  ProcessCubeFunctor &operator=(const ProcessCubeFunctor &rhs) {
539  m_inputCube = rhs.m_inputCube;
540  m_inputTemplateBrick = rhs.m_inputTemplateBrick;
541 
542  m_outputCube = rhs.m_outputCube;
543  m_outputTemplateBrick = rhs.m_outputTemplateBrick;
544 
545  m_processingFunctor = rhs.m_processingFunctor;
546 
547  return *this;
548  }
549 
550  private:
552  Cube *m_inputCube;
554  const Brick *m_inputTemplateBrick;
555 
557  Cube *m_outputCube;
559  const Brick *m_outputTemplateBrick;
560 
562  const T &m_processingFunctor;
563  };
564 
565 
580  template <typename T>
581  class ProcessCubesFunctor :
582  public std::unary_function<const int &, void *> {
583  public:
603  ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
604  std::vector<Brick *> &inputTemplateBricks,
605  std::vector<Cube *> &outputCubes,
606  std::vector<Brick *> &outputTemplateBricks,
607  bool wraps,
608  const T &processingFunctor) :
609  m_inputCubes(inputCubes),
610  m_inputTemplateBricks(inputTemplateBricks),
611  m_outputCubes(outputCubes),
612  m_outputTemplateBricks(outputTemplateBricks),
613  m_wraps(wraps),
614  m_processingFunctor(processingFunctor) {
615  }
616 
617 
623  ProcessCubesFunctor(const ProcessCubesFunctor &other) :
624  m_inputCubes(other.m_inputCubes),
625  m_inputTemplateBricks(other.m_inputTemplateBricks),
626  m_outputCubes(other.m_outputCubes),
627  m_outputTemplateBricks(other.m_outputTemplateBricks),
628  m_wraps(other.m_wraps),
629  m_processingFunctor(other.m_processingFunctor) {
630  }
631 
632 
636  virtual ~ProcessCubesFunctor() {
637  }
638 
639 
646  void *operator()(const int &brickPosition) const {
647  QPair< std::vector<Buffer *>, std::vector<Buffer *> > functorBricks;
648 
649  for (int i = 0; i < (int)m_inputTemplateBricks.size(); i++) {
650  Brick *inputBrick = new Brick(*m_inputTemplateBricks[i]);
651  functorBricks.first.push_back(inputBrick);
652 
653  if (m_wraps) {
654  inputBrick->setpos(brickPosition % inputBrick->Bricks());
655  }
656  else {
657  inputBrick->setpos(brickPosition);
658  }
659 
660  if (i != 0 &&
661  functorBricks.first.size() &&
662  inputBrick->Band() != functorBricks.first[0]->Band() &&
663  m_inputCubes[i]->bandCount() != 1) {
664  inputBrick->SetBaseBand(functorBricks.first[0]->Band());
665  }
666 
667  m_inputCubes[i]->read(*inputBrick);
668  }
669 
670  for (int i = 0; i < (int)m_outputTemplateBricks.size(); i++) {
671  Brick *outputBrick = new Brick(*m_outputTemplateBricks[i]);
672  functorBricks.second.push_back(outputBrick);
673  outputBrick->setpos(brickPosition);
674  }
675 
676  // Pass them to the application function
677  m_processingFunctor(functorBricks.first, functorBricks.second);
678 
679  // And copy them into the output cubes
680  for (int i = 0; i < (int)functorBricks.second.size(); i++) {
681  m_outputCubes[i]->write(*functorBricks.second[i]);
682  delete functorBricks.second[i];
683  }
684 
685  for (int i = 0; i < (int)functorBricks.first.size(); i++) {
686  delete functorBricks.first[i];
687  }
688 
689  return NULL;
690  }
691 
692 
700  ProcessCubesFunctor &operator=(const ProcessCubesFunctor &rhs) {
701  m_inputCubes = rhs.m_inputCubes;
702  m_inputTemplateBricks = rhs.m_inputTemplateBricks;
703 
704  m_outputCubes = rhs.m_outputCubes;
705  m_outputTemplateBricks = rhs.m_outputTemplateBricks;
706 
707  m_wraps = rhs.m_wraps;
708 
709  m_processingFunctor = rhs.m_processingFunctor;
710 
711  return *this;
712  }
713 
714  private:
716  std::vector<Cube *> m_inputCubes;
721  std::vector<Brick *> &m_inputTemplateBricks;
722 
724  std::vector<Cube *> m_outputCubes;
729  std::vector<Brick *> &m_outputTemplateBricks;
730 
732  bool m_wraps;
733 
735  const T &m_processingFunctor;
736  };
737 
738 
739  void BlockingReportProgress(QFuture<void> &future);
740  std::vector<int> CalculateMaxDimensions(std::vector<Cube *> cubes) const;
741  bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks);
742  int PrepProcessCube(Brick **ibrick, Brick **obrick);
743  int PrepProcessCubes(std::vector<Buffer *> & ibufs,
744  std::vector<Buffer *> & obufs,
745  std::vector<Brick *> & imgrs,
746  std::vector<Brick *> & omgrs);
747 
748 
758  class ProcessIterator : public std::iterator<
759  std::forward_iterator_tag, int> {
760  public:
761  ProcessIterator(int position);
762  ProcessIterator(const ProcessIterator &other);
763  virtual ~ProcessIterator();
764 
765  ProcessIterator &operator++();
766 
773  bool operator==(const ProcessIterator &rhs) {
774  return (m_currentPosition == rhs.m_currentPosition);
775  }
776 
783  bool operator!=(const ProcessIterator &rhs) {
784  return !(*this == rhs);
785  }
786 
787 
793  void swap(ProcessIterator &other) {
794  std::swap(m_currentPosition, other.m_currentPosition);
795  }
796 
797 
804  ProcessIterator &operator=(const ProcessIterator &rhs) {
805  ProcessIterator copy(rhs);
806  swap(copy);
807  return *this;
808  }
809 
810 
815  int operator*() const {
816  return m_currentPosition;
817  }
818 
819  private:
821  int m_currentPosition;
822  };
823 
824  private:
825  bool p_reverse;
828  bool p_wrapOption;
829  bool p_inputBrickSizeSet;
831  bool p_outputBrickSizeSet;
834  int p_outputRequirements;
835 
836 
837  std::vector<int> p_inputBrickSamples;
839  std::vector<int> p_inputBrickLines;
841  std::vector<int> p_inputBrickBands;
843  std::vector<int> p_outputBrickSamples;
845  std::vector<int> p_outputBrickLines;
847  std::vector<int> p_outputBrickBands;
853  };
854 
855 };
856 
857 #endif
Buffer for reading and writing cube data.
Definition: Buffer.h:68
Manipulate and parse attributes of input cube filenames.
Definition: CubeAttribute.h:395
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:252
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
Definition: ProcessByBrick.cpp:614
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:101
Definition: ProcessByBrick.h:108
Definition: ProcessByBrick.h:103
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
Definition: ProcessByBrick.cpp:139
IOCubes
Definition: ProcessByBrick.h:102
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
Definition: ProcessByBrick.cpp:50
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition: Process.h:205
Definition: ProcessByBrick.h:102
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
Definition: ProcessByBrick.cpp:391
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:464
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:60
Definition: ProcessByBrick.h:107
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:150
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:250
ProcessingDirection
Definition: ProcessByBrick.h:106
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
Definition: ProcessByBrick.cpp:268
Definition: ProcessByBrick.h:104
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:73
virtual void SetBricks(IOCubes cn)
Definition: ProcessByBrick.cpp:117
Process cubes by brick.
Definition: ProcessByBrick.h:94
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:227
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
Definition: ProcessByBrick.h:174
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:160
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:485
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:211
Isis::Progress * p_progress
Pointer to a Progress object.
Definition: Process.h:159
ProcessingDirection GetProcessingDirection()
Returns the direction the data will be read, either all lines in a single band proceeding to the next...
Definition: ProcessByBrick.cpp:420
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:407
void SetOutputRequirements(int outputRequirements)
Definition: ProcessByBrick.cpp:110
Definition: CubeIoHandler.h:39
ProcessByBrick()
Constructs a ProcessByBrick object.
Definition: ProcessByBrick.cpp:31
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
Definition: ProcessByBrick.cpp:436
void Finalize()
Cleans up by closing cubes and freeing memory.
Definition: ProcessByBrick.cpp:624
Base class for all cube processing derivatives.
Definition: Process.h:157
bool Wraps()
Returns true if the wrapping option is enabled.
Definition: ProcessByBrick.cpp:446
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
Definition: ProcessByBrick.cpp:327
std::vector< Isis::Cube * > InputCubes
A vector of pointers to opened Cube objects.
Definition: Process.h:199
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:25:56