Line data Source code
1 : #pragma once 2 : 3 : #include "BlockDescriptor.h" 4 : #include "VolumeDescriptor.h" 5 : 6 : namespace elsa 7 : { 8 : /** 9 : * @brief Class representing a descriptor obtained after the partition of a normal data 10 : * descriptor into blocks. 11 : * 12 : * @author Nikola Dinev 13 : * 14 : * A single block of the PartitionDescriptor represents a linear segment containing one or more 15 : * slices of the original descriptor, taken along its last dimension. This also means that the 16 : * number of coefficients per block can only vary in the last dimension. 17 : * 18 : * The PartitionDescriptor has the same dimension, the same number of coefficients and spacing 19 : * per dimension as the original. 20 : */ 21 : class PartitionDescriptor : public BlockDescriptor 22 : { 23 : public: 24 : /** 25 : * @brief Construct a PartitionDescriptor by partitioning a given descriptor into blocks of 26 : * fairly equal sizes 27 : * 28 : * @param[in] dataDescriptor the descriptor to be partitioned 29 : * @param[in] numberOfBlocks the number of blocks 30 : * 31 : * @throw InvalidArgumentError if numberOfBlocks is less than 2 or greater than the number 32 : * of coefficients in the last dimension 33 : * 34 : * If the given descriptor has a size of \f$ N \f$ in its last dimension, when dividing it 35 : * into \f$ m \f$ blocks and \f$ N \f$ is not evenly divisible by \f$ m \f$, the last \f$ N 36 : * \bmod m \f$ blocks will have a size of the last dimension one bigger than that of the 37 : * others. 38 : * 39 : * Note: if the passed in DataDescriptor is a block descriptor, the block information 40 : * is ignored when generating the new PartitionDescriptor. 41 : */ 42 : PartitionDescriptor(const DataDescriptor& dataDescriptor, index_t numberOfBlocks); 43 : 44 : /** 45 : * @brief Construct a PartitionDescriptor by specifying the number of slices contained in 46 : * each block 47 : * 48 : * @param[in] dataDescriptor the descriptor to be partitioned 49 : * @param[in] slicesInBlock the number of slices in each block 50 : * 51 : * @throw InvalidArgumentError if slicesInBlock does not specify a valid partition scheme 52 : * for the given descriptor 53 : * 54 : * Note: if the passed in DataDescriptor is a block descriptor, the block information 55 : * is ignored when generating the new PartitionDescriptor. 56 : */ 57 : PartitionDescriptor(const DataDescriptor& dataDescriptor, IndexVector_t slicesInBlock); 58 : 59 : /// default destructor 60 72284 : ~PartitionDescriptor() override = default; 61 : 62 : /// return the number of blocks 63 : index_t getNumberOfBlocks() const override; 64 : 65 : /// return the DataDescriptor of the i-th block 66 : const DataDescriptor& getDescriptorOfBlock(index_t i) const override; 67 : 68 : /// return the offset to access the data of the i-th block 69 : index_t getOffsetOfBlock(index_t i) const override; 70 : 71 : protected: 72 : /// maps a block index to the index of the corresponding descriptor in _blockDescriptors 73 : IndexVector_t _indexMap; 74 : 75 : /// vector of unique DataDescriptors describing the individual blocks 76 : std::vector<std::unique_ptr<DataDescriptor>> _blockDescriptors; 77 : 78 : /// vector of the individual block data offsets 79 : IndexVector_t _blockOffsets; 80 : 81 : /// protected copy constructor; used for cloning 82 : PartitionDescriptor(const PartitionDescriptor& other); 83 : 84 : /// implement the polymorphic clone operation 85 : PartitionDescriptor* cloneImpl() const override; 86 : 87 : /// implement the polymorphic comparison operation 88 : bool isEqual(const DataDescriptor& other) const override; 89 : 90 : private: 91 : /// generates the descriptor of a partition containing numberOfSlices slices 92 : std::unique_ptr<VolumeDescriptor> 93 : generateDescriptorOfPartition(index_t numberOfSlices) const; 94 : }; 95 : } // namespace elsa