1#ifndef ProcessByBrick_h 
    2#define ProcessByBrick_h 
   10#include <QtConcurrentMap> 
  102                         int requirements = 0);
 
  106                         int requirements = 0);
 
  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);
 
  168          const Functor & functor, 
bool threaded = 
true) {
 
  172        bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
 
  173        bool writeOutput = (!haveInput) || (cube->
isReadWrite());
 
  175        ProcessCubeInPlaceFunctor<Functor> wrapperFunctor(
 
  176            cube, brick, haveInput, writeOutput, functor);
 
  178        RunProcess(wrapperFunctor, brick->
Bricks(), threaded);
 
  204      template <
typename Functor> 
void ProcessCube(
const Functor & functor,
 
  205                                                   bool threaded = 
true) {
 
  206        Brick *inputCubeData = NULL;
 
  207        Brick *outputCubeData = NULL;
 
  209        int numBricks = PrepProcessCube(&inputCubeData, &outputCubeData);
 
  211        ProcessCubeFunctor<Functor> wrapperFunctor(
InputCubes[0], inputCubeData,
 
  214        RunProcess(wrapperFunctor, numBricks, threaded);
 
  216        delete inputCubeData;
 
  217        delete outputCubeData;
 
  244                                                    bool threaded = 
true) {
 
  245        std::vector<Brick *> inputCubeData;
 
  246        std::vector<Brick *> outputCubeData;
 
  248        std::vector<Buffer *> inputCubeDataParents;
 
  249        std::vector<Buffer *> outputCubeDataParents;
 
  251        int numBricks = PrepProcessCubes(
 
  252            inputCubeDataParents, outputCubeDataParents,
 
  253            inputCubeData, outputCubeData);
 
  255        ProcessCubesFunctor<Functor> wrapperFunctor(
InputCubes, inputCubeData,
 
  258        RunProcess(wrapperFunctor, numBricks, threaded);
 
  260        for(
unsigned int i = 0; i < inputCubeData.size(); i++) {
 
  261          delete inputCubeData[i];
 
  264        for(
unsigned int i = 0; i < outputCubeData.size(); i++) {
 
  265          delete outputCubeData[i];
 
  283      template <
typename Functor>
 
  284      void RunProcess(
const Functor &wrapperFunctor,
 
  285                      int numSteps, 
bool threaded) {
 
  286        ProcessIterator begin(0);
 
  287        ProcessIterator end(numSteps);
 
  292        int threadCount = QThreadPool::globalInstance()->maxThreadCount();
 
  293        if (threaded && threadCount > 1) {
 
  294          QFuture<void> result = QtConcurrent::mapped(begin, end,
 
  296          BlockingReportProgress(result);
 
  299          while (begin != end) {
 
  300            wrapperFunctor(*begin);
 
  322      template <
typename T>
 
  323      class ProcessCubeInPlaceFunctor :
 
  324          public std::unary_function<const int &, void *> {
 
  341          ProcessCubeInPlaceFunctor(Cube *cube,
 
  342                                    const Brick *templateBrick,
 
  343                                    bool readInput, 
bool writeOutput,
 
  344                                    const T &processingFunctor) :
 
  346              m_templateBrick(templateBrick),
 
  347              m_readInput(readInput),
 
  348              m_writeOutput(writeOutput),
 
  349              m_processingFunctor(processingFunctor) {
 
  358          ProcessCubeInPlaceFunctor(
const ProcessCubeInPlaceFunctor &other) :
 
  359              m_cube(other.m_cube),
 
  360              m_templateBrick(other.m_templateBrick),
 
  361              m_readInput(other.m_readInput),
 
  362              m_writeOutput(other.m_writeOutput),
 
  363              m_processingFunctor(other.m_processingFunctor) {
 
  370          virtual ~ProcessCubeInPlaceFunctor() {
 
  372            m_templateBrick = NULL;
 
  382          void *operator()(
const int &brickPosition)
 const {
 
  383            Brick cubeData(*m_templateBrick);
 
  384            cubeData.setpos(brickPosition);
 
  387              m_cube->read(cubeData);
 
  389            m_processingFunctor(cubeData);
 
  392              m_cube->write(cubeData);
 
  405          ProcessCubeInPlaceFunctor &operator=(
 
  406              const ProcessCubeInPlaceFunctor &rhs) {
 
  408            m_templateBrick = rhs.m_templateBrick;
 
  410            m_readInput = rhs.m_readInput;
 
  411            m_writeOutput = rhs.m_writeOutput;
 
  413            m_processingFunctor = rhs.m_processingFunctor;
 
  422          const Brick *m_templateBrick;
 
  429          const T &m_processingFunctor;
 
  446      template <
typename T>
 
  447      class ProcessCubeFunctor :
 
  448          public std::unary_function<const int &, void *> {
 
  465          ProcessCubeFunctor(Cube *inputCube,
 
  466                             const Brick *inputTemplateBrick,
 
  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) {
 
  483          ProcessCubeFunctor(
const ProcessCubeFunctor &other) :
 
  484              m_inputCube(other.m_inputCube),
 
  485              m_inputTemplateBrick(other.m_inputTemplateBrick),
 
  486              m_outputCube(other.m_outputCube),
 
  487              m_outputTemplateBrick(other.m_outputTemplateBrick),
 
  488              m_processingFunctor(other.m_processingFunctor) {
 
  495          virtual ~ProcessCubeFunctor() {
 
  496            m_inputTemplateBrick = NULL;
 
  497            m_outputTemplateBrick = NULL;
 
  507          void *operator()(
const int &brickPosition)
 const {
 
  508            Brick inputCubeData(*m_inputTemplateBrick);
 
  509            Brick outputCubeData(*m_outputTemplateBrick);
 
  511            inputCubeData.setpos(brickPosition);
 
  512            outputCubeData.setpos(brickPosition);
 
  514            m_inputCube->read(inputCubeData);
 
  516            m_processingFunctor(inputCubeData, outputCubeData);
 
  518            m_outputCube->write(outputCubeData);
 
  531          ProcessCubeFunctor &operator=(
const ProcessCubeFunctor &rhs) {
 
  532            m_inputCube = rhs.m_inputCube;
 
  533            m_inputTemplateBrick = rhs.m_inputTemplateBrick;
 
  535            m_outputCube = rhs.m_outputCube;
 
  536            m_outputTemplateBrick = rhs.m_outputTemplateBrick;
 
  538            m_processingFunctor = rhs.m_processingFunctor;
 
  547          const Brick *m_inputTemplateBrick;
 
  552          const Brick *m_outputTemplateBrick;
 
  555          const T &m_processingFunctor;
 
  573      template <
typename T>
 
  574      class ProcessCubesFunctor :
 
  575          public std::unary_function<const int &, void *> {
 
  596          ProcessCubesFunctor(std::vector<Cube *> &inputCubes,
 
  597                              std::vector<Brick *> &inputTemplateBricks,
 
  598                              std::vector<Cube *> &outputCubes,
 
  599                              std::vector<Brick *> &outputTemplateBricks,
 
  601                              const T &processingFunctor) :
 
  602              m_inputCubes(inputCubes),
 
  603              m_inputTemplateBricks(inputTemplateBricks),
 
  604              m_outputCubes(outputCubes),
 
  605              m_outputTemplateBricks(outputTemplateBricks),
 
  607              m_processingFunctor(processingFunctor) {
 
  616          ProcessCubesFunctor(
const ProcessCubesFunctor &other)  :
 
  617              m_inputCubes(other.m_inputCubes),
 
  618              m_inputTemplateBricks(other.m_inputTemplateBricks),
 
  619              m_outputCubes(other.m_outputCubes),
 
  620              m_outputTemplateBricks(other.m_outputTemplateBricks),
 
  621              m_wraps(other.m_wraps),
 
  622              m_processingFunctor(other.m_processingFunctor) {
 
  629          virtual ~ProcessCubesFunctor() {
 
  639          void *operator()(
const int &brickPosition)
 const {
 
  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);
 
  647                inputBrick->setpos(brickPosition % inputBrick->Bricks());
 
  650                inputBrick->setpos(brickPosition);
 
  654                  functorBricks.first.size() &&
 
  655                  inputBrick->Band() != functorBricks.first[0]->Band() &&
 
  656                  m_inputCubes[i]->bandCount() != 1) {
 
  657                inputBrick->SetBaseBand(functorBricks.first[0]->Band());
 
  660              m_inputCubes[i]->read(*inputBrick);
 
  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);
 
  670            m_processingFunctor(functorBricks.first, functorBricks.second);
 
  673            for (
int i = 0; i < (int)functorBricks.second.size(); i++) {
 
  674              m_outputCubes[i]->write(*functorBricks.second[i]);
 
  675              delete functorBricks.second[i];
 
  678            for (
int i = 0; i < (int)functorBricks.first.size(); i++) {
 
  679              delete functorBricks.first[i];
 
  693          ProcessCubesFunctor &operator=(
const ProcessCubesFunctor &rhs) {
 
  694            m_inputCubes = rhs.m_inputCubes;
 
  695            m_inputTemplateBricks = rhs.m_inputTemplateBricks;
 
  697            m_outputCubes = rhs.m_outputCubes;
 
  698            m_outputTemplateBricks = rhs.m_outputTemplateBricks;
 
  700            m_wraps = rhs.m_wraps;
 
  702            m_processingFunctor = rhs.m_processingFunctor;
 
  709          std::vector<Cube *> m_inputCubes;
 
  714          std::vector<Brick *> &m_inputTemplateBricks;
 
  717          std::vector<Cube *> m_outputCubes;
 
  722          std::vector<Brick *> &m_outputTemplateBricks;
 
  728          const T &m_processingFunctor;
 
  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);
 
  751      class ProcessIterator : 
public std::iterator<
 
  752          std::forward_iterator_tag, int> {
 
  754          ProcessIterator(
int position);
 
  755          ProcessIterator(
const ProcessIterator &other);
 
  756          virtual ~ProcessIterator();
 
  758          ProcessIterator &operator++();
 
  766          bool operator==(
const ProcessIterator &rhs) {
 
  767            return (m_currentPosition == rhs.m_currentPosition);
 
  776          bool operator!=(
const ProcessIterator &rhs) {
 
  777            return !(*
this == rhs);
 
  786          void swap(ProcessIterator &other) {
 
  787            std::swap(m_currentPosition, other.m_currentPosition);
 
  797          ProcessIterator &operator=(
const ProcessIterator &rhs) {
 
  798            ProcessIterator copy(rhs);
 
  809            return m_currentPosition;
 
  814          int m_currentPosition;
 
  822      bool p_inputBrickSizeSet;  
 
  824      bool p_outputBrickSizeSet; 
 
  827      int p_outputRequirements;
 
  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;   
 
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:45
 
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:168
 
Buffer for reading and writing cube data.
Definition: Buffer.h:53
 
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
 
IO Handler for Isis Cubes.
Definition: Cube.h:168
 
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
 
Process cubes by brick.
Definition: ProcessByBrick.h:83
 
void SetOutputRequirements(int outputRequirements)
Definition: ProcessByBrick.cpp:95
 
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
 
void Finalize()
Cleans up by closing cubes and freeing memory.
Definition: ProcessByBrick.cpp:749
 
ProcessingDirection
Definition: ProcessByBrick.h:95
 
@ LinesFirst
Definition: ProcessByBrick.h:96
 
@ BandsFirst
Definition: ProcessByBrick.h:97
 
void ProcessCubeInPlace(const Functor &functor, bool threaded=true)
Operate over a single cube (either input or output).
Definition: ProcessByBrick.h:167
 
ProcessByBrick()
Constructs a ProcessByBrick object.
Definition: ProcessByBrick.cpp:16
 
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:243
 
void SetOutputBrickSize(int ns, int nl, int nb)
Sets the size of all output bricks.
Definition: ProcessByBrick.cpp:300
 
void VerifyCubes(IOCubes cn)
Verifies the dimensions of the input/output cubes.
Definition: ProcessByBrick.cpp:120
 
void SetInputBrickSize(int ns, int nl, int nb)
Sets the size of all input bricks.
Definition: ProcessByBrick.cpp:241
 
virtual void StartProcess(void funct(Buffer &in))
Starts the systematic processing of the input cube by moving an arbitrarily-shaped brick through the ...
Definition: ProcessByBrick.cpp:436
 
Cube * SetInputCube(const QString ¶meter, int requirements=0)
Opens an input cube specified by the user and verifies requirements are met.
Definition: ProcessByBrick.cpp:58
 
void ProcessCube(const Functor &functor, bool threaded=true)
Operate over a single input cube creating a separate output cube.
Definition: ProcessByBrick.h:204
 
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
 
void SetWrap(bool wrap)
This wrapping option only applys when there are two or more input cubes.
Definition: ProcessByBrick.cpp:409
 
IOCubes
Definition: ProcessByBrick.h:91
 
@ InputOutput
Definition: ProcessByBrick.h:92
 
@ InputOutputList
Definition: ProcessByBrick.h:93
 
@ InPlace
Definition: ProcessByBrick.h:91
 
bool Wraps()
Returns true if the wrapping option is enabled.
Definition: ProcessByBrick.cpp:419
 
virtual ~ProcessByBrick()
Destroys the ProcessByBrick object.
Definition: ProcessByBrick.cpp:35
 
virtual void SetBricks(IOCubes cn)
Definition: ProcessByBrick.cpp:102
 
void EndProcess()
End the processing sequence and cleans up by closing cubes, freeing memory, etc.
Definition: ProcessByBrick.cpp:739
 
virtual Cube * SetOutputCube(const QString &fname, const CubeAttributeOutput &att)
Create the output file.
Definition: ProcessByBrick.cpp:364
 
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
 
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 ¶meter)
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 ¶meter, 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
 
Angle operator*(double mult, Angle angle)
Multiply this angle by a double and return the resulting angle.
Definition: Angle.cpp:170
 
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:23