1 #ifndef ProcessByBrick_h
2 #define ProcessByBrick_h
26 #include <QtConcurrentMap>
113 int requirements = 0);
117 int requirements = 0);
148 virtual void StartProcess(
void funct(std::vector<Buffer *> &in,
149 std::vector<Buffer *> &out));
175 const Functor & functor,
bool threaded =
true) {
179 bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
180 bool writeOutput = (!haveInput) || (cube->
isReadWrite());
182 ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
183 cube, brick, haveInput, writeOutput, functor);
185 RunProcess(wrapperFunctor, brick->
Bricks(), threaded);
211 template <
typename Functor>
void ProcessCube(
const Functor & functor,
212 bool threaded =
true) {
213 Brick *inputCubeData = NULL;
214 Brick *outputCubeData = NULL;
216 int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
218 ProcessCubeFunctor<Functor> wrapperFunctor(
InputCubes[0], inputCubeData,
221 RunProcess(wrapperFunctor, numBricks, threaded);
223 delete inputCubeData;
224 delete outputCubeData;
251 bool threaded =
true) {
252 std::vector<Brick *> inputCubeData;
253 std::vector<Brick *> outputCubeData;
255 std::vector<Buffer *> inputCubeDataParents;
256 std::vector<Buffer *> outputCubeDataParents;
258 int numBricks = PrepProcessCubes(
259 inputCubeDataParents, outputCubeDataParents,
260 inputCubeData, outputCubeData);
262 ProcessCubesFunctor<Functor> wrapperFunctor(
InputCubes, inputCubeData,
265 RunProcess(wrapperFunctor, numBricks, threaded);
267 for(
unsigned int i = 0; i < inputCubeData.size(); i++) {
268 delete inputCubeData[i];
271 for(
unsigned int i = 0; i < outputCubeData.size(); i++) {
272 delete outputCubeData[i];
290 template <
typename Functor>
291 void RunProcess(
const Functor &wrapperFunctor,
292 int numSteps,
bool threaded) {
293 ProcessIterator begin(0);
294 ProcessIterator end(numSteps);
299 int threadCount = QThreadPool::globalInstance()->maxThreadCount();
300 if (threaded && threadCount > 1) {
301 QFuture<void> result = QtConcurrent::mapped(begin, end,
303 BlockingReportProgress(result);
306 while (begin != end) {
307 wrapperFunctor(*begin);
329 template <
typename T>
330 class ProcessCubeInPlaceFunctor :
331 public std::unary_function<const int &, void *> {
348 ProcessCubeInPlaceFunctor(Cube *cube,
349 const Brick *templateBrick,
350 bool readInput,
bool writeOutput,
351 const T &processingFunctor) :
353 m_templateBrick(templateBrick),
354 m_readInput(readInput),
355 m_writeOutput(writeOutput),
356 m_processingFunctor(processingFunctor) {
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) {
377 virtual ~ProcessCubeInPlaceFunctor() {
379 m_templateBrick = NULL;
389 void *operator()(
const int &brickPosition)
const {
390 Brick cubeData(*m_templateBrick);
391 cubeData.setpos(brickPosition);
394 m_cube->read(cubeData);
396 m_processingFunctor(cubeData);
399 m_cube->write(cubeData);
412 ProcessCubeInPlaceFunctor &operator=(
413 const ProcessCubeInPlaceFunctor &rhs) {
415 m_templateBrick = rhs.m_templateBrick;
417 m_readInput = rhs.m_readInput;
418 m_writeOutput = rhs.m_writeOutput;
420 m_processingFunctor = rhs.m_processingFunctor;
429 const Brick *m_templateBrick;
436 const T &m_processingFunctor;
453 template <
typename T>
454 class ProcessCubeFunctor :
455 public std::unary_function<const int &, void *> {
472 ProcessCubeFunctor(Cube *inputCube,
473 const Brick *inputTemplateBrick,
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) {
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) {
502 virtual ~ProcessCubeFunctor() {
503 m_inputTemplateBrick = NULL;
504 m_outputTemplateBrick = NULL;
514 void *operator()(
const int &brickPosition)
const {
515 Brick inputCubeData(*m_inputTemplateBrick);
516 Brick outputCubeData(*m_outputTemplateBrick);
518 inputCubeData.setpos(brickPosition);
519 outputCubeData.setpos(brickPosition);
521 m_inputCube->read(inputCubeData);
523 m_processingFunctor(inputCubeData, outputCubeData);
525 m_outputCube->write(outputCubeData);
538 ProcessCubeFunctor &operator=(
const ProcessCubeFunctor &rhs) {
539 m_inputCube = rhs.m_inputCube;
540 m_inputTemplateBrick = rhs.m_inputTemplateBrick;
542 m_outputCube = rhs.m_outputCube;
543 m_outputTemplateBrick = rhs.m_outputTemplateBrick;
545 m_processingFunctor = rhs.m_processingFunctor;
554 const Brick *m_inputTemplateBrick;
559 const Brick *m_outputTemplateBrick;
562 const T &m_processingFunctor;
580 template <
typename T>
581 class ProcessCubesFunctor :
582 public std::unary_function<const int &, void *> {
603 ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
604 std::vector<Brick *> &inputTemplateBricks,
605 std::vector<Cube *> &outputCubes,
606 std::vector<Brick *> &outputTemplateBricks,
608 const T &processingFunctor) :
609 m_inputCubes(inputCubes),
610 m_inputTemplateBricks(inputTemplateBricks),
611 m_outputCubes(outputCubes),
612 m_outputTemplateBricks(outputTemplateBricks),
614 m_processingFunctor(processingFunctor) {
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) {
636 virtual ~ProcessCubesFunctor() {
646 void *operator()(
const int &brickPosition)
const {
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);
654 inputBrick->setpos(brickPosition % inputBrick->Bricks());
657 inputBrick->setpos(brickPosition);
661 functorBricks.first.size() &&
662 inputBrick->Band() != functorBricks.first[0]->Band() &&
663 m_inputCubes[i]->bandCount() != 1) {
664 inputBrick->SetBaseBand(functorBricks.first[0]->Band());
667 m_inputCubes[i]->read(*inputBrick);
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);
677 m_processingFunctor(functorBricks.first, functorBricks.second);
680 for (
int i = 0; i < (int)functorBricks.second.size(); i++) {
681 m_outputCubes[i]->write(*functorBricks.second[i]);
682 delete functorBricks.second[i];
685 for (
int i = 0; i < (int)functorBricks.first.size(); i++) {
686 delete functorBricks.first[i];
700 ProcessCubesFunctor &operator=(
const ProcessCubesFunctor &rhs) {
701 m_inputCubes = rhs.m_inputCubes;
702 m_inputTemplateBricks = rhs.m_inputTemplateBricks;
704 m_outputCubes = rhs.m_outputCubes;
705 m_outputTemplateBricks = rhs.m_outputTemplateBricks;
707 m_wraps = rhs.m_wraps;
709 m_processingFunctor = rhs.m_processingFunctor;
716 std::vector<Cube *> m_inputCubes;
721 std::vector<Brick *> &m_inputTemplateBricks;
724 std::vector<Cube *> m_outputCubes;
729 std::vector<Brick *> &m_outputTemplateBricks;
735 const T &m_processingFunctor;
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);
758 class ProcessIterator :
public std::iterator<
759 std::forward_iterator_tag, int> {
761 ProcessIterator(
int position);
762 ProcessIterator(
const ProcessIterator &other);
763 virtual ~ProcessIterator();
765 ProcessIterator &operator++();
773 bool operator==(
const ProcessIterator &rhs) {
774 return (m_currentPosition == rhs.m_currentPosition);
783 bool operator!=(
const ProcessIterator &rhs) {
784 return !(*
this == rhs);
793 void swap(ProcessIterator &other) {
794 std::swap(m_currentPosition, other.m_currentPosition);
804 ProcessIterator &operator=(
const ProcessIterator &rhs) {
805 ProcessIterator copy(rhs);
816 return m_currentPosition;
821 int m_currentPosition;
829 bool p_inputBrickSizeSet;
831 bool p_outputBrickSizeSet;
834 int p_outputRequirements;
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;
Buffer for reading and writing cube data.
Definition: Buffer.h:68
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 ¶meter, 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 ¶meter, 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 ¶meter)
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