Isis 3.0 Programmer Reference
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 
102  enum IOCubes{InPlace,
103  InputOutput,
104  InputOutputList};
105 
106  enum ProcessingDirection {
107  LinesFirst,
108  BandsFirst
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 
138  void SetProcessingDirection(ProcessingDirection direction);
139  ProcessingDirection GetProcessingDirection();
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>
331  public std::unary_function<const int &, void *> {
332  public:
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 
366  m_cube(other.m_cube),
368  m_readInput(other.m_readInput),
371  }
372 
373 
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 
413  const ProcessCubeInPlaceFunctor &rhs) {
414  m_cube = rhs.m_cube;
416 
417  m_readInput = rhs.m_readInput;
419 
421 
422  return *this;
423  }
424 
425  private:
434 
437  };
438 
439 
453  template <typename T>
455  public std::unary_function<const int &, void *> {
456  public:
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 
491  m_inputCube(other.m_inputCube),
493  m_outputCube(other.m_outputCube),
496  }
497 
498 
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 
539  m_inputCube = rhs.m_inputCube;
541 
544 
546 
547  return *this;
548  }
549 
550  private:
555 
560 
563  };
564 
565 
580  template <typename T>
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 
624  m_inputCubes(other.m_inputCubes),
628  m_wraps(other.m_wraps),
630  }
631 
632 
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 
703 
706 
707  m_wraps = rhs.m_wraps;
708 
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 
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 
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 
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:
822  };
823 
824  private:
825  bool p_reverse;
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.
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
This class is designed to iterate over all brick positions in a cube.
std::vector< Brick * > & m_outputTemplateBricks
Template bricks for writing output data.
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.
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
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:205
int operator*() const
Convert this iterator into a position.
int PrepProcessCube(Brick **ibrick, Brick **obrick)
Prepare and check to run &quot;function&quot; parameter for StartProcess(void funct(Buffer &amp;in, Buffer &amp;out)) and StartProcessIO(Functor funct)
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
int PrepProcessCubes(std::vector< Buffer * > &ibufs, std::vector< Buffer * > &obufs, std::vector< Brick * > &imgrs, std::vector< Brick * > &omgrs)
Prepare and check to run &quot;function&quot; parameter for StartProcess(void funct(vector&lt;Buffer *&gt; &amp;in...
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:60
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...
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 read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:686
Cube * SetInputCube(const QString &parameter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
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:227
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).
void SetBaseBand(const int start_band)
This method is used to set the base band position of the shape buffer.
Definition: Brick.h:140
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
Definition: Buffer.cpp:178
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:160
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.
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.
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
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:159
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:725
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.
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...
bool p_outputBrickSizeSet
Indicates whether the brick size has been set.
bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks)
Prepare and check to run &quot;function&quot; parameter for StartProcess(void funct(Buffer &amp;in)) and StartProce...
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:157
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:199
IO Handler for Isis Cubes.
Definition: Cube.h:158