Isis 3 Programmer Reference
ProcessByBrick.h
1#ifndef ProcessByBrick_h
2#define ProcessByBrick_h
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
19namespace Isis {
83 class ProcessByBrick : public Process {
84 public:
87
89 virtual ~ProcessByBrick();
90
91 enum IOCubes{InPlace,
92 InputOutput,
93 InputOutputList};
94
95 enum ProcessingDirection {
96 LinesFirst,
97 BandsFirst
98 };
99
101 Cube *SetInputCube(const QString &parameter,
102 int requirements = 0);
103
104 Cube *SetInputCube(const QString &fname,
105 const CubeAttributeInput &att,
106 int requirements = 0);
107
108 virtual void SetBricks(IOCubes cn);
109 void VerifyCubes(IOCubes cn);
110
111 void SetBrickSize(int ns, int nl, int nb);
112
113 void SetInputBrickSize(int ns, int nl, int nb);
114 void SetInputBrickSize(int ns, int nl, int nb, int cube);
115
116 void SetOutputBrickSize(int ns, int nl, int nb);
117 void SetOutputBrickSize(int ns, int nl, int nb, int cube);
118
119 // Overload the SetOutputCube() method to allow the user to pass in the
120 // file name and attributes without the lines and samples.
121 // Any other calls to this method will use the prototypes found in the
122 //process class due to the using statement below.
124 virtual Cube *SetOutputCube(const QString &fname,
125 const CubeAttributeOutput &att);
126
127 void SetProcessingDirection(ProcessingDirection direction);
128 ProcessingDirection GetProcessingDirection();
129
130 void SetOutputRequirements(int outputRequirements);
131 void SetWrap(bool wrap);
132 bool Wraps();
133
134 using Isis::Process::StartProcess; // make parents virtual function visable
135 virtual void StartProcess(void funct(Buffer &in));
136 virtual void StartProcess(std::function<void(Buffer &in)> funct );
137 virtual void StartProcess(void funct(Buffer &in, Buffer &out));
138 virtual void StartProcess(std::function<void(Buffer &in, Buffer &out)> funct);
139 virtual void StartProcess(void funct(std::vector<Buffer *> &in,
140 std::vector<Buffer *> &out));
141 virtual void StartProcess(std::function<void(std::vector<Buffer *> &in,
142 std::vector<Buffer *> &out)> funct);
143 void EndProcess();// Depricated. Please use Finalize
144 void Finalize();
145
146
167 template <typename Functor> void ProcessCubeInPlace(
168 const Functor & functor, bool threaded = true) {
169 Cube *cube = NULL;
170 Brick *brick = NULL;
171
172 bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
173 bool writeOutput = (!haveInput) || (cube->isReadWrite());
174
175 ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
176 cube, brick, haveInput, writeOutput, functor);
177
178 RunProcess(wrapperFunctor, brick->Bricks(), threaded);
179
180 delete brick;
181 }
182
183
204 template <typename Functor> void ProcessCube(const Functor & functor,
205 bool threaded = true) {
206 Brick *inputCubeData = NULL;
207 Brick *outputCubeData = NULL;
208
209 int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
210
211 ProcessCubeFunctor<Functor> wrapperFunctor(InputCubes[0], inputCubeData,
212 OutputCubes[0], outputCubeData, functor);
213
214 RunProcess(wrapperFunctor, numBricks, threaded);
215
216 delete inputCubeData;
217 delete outputCubeData;
218 }
219
220
243 template <typename Functor> void ProcessCubes(const Functor & functor,
244 bool threaded = true) {
245 std::vector<Brick *> inputCubeData;
246 std::vector<Brick *> outputCubeData;
247
248 std::vector<Buffer *> inputCubeDataParents;
249 std::vector<Buffer *> outputCubeDataParents;
250
251 int numBricks = PrepProcessCubes(
252 inputCubeDataParents, outputCubeDataParents,
253 inputCubeData, outputCubeData);
254
255 ProcessCubesFunctor<Functor> wrapperFunctor(InputCubes, inputCubeData,
256 OutputCubes, outputCubeData, Wraps(), functor);
257
258 RunProcess(wrapperFunctor, numBricks, threaded);
259
260 for(unsigned int i = 0; i < inputCubeData.size(); i++) {
261 delete inputCubeData[i];
262 }
263
264 for(unsigned int i = 0; i < outputCubeData.size(); i++) {
265 delete outputCubeData[i];
266 }
267 }
268
269
270 private:
283 template <typename Functor>
284 void RunProcess(const Functor &wrapperFunctor,
285 int numSteps, bool threaded) {
286 ProcessIterator begin(0);
287 ProcessIterator end(numSteps);
288
289 p_progress->SetMaximumSteps(numSteps);
291
292 int threadCount = QThreadPool::globalInstance()->maxThreadCount();
293 if (threaded && threadCount > 1) {
294 QFuture<void> result = QtConcurrent::mapped(begin, end,
295 wrapperFunctor);
297 }
298 else {
299 while (begin != end) {
300 wrapperFunctor(*begin);
301 ++begin;
303 }
304 }
305 }
306
307
322 template <typename T>
324 public std::function<void*(int)> {
325 public:
342 const Brick *templateBrick,
343 bool readInput, bool writeOutput,
344 const T &processingFunctor) :
345 m_cube(cube),
346 m_templateBrick(templateBrick),
347 m_readInput(readInput),
348 m_writeOutput(writeOutput),
349 m_processingFunctor(processingFunctor) {
350 }
351
352
365
366
371 m_cube = NULL;
372 m_templateBrick = NULL;
373 }
374
375
382 void *operator()(const int &brickPosition) const {
383 Brick cubeData(*m_templateBrick);
384 cubeData.setpos(brickPosition);
385
386 if (m_readInput)
387 m_cube->read(cubeData);
388
389 m_processingFunctor(cubeData);
390
391 if (m_writeOutput)
392 m_cube->write(cubeData);
393
394 return NULL;
395 }
396
397
406 const ProcessCubeInPlaceFunctor &rhs) {
407 m_cube = rhs.m_cube;
408 m_templateBrick = rhs.m_templateBrick;
409
410 m_readInput = rhs.m_readInput;
411 m_writeOutput = rhs.m_writeOutput;
412
413 m_processingFunctor = rhs.m_processingFunctor;
414
415 return *this;
416 }
417
418 private:
427
430 };
431
432
446 template <typename T>
448 public std::function<void *(const int &)> {
449 public:
466 const Brick *inputTemplateBrick,
467 Cube *outputCube,
468 const Brick *outputTemplateBrick,
469 const T &processingFunctor) :
470 m_inputCube(inputCube),
471 m_inputTemplateBrick(inputTemplateBrick),
472 m_outputCube(outputCube),
473 m_outputTemplateBrick(outputTemplateBrick),
474 m_processingFunctor(processingFunctor) {
475 }
476
477
490
491
498 }
499
500
507 void *operator()(const int &brickPosition) const {
508 Brick inputCubeData(*m_inputTemplateBrick);
509 Brick outputCubeData(*m_outputTemplateBrick);
510
511 inputCubeData.setpos(brickPosition);
512 outputCubeData.setpos(brickPosition);
513
514 m_inputCube->read(inputCubeData);
515
516 m_processingFunctor(inputCubeData, outputCubeData);
517
518 m_outputCube->write(outputCubeData);
519
520 return NULL;
521 }
522
523
532 m_inputCube = rhs.m_inputCube;
533 m_inputTemplateBrick = rhs.m_inputTemplateBrick;
534
535 m_outputCube = rhs.m_outputCube;
536 m_outputTemplateBrick = rhs.m_outputTemplateBrick;
537
538 m_processingFunctor = rhs.m_processingFunctor;
539
540 return *this;
541 }
542
543 private:
548
553
556 };
557
558
573 template <typename T>
575 public std::function<void *(const int &)> {
576 public:
596 ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
597 std::vector<Brick *> &inputTemplateBricks,
598 std::vector<Cube *> &outputCubes,
599 std::vector<Brick *> &outputTemplateBricks,
600 bool wraps,
601 const T &processingFunctor) :
602 m_inputCubes(inputCubes),
603 m_inputTemplateBricks(inputTemplateBricks),
604 m_outputCubes(outputCubes),
605 m_outputTemplateBricks(outputTemplateBricks),
606 m_wraps(wraps),
607 m_processingFunctor(processingFunctor) {
608 }
609
610
624
625
630 }
631
632
639 void *operator()(const int &brickPosition) const {
640 QPair< std::vector<Buffer *>, std::vector<Buffer *> > functorBricks;
641
642 for (int i = 0; i < (int)m_inputTemplateBricks.size(); i++) {
643 Brick *inputBrick = new Brick(*m_inputTemplateBricks[i]);
644 functorBricks.first.push_back(inputBrick);
645
646 if (m_wraps) {
647 inputBrick->setpos(brickPosition % inputBrick->Bricks());
648 }
649 else {
650 inputBrick->setpos(brickPosition);
651 }
652
653 if (i != 0 &&
654 functorBricks.first.size() &&
655 inputBrick->Band() != functorBricks.first[0]->Band() &&
656 m_inputCubes[i]->bandCount() != 1) {
657 inputBrick->SetBaseBand(functorBricks.first[0]->Band());
658 }
659
660 m_inputCubes[i]->read(*inputBrick);
661 }
662
663 for (int i = 0; i < (int)m_outputTemplateBricks.size(); i++) {
664 Brick *outputBrick = new Brick(*m_outputTemplateBricks[i]);
665 functorBricks.second.push_back(outputBrick);
666 outputBrick->setpos(brickPosition);
667 }
668
669 // Pass them to the application function
670 m_processingFunctor(functorBricks.first, functorBricks.second);
671
672 // And copy them into the output cubes
673 for (int i = 0; i < (int)functorBricks.second.size(); i++) {
674 m_outputCubes[i]->write(*functorBricks.second[i]);
675 delete functorBricks.second[i];
676 }
677
678 for (int i = 0; i < (int)functorBricks.first.size(); i++) {
679 delete functorBricks.first[i];
680 }
681
682 return NULL;
683 }
684
685
695 m_inputTemplateBricks = rhs.m_inputTemplateBricks;
696
697 m_outputCubes = rhs.m_outputCubes;
698 m_outputTemplateBricks = rhs.m_outputTemplateBricks;
699
700 m_wraps = rhs.m_wraps;
701
702 m_processingFunctor = rhs.m_processingFunctor;
703
704 return *this;
705 }
706
707 private:
709 std::vector<Cube *> m_inputCubes;
714 std::vector<Brick *> &m_inputTemplateBricks;
715
717 std::vector<Cube *> m_outputCubes;
722 std::vector<Brick *> &m_outputTemplateBricks;
723
726
729 };
730
731
732 void BlockingReportProgress(QFuture<void> &future);
733 std::vector<int> CalculateMaxDimensions(std::vector<Cube *> cubes) const;
734 bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks);
735 int PrepProcessCube(Brick **ibrick, Brick **obrick);
736 int PrepProcessCubes(std::vector<Buffer *> & ibufs,
737 std::vector<Buffer *> & obufs,
738 std::vector<Brick *> & imgrs,
739 std::vector<Brick *> & omgrs);
740
741
751 class ProcessIterator : public std::iterator<
752 std::forward_iterator_tag, int> {
753 public:
754 ProcessIterator(int position);
755 ProcessIterator(const ProcessIterator &other);
756 virtual ~ProcessIterator();
757
759
766 bool operator==(const ProcessIterator &rhs) {
767 return (m_currentPosition == rhs.m_currentPosition);
768 }
769
776 bool operator!=(const ProcessIterator &rhs) {
777 return !(*this == rhs);
778 }
779
780
786 void swap(ProcessIterator &other) {
787 std::swap(m_currentPosition, other.m_currentPosition);
788 }
789
790
798 ProcessIterator copy(rhs);
799 swap(copy);
800 return *this;
801 }
802
803
808 int operator*() const {
809 return m_currentPosition;
810 }
811
812 private:
815 };
816
817 private:
827 int p_outputRequirements;
828
829
830 std::vector<int> p_inputBrickSamples;
832 std::vector<int> p_inputBrickLines;
834 std::vector<int> p_inputBrickBands;
836 std::vector<int> p_outputBrickSamples;
838 std::vector<int> p_outputBrickLines;
840 std::vector<int> p_outputBrickBands;
846 };
847
848};
849
850#endif
Buffer for containing a three dimensional section of an image.
Definition Brick.h:45
Buffer for reading and writing cube data.
Definition Buffer.h:53
Manipulate and parse attributes of input cube filenames.
Manipulate and parse attributes of output cube filenames.
IO Handler for Isis Cubes.
Definition Cube.h:168
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:813
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition Cube.cpp:977
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:230
Create an output cube given one input cube.
Cube * m_inputCube
The cube to read from for the input brick data.
Cube * m_outputCube
The cube to write to with the output of m_processingFunctor.
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
ProcessCubeFunctor & operator=(const ProcessCubeFunctor &rhs)
Assignment of these objects is fully supported.
ProcessCubeFunctor(const ProcessCubeFunctor &other)
Copy construction of these objects is fully supported.
ProcessCubeFunctor(Cube *inputCube, const Brick *inputTemplateBrick, Cube *outputCube, const Brick *outputTemplateBrick, const T &processingFunctor)
Construct a ProcessCubeFunctor.
const Brick * m_inputTemplateBrick
An example brick for the input parameter to m_processingFunctor.
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
const Brick * m_outputTemplateBrick
An example brick for the output parameter to m_processingFunctor.
Process a cube in place (one input/zero output or zero input/one output or one cube that acts both as...
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
bool m_writeOutput
Should we write to the output cube after processing.
ProcessCubeInPlaceFunctor(Cube *cube, const Brick *templateBrick, bool readInput, bool writeOutput, const T &processingFunctor)
Construct a ProcessCubeInPlaceFunctor.
bool m_readInput
Should we read from the cube before processing.
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
ProcessCubeInPlaceFunctor & operator=(const ProcessCubeInPlaceFunctor &rhs)
Assignment of these objects is fully supported.
ProcessCubeInPlaceFunctor(const ProcessCubeInPlaceFunctor &other)
Copy construction of these objects is fully supported.
Cube * m_cube
The cube we're I/O'ing on.
const Brick * m_templateBrick
A brick with the right dimensions, pixel type, etc. for processing.
Create an arbitrary number of output cubes given an arbitrary number of input cubes (these counts can...
void * operator()(const int &brickPosition) const
Do the work for one position in a cube.
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.
const T & m_processingFunctor
The functor which does the work/arbitrary calculations.
std::vector< Cube * > m_inputCubes
The input cubes for reading data from.
ProcessCubesFunctor(const ProcessCubesFunctor &other)
Copy construction of these objects is fully supported.
bool m_wraps
Wrap smaller cubes back to the beginning?
std::vector< Brick * > & m_inputTemplateBricks
Template bricks for reading input data.
ProcessCubesFunctor & operator=(const ProcessCubesFunctor &rhs)
Assignment of these objects is fully supported.
std::vector< Cube * > m_outputCubes
The output cubes for writing data to.
std::vector< Brick * > & m_outputTemplateBricks
Template bricks for writing output data.
This class is designed to iterate over all brick positions in a cube.
int operator*() const
Convert this iterator into a position.
bool operator==(const ProcessIterator &rhs)
Compare equality of two iterator positions.
ProcessIterator(int position)
Initialize a process iterator given a position.
ProcessIterator & operator=(const ProcessIterator &rhs)
Assignment of these iterators is fully supported.
int m_currentPosition
The current iterator's position/value.
void swap(ProcessIterator &other)
Exception-safe swap method.
bool operator!=(const ProcessIterator &rhs)
Compare inequality of two iterator positions.
ProcessIterator & operator++()
Increment the process iterator to the next position.
Process cubes by brick.
bool p_wrapOption
Indicates whether the brick manager will wrap.
std::vector< int > p_inputBrickBands
Number of bands in the input bricks.
void SetProcessingDirection(ProcessingDirection direction)
Set the direction the data will be read, either all lines in a single band proceeding to the next ban...
std::vector< int > p_outputBrickLines
Number of lines in the output bricks.
bool p_inputBrickSizeSet
Indicates whether the brick size has been set.
void Finalize()
Cleans up by closing cubes and freeing memory.
bool PrepProcessCubeInPlace(Cube **cube, Brick **bricks)
Prepare and check to run "function" parameter for StartProcess(void funct(Buffer &in)) and StartProce...
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
bool p_reverse
Use the reverse option for constructing the Buffer objects when the Processing Direction is changed f...
ProcessByBrick()
Constructs a ProcessByBrick object.
void ProcessCubes(const Functor &functor, bool threaded=true)
Operate over an arbitrary number of input cubes given an arbitrary number of output cubes.
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
int PrepProcessCube(Brick **ibrick, Brick **obrick)
Prepare and check to run "function" parameter for StartProcess(void funct(Buffer &in,...
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
std::vector< int > p_inputBrickSamples
Number of samples in the input bricks.
virtual void StartProcess(void funct(Buffer &in))
Starts the systematic processing of the input cube by moving an arbitrarily-shaped brick through the ...
Cube * SetInputCube(const QString &parameter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
void ProcessCube(const Functor &functor, bool threaded=true)
Operate over a single input cube creating a separate output cube.
std::vector< int > p_outputBrickBands
Number of bands in the output bricks.
void SetBrickSize(int ns, int nl, int nb)
Sets the input and output bricks sizes to the given number of samples, lines, and bands.
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
bool Wraps()
Returns true if the wrapping option is enabled.
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
std::vector< int > p_inputBrickLines
Number of lines in the input bricks.
ProcessingDirection GetProcessingDirection()
Returns the direction the data will be read, either all lines in a single band proceeding to the next...
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,...
void BlockingReportProgress(QFuture< void > &future)
This method blocks until the future reports that it is finished.
bool p_outputBrickSizeSet
Indicates whether the brick size has been set.
std::vector< int > p_outputBrickSamples
Number of samples in the output bricks.
void RunProcess(const Functor &wrapperFunctor, int numSteps, bool threaded)
This method runs the given wrapper functor numSteps times with or without threading,...
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...
Base class for all cube processing derivatives.
Definition Process.h:143
virtual void StartProcess(void funct())
In the base class, this method will invoked a user-specified function exactly one time.
Definition Process.h:213
std::vector< Isis::Cube * > InputCubes
A vector of pointers to opened Cube objects.
Definition Process.h:185
Isis::Progress * p_progress
Pointer to a Progress object.
Definition Process.h:145
virtual Isis::Cube * SetOutputCube(const QString &parameter)
Allocates a user-specified output cube whose size matches the first input cube.
Definition Process.cpp:163
std::vector< Isis::Cube * > OutputCubes
A vector of pointers to allocated Cube objects.
Definition Process.h:191
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:139
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16