Isis Developer Reference
ProcessByBrick.h
Go to the documentation of this file.
1 #ifndef ProcessByBrick_h
2 #define ProcessByBrick_h
3 
8 /* SPDX-License-Identifier: CC0-1.0 */
9 #include <functional>
10 #include <QtConcurrentMap>
11 #include <QTime>
12 
13 #include "Brick.h"
14 #include "Buffer.h"
15 #include "Cube.h"
16 #include "Process.h"
17 #include "Progress.h"
18 
19 namespace Isis {
81  class ProcessByBrick : public Process {
82  public:
85 
87  virtual ~ProcessByBrick();
88 
92 
96  };
97 
99  Cube *SetInputCube(const QString &parameter,
100  int requirements = 0);
101 
102  Cube *SetInputCube(const QString &fname,
103  const CubeAttributeInput &att,
104  int requirements = 0);
105 
106  virtual void SetBricks(IOCubes cn);
107  void VerifyCubes(IOCubes cn);
108 
109  void SetBrickSize(int ns, int nl, int nb);
110 
111  void SetInputBrickSize(int ns, int nl, int nb);
112  void SetInputBrickSize(int ns, int nl, int nb, int cube);
113 
114  void SetOutputBrickSize(int ns, int nl, int nb);
115  void SetOutputBrickSize(int ns, int nl, int nb, int cube);
116 
117  // Overload the SetOutputCube() method to allow the user to pass in the
118  // file name and attributes without the lines and samples.
119  // Any other calls to this method will use the prototypes found in the
120  //process class due to the using statement below.
122  virtual Cube *SetOutputCube(const QString &fname,
123  const CubeAttributeOutput &att);
124 
127 
128  void SetOutputRequirements(int outputRequirements);
129  void SetWrap(bool wrap);
130  bool Wraps();
131 
132  using Isis::Process::StartProcess; // make parents virtual function visable
133  virtual void StartProcess(void funct(Buffer &in));
134  virtual void StartProcess(std::function<void(Buffer &in)> funct );
135  virtual void StartProcess(std::function<void(Buffer &in, Buffer &out)> funct);
136  virtual void StartProcess(void funct(Buffer &in, Buffer &out));
137  virtual void StartProcess(void funct(std::vector<Buffer *> &in,
138  std::vector<Buffer *> &out));
139  void EndProcess();// Depricated. Please use Finalize
140  void Finalize();
141 
142 
163  template <typename Functor> void ProcessCubeInPlace(
164  const Functor & functor, bool threaded = true) {
165  Cube *cube = NULL;
166  Brick *brick = NULL;
167 
168  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
169  bool writeOutput = (!haveInput) || (cube->isReadWrite());
170 
171  ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
172  cube, brick, haveInput, writeOutput, functor);
173 
174  RunProcess(wrapperFunctor, brick->Bricks(), threaded);
175 
176  delete brick;
177  }
178 
179 
200  template <typename Functor> void ProcessCube(const Functor & functor,
201  bool threaded = true) {
202  Brick *inputCubeData = NULL;
203  Brick *outputCubeData = NULL;
204 
205  int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
206 
207  ProcessCubeFunctor<Functor> wrapperFunctor(InputCubes[0], inputCubeData,
208  OutputCubes[0], outputCubeData, functor);
209 
210  RunProcess(wrapperFunctor, numBricks, threaded);
211 
212  delete inputCubeData;
213  delete outputCubeData;
214  }
215 
216 
239  template <typename Functor> void ProcessCubes(const Functor & functor,
240  bool threaded = true) {
241  std::vector<Brick *> inputCubeData;
242  std::vector<Brick *> outputCubeData;
243 
244  std::vector<Buffer *> inputCubeDataParents;
245  std::vector<Buffer *> outputCubeDataParents;
246 
247  int numBricks = PrepProcessCubes(
248  inputCubeDataParents, outputCubeDataParents,
249  inputCubeData, outputCubeData);
250 
251  ProcessCubesFunctor<Functor> wrapperFunctor(InputCubes, inputCubeData,
252  OutputCubes, outputCubeData, Wraps(), functor);
253 
254  RunProcess(wrapperFunctor, numBricks, threaded);
255 
256  for(unsigned int i = 0; i < inputCubeData.size(); i++) {
257  delete inputCubeData[i];
258  }
259 
260  for(unsigned int i = 0; i < outputCubeData.size(); i++) {
261  delete outputCubeData[i];
262  }
263  }
264 
265 
266  private:
279  template <typename Functor>
280  void RunProcess(const Functor &wrapperFunctor,
281  int numSteps, bool threaded) {
282  ProcessIterator begin(0);
283  ProcessIterator end(numSteps);
284 
285  p_progress->SetMaximumSteps(numSteps);
287 
288  int threadCount = QThreadPool::globalInstance()->maxThreadCount();
289  if (threaded && threadCount > 1) {
290  QFuture<void> result = QtConcurrent::mapped(begin, end,
291  wrapperFunctor);
292  BlockingReportProgress(result);
293  }
294  else {
295  while (begin != end) {
296  wrapperFunctor(*begin);
297  ++begin;
299  }
300  }
301  }
302 
303 
318  template <typename T>
319  class ProcessCubeInPlaceFunctor :
320  public std::unary_function<const int &, void *> {
321  public:
337  ProcessCubeInPlaceFunctor(Cube *cube,
338  const Brick *templateBrick,
339  bool readInput, bool writeOutput,
340  const T &processingFunctor) :
341  m_cube(cube),
342  m_templateBrick(templateBrick),
343  m_readInput(readInput),
344  m_writeOutput(writeOutput),
345  m_processingFunctor(processingFunctor) {
346  }
347 
348 
354  ProcessCubeInPlaceFunctor(const ProcessCubeInPlaceFunctor &other) :
355  m_cube(other.m_cube),
356  m_templateBrick(other.m_templateBrick),
357  m_readInput(other.m_readInput),
358  m_writeOutput(other.m_writeOutput),
359  m_processingFunctor(other.m_processingFunctor) {
360  }
361 
362 
366  virtual ~ProcessCubeInPlaceFunctor() {
367  m_cube = NULL;
368  m_templateBrick = NULL;
369  }
370 
371 
378  void *operator()(const int &brickPosition) const {
379  Brick cubeData(*m_templateBrick);
380  cubeData.setpos(brickPosition);
381 
382  if (m_readInput)
383  m_cube->read(cubeData);
384 
385  m_processingFunctor(cubeData);
386 
387  if (m_writeOutput)
388  m_cube->write(cubeData);
389 
390  return NULL;
391  }
392 
393 
401  ProcessCubeInPlaceFunctor &operator=(
402  const ProcessCubeInPlaceFunctor &rhs) {
403  m_cube = rhs.m_cube;
404  m_templateBrick = rhs.m_templateBrick;
405 
406  m_readInput = rhs.m_readInput;
407  m_writeOutput = rhs.m_writeOutput;
408 
409  m_processingFunctor = rhs.m_processingFunctor;
410 
411  return *this;
412  }
413 
414  private:
416  Cube *m_cube;
418  const Brick *m_templateBrick;
420  bool m_readInput;
422  bool m_writeOutput;
423 
425  const T &m_processingFunctor;
426  };
427 
428 
442  template <typename T>
443  class ProcessCubeFunctor :
444  public std::unary_function<const int &, void *> {
445  public:
461  ProcessCubeFunctor(Cube *inputCube,
462  const Brick *inputTemplateBrick,
463  Cube *outputCube,
464  const Brick *outputTemplateBrick,
465  const T &processingFunctor) :
466  m_inputCube(inputCube),
467  m_inputTemplateBrick(inputTemplateBrick),
468  m_outputCube(outputCube),
469  m_outputTemplateBrick(outputTemplateBrick),
470  m_processingFunctor(processingFunctor) {
471  }
472 
473 
479  ProcessCubeFunctor(const ProcessCubeFunctor &other) :
480  m_inputCube(other.m_inputCube),
481  m_inputTemplateBrick(other.m_inputTemplateBrick),
482  m_outputCube(other.m_outputCube),
483  m_outputTemplateBrick(other.m_outputTemplateBrick),
484  m_processingFunctor(other.m_processingFunctor) {
485  }
486 
487 
491  virtual ~ProcessCubeFunctor() {
492  m_inputTemplateBrick = NULL;
493  m_outputTemplateBrick = NULL;
494  }
495 
496 
503  void *operator()(const int &brickPosition) const {
504  Brick inputCubeData(*m_inputTemplateBrick);
505  Brick outputCubeData(*m_outputTemplateBrick);
506 
507  inputCubeData.setpos(brickPosition);
508  outputCubeData.setpos(brickPosition);
509 
510  m_inputCube->read(inputCubeData);
511 
512  m_processingFunctor(inputCubeData, outputCubeData);
513 
514  m_outputCube->write(outputCubeData);
515 
516  return NULL;
517  }
518 
519 
527  ProcessCubeFunctor &operator=(const ProcessCubeFunctor &rhs) {
528  m_inputCube = rhs.m_inputCube;
529  m_inputTemplateBrick = rhs.m_inputTemplateBrick;
530 
531  m_outputCube = rhs.m_outputCube;
532  m_outputTemplateBrick = rhs.m_outputTemplateBrick;
533 
534  m_processingFunctor = rhs.m_processingFunctor;
535 
536  return *this;
537  }
538 
539  private:
541  Cube *m_inputCube;
543  const Brick *m_inputTemplateBrick;
544 
546  Cube *m_outputCube;
548  const Brick *m_outputTemplateBrick;
549 
551  const T &m_processingFunctor;
552  };
553 
554 
569  template <typename T>
570  class ProcessCubesFunctor :
571  public std::unary_function<const int &, void *> {
572  public:
592  ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
593  std::vector<Brick *> &inputTemplateBricks,
594  std::vector<Cube *> &outputCubes,
595  std::vector<Brick *> &outputTemplateBricks,
596  bool wraps,
597  const T &processingFunctor) :
598  m_inputCubes(inputCubes),
599  m_inputTemplateBricks(inputTemplateBricks),
600  m_outputCubes(outputCubes),
601  m_outputTemplateBricks(outputTemplateBricks),
602  m_wraps(wraps),
603  m_processingFunctor(processingFunctor) {
604  }
605 
606 
612  ProcessCubesFunctor(const ProcessCubesFunctor &other) :
613  m_inputCubes(other.m_inputCubes),
614  m_inputTemplateBricks(other.m_inputTemplateBricks),
615  m_outputCubes(other.m_outputCubes),
616  m_outputTemplateBricks(other.m_outputTemplateBricks),
617  m_wraps(other.m_wraps),
618  m_processingFunctor(other.m_processingFunctor) {
619  }
620 
621 
625  virtual ~ProcessCubesFunctor() {
626  }
627 
628 
635  void *operator()(const int &brickPosition) const {
636  QPair< std::vector<Buffer *>, std::vector<Buffer *> > functorBricks;
637 
638  for (int i = 0; i < (int)m_inputTemplateBricks.size(); i++) {
639  Brick *inputBrick = new Brick(*m_inputTemplateBricks[i]);
640  functorBricks.first.push_back(inputBrick);
641 
642  if (m_wraps) {
643  inputBrick->setpos(brickPosition % inputBrick->Bricks());
644  }
645  else {
646  inputBrick->setpos(brickPosition);
647  }
648 
649  if (i != 0 &&
650  functorBricks.first.size() &&
651  inputBrick->Band() != functorBricks.first[0]->Band() &&
652  m_inputCubes[i]->bandCount() != 1) {
653  inputBrick->SetBaseBand(functorBricks.first[0]->Band());
654  }
655 
656  m_inputCubes[i]->read(*inputBrick);
657  }
658 
659  for (int i = 0; i < (int)m_outputTemplateBricks.size(); i++) {
660  Brick *outputBrick = new Brick(*m_outputTemplateBricks[i]);
661  functorBricks.second.push_back(outputBrick);
662  outputBrick->setpos(brickPosition);
663  }
664 
665  // Pass them to the application function
666  m_processingFunctor(functorBricks.first, functorBricks.second);
667 
668  // And copy them into the output cubes
669  for (int i = 0; i < (int)functorBricks.second.size(); i++) {
670  m_outputCubes[i]->write(*functorBricks.second[i]);
671  delete functorBricks.second[i];
672  }
673 
674  for (int i = 0; i < (int)functorBricks.first.size(); i++) {
675  delete functorBricks.first[i];
676  }
677 
678  return NULL;
679  }
680 
681 
689  ProcessCubesFunctor &operator=(const ProcessCubesFunctor &rhs) {
690  m_inputCubes = rhs.m_inputCubes;
691  m_inputTemplateBricks = rhs.m_inputTemplateBricks;
692 
693  m_outputCubes = rhs.m_outputCubes;
694  m_outputTemplateBricks = rhs.m_outputTemplateBricks;
695 
696  m_wraps = rhs.m_wraps;
697 
698  m_processingFunctor = rhs.m_processingFunctor;
699 
700  return *this;
701  }
702 
703  private:
705  std::vector<Cube *> m_inputCubes;
710  std::vector<Brick *> &m_inputTemplateBricks;
711 
713  std::vector<Cube *> m_outputCubes;
718  std::vector<Brick *> &m_outputTemplateBricks;
719 
721  bool m_wraps;
722 
724  const T &m_processingFunctor;
725  };
726 
727 
728  void BlockingReportProgress(QFuture<void> &future);
729  std::vector<int> CalculateMaxDimensions(std::vector<Cube *> cubes) const;
730  bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks);
731  int PrepProcessCube(Brick **ibrick, Brick **obrick);
732  int PrepProcessCubes(std::vector<Buffer *> & ibufs,
733  std::vector<Buffer *> & obufs,
734  std::vector<Brick *> & imgrs,
735  std::vector<Brick *> & omgrs);
736 
737 
747  class ProcessIterator : public std::iterator<
748  std::forward_iterator_tag, int> {
749  public:
750  ProcessIterator(int position);
751  ProcessIterator(const ProcessIterator &other);
752  virtual ~ProcessIterator();
753 
754  ProcessIterator &operator++();
755 
762  bool operator==(const ProcessIterator &rhs) {
763  return (m_currentPosition == rhs.m_currentPosition);
764  }
765 
772  bool operator!=(const ProcessIterator &rhs) {
773  return !(*this == rhs);
774  }
775 
776 
782  void swap(ProcessIterator &other) {
783  std::swap(m_currentPosition, other.m_currentPosition);
784  }
785 
786 
793  ProcessIterator &operator=(const ProcessIterator &rhs) {
794  ProcessIterator copy(rhs);
795  swap(copy);
796  return *this;
797  }
798 
799 
804  int operator*() const {
805  return m_currentPosition;
806  }
807 
808  private:
810  int m_currentPosition;
811  };
812 
813  private:
814  bool p_reverse;
817  bool p_wrapOption;
818  bool p_inputBrickSizeSet;
820  bool p_outputBrickSizeSet;
823  int p_outputRequirements;
824 
825 
826  std::vector<int> p_inputBrickSamples;
828  std::vector<int> p_inputBrickLines;
830  std::vector<int> p_inputBrickBands;
832  std::vector<int> p_outputBrickSamples;
834  std::vector<int> p_outputBrickLines;
836  std::vector<int> p_outputBrickBands;
842  };
843 
844 };
845 
846 #endif
Isis::Process::InputCubes
std::vector< Isis::Cube * > InputCubes
A vector of pointers to opened Cube objects.
Definition: Process.h:185
Cube.h
Isis::ProcessByBrick::SetInputBrickSize
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
Definition: ProcessByBrick.cpp:241
Isis::ProcessByBrick::LinesFirst
@ LinesFirst
Definition: ProcessByBrick.h:94
Isis::Progress::CheckStatus
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:105
Isis::ProcessByBrick::VerifyCubes
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
Definition: ProcessByBrick.cpp:120
Isis::operator*
Angle operator*(double mult, Angle angle)
Multiply this angle by a double and return the resulting angle.
Definition: Angle.cpp:170
Isis::Cube::read
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:807
Process.h
Isis::Progress::SetMaximumSteps
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:85
Isis::Process::OutputCubes
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition: Process.h:191
Isis::Process
Base class for all cube processing derivatives.
Definition: Process.h:143
Isis::ProcessByBrick::SetOutputCube
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
Definition: ProcessByBrick.cpp:364
Isis::ProcessByBrick::SetInputCube
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:136
Isis::CubeAttributeOutput
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
Isis::ProcessByBrick::~ProcessByBrick
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
Definition: ProcessByBrick.cpp:35
Isis::Process::StartProcess
virtual void StartProcess(void funct())
In the base class, this method will invoked a user-specified function exactly one time.
Definition: Process.h:213
Isis::Brick
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:45
Isis::BufferManager::begin
bool begin()
Moves the shape buffer to the first position.
Definition: BufferManager.h:96
Isis::ProcessByBrick::ProcessCubeInPlace
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
Definition: ProcessByBrick.h:163
Isis::ProcessByBrick::SetOutputBrickSize
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
Definition: ProcessByBrick.cpp:300
Isis::Brick::Bricks
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:168
Isis::ProcessByBrick::SetBrickSize
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:225
Isis::Buffer
Buffer for reading and writing cube data.
Definition: Buffer.h:53
Isis::BufferManager::end
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
Definition: BufferManager.h:115
Isis::ProcessByBrick::ProcessingDirection
ProcessingDirection
Definition: ProcessByBrick.h:93
Isis::ProcessByBrick::IOCubes
IOCubes
Definition: ProcessByBrick.h:89
ProcessByBrick.h
Isis::ProcessByBrick::SetWrap
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
Definition: ProcessByBrick.cpp:409
Buffer.h
Isis::ProcessByBrick::ProcessCube
void ProcessCube(const Functor &functor, bool threaded=true)
Operate over a single input cube creating a separate output cube.
Definition: ProcessByBrick.h:200
Isis::Cube::lineCount
int lineCount() const
Definition: Cube.cpp:1734
Isis::ProcessByBrick::SetOutputRequirements
void SetOutputRequirements(int outputRequirements)
Definition: ProcessByBrick.cpp:95
_FILEINFO_
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:24
Isis::Cube::isReadWrite
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:235
Isis::ProcessByBrick
Process cubes by brick.
Definition: ProcessByBrick.h:81
Isis::Process::SetInputCube
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:136
Isis::ProcessByBrick::ProcessCubes
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:239
Isis::ProcessByBrick::InPlace
@ InPlace
Definition: ProcessByBrick.h:89
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::ProcessByBrick::StartProcess
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:437
Isis::ProcessByBrick::ProcessByBrick
ProcessByBrick()
Constructs a ProcessByBrick object.
Definition: ProcessByBrick.cpp:16
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::SpatialMatch
const int SpatialMatch
Definition: Process.h:21
Isis::ProcessByBrick::InputOutputList
@ InputOutputList
Definition: ProcessByBrick.h:91
Isis::Process::SetOutputCube
virtual Isis::Cube * SetOutputCube(const QString &parameter)
Allocates a user-specified output cube whose size matches the first input cube.
Definition: Process.cpp:160
Isis::ProcessByBrick::BandsFirst
@ BandsFirst
Definition: ProcessByBrick.h:95
Brick.h
Isis::ProcessByBrick::Wraps
bool Wraps()
Returns true if the wrapping option is enabled.
Definition: ProcessByBrick.cpp:419
std
Namespace for the standard library.
Isis::ProcessByBrick::Finalize
void Finalize()
Cleans up by closing cubes and freeing memory.
Definition: ProcessByBrick.cpp:679
QPair
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:23
Isis::ProcessByBrick::SetBricks
virtual void SetBricks(IOCubes cn)
Definition: ProcessByBrick.cpp:102
Isis::Cube::write
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition: Cube.cpp:971
Isis::ProcessByBrick::SetProcessingDirection
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:380
Isis::CubeAttributeInput
Manipulate and parse attributes of input cube filenames.
Definition: CubeAttribute.h:381
Isis::Process::p_progress
Isis::Progress * p_progress
Pointer to a Progress object.
Definition: Process.h:145
Isis::ProcessByBrick::EndProcess
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
Definition: ProcessByBrick.cpp:669
Isis::ProcessByBrick::GetProcessingDirection
ProcessingDirection GetProcessingDirection()
Returns the direction the data will be read, either all lines in a single band proceeding to the next...
Definition: ProcessByBrick.cpp:393
Progress.h
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::ProcessByBrick::InputOutput
@ InputOutput
Definition: ProcessByBrick.h:90
Isis::AllMatchOrOne
const int AllMatchOrOne
Definition: Process.h:25