#ifndef TRIPLETS_SECTOR_LAYER_H_ #define TRIPLETS_SECTOR_LAYER_H_ /** @file sector-layer.h definition of SectorLayer and helper structures */ #include "data.h" #include "util.h" #include "vec.h" /** an iterator for a double range */ struct range2_iter { /** id of the current range (0 - 1) */ int irange; /** value in the current range */ int val; /** ranges to iterate over */ range ranges[2]; /** constructor */ hostdevice__ range2_iter(int irange, int val, range r1, range r2) { this->irange = irange; this->val = val; this->ranges[0] = r1; this->ranges[1] = r2; } // range2_iter /** increment */ hostdevice__ range2_iter &operator++() { val++; // try going to the next range if(irange == 0 && val == ranges[0].end) { irange = 1; if(!ranges[1].is_empty()) val = ranges[1].start; else val = ranges[1].end; } return *this; } // operator++() hostdevice__ range2_iter operator++(int dummy) { range2_iter res = *this; ++*this; return res; } // operator++(postfix) hostdevice__ int operator*() const { return val; } }; // range2_iter // compare 2 range iterators for equality/inequality hostdevice__ inline bool operator==(const range2_iter &i1, const range2_iter &i2) { return i1.irange == i2.irange && i1.val == i2.val; } // operator== hostdevice__ inline bool operator!=(const range2_iter &i1, const range2_iter &i2) { return i1.irange != i2.irange || i1.val != i2.val; } // operator!= /** 2 ranges of tubes resulting from intersection of sector-layer with a ring; sub-ranges do not intersect */ struct range2 { inline hostdevice__ range2() {} inline hostdevice__ range2(range r1, range r2 = range::empty()) { ranges[0] = r1; ranges[1] = r2; } static hostdevice__ range2 empty(void) { return range2(range::empty(), range::empty()); } /** checks whether the double-range is empty */ hostdevice__ bool is_empty(void) const { return ranges[0].is_empty() && ranges[1].is_empty(); } /** begin iterator */ hostdevice__ range2_iter begin() const { int irange = 1, val = ranges[1].end; if(!ranges[0].is_empty()) { irange = 0; val = ranges[0].start; } else if(!ranges[1].is_empty()) { irange = 1; val = ranges[1].start; } return range2_iter(irange, val, ranges[0], ranges[1]); } // begin /** end iterator */ hostdevice__ range2_iter end() const { return range2_iter(1, ranges[1].end, ranges[0], ranges[1]); } // end /** the ranges */ range ranges[2]; }; // range2 /** a single sector-layer (sector-row) of tubes, numbered contiguously and sharing the same line */ struct SectorLayer { // /** default empty constructor for a sector-layer; required to be used with // constant memory */ // hostdevice__ SectorLayer() {} // /** creates a new sector-layer and initializes it with default values */ // hostdevice__ SectorLayer(bool dummy) : p0(0), k(0), straws(range::empty()), // is_skewed(false) {} // /** creates a new sector-layer with parameters */ // hostdevice__ SectorLayer // (int row, int sector, fvec2 p0, fvec2 k, range straws, bool is_skewed); /** a helper function to create a sector-layer from a range of straws */ static SectorLayer from_tubes(layptr tubes, range straws); /** a helper function to create a sector-layer for skewlet bins */ static SectorLayer from_skewlet_bins (const SectorLayer *sls1, int stride, layptr tubes, range bins); /** computes an intersection of a sector-layer with a track ring @param center_dist distance between centers of neighboring bins/tubes @param inv_center_dist inverted center_dist, to accelerate some computations @param max_dist maximum distance from the center of the cell to the track, i.e. the distance by which the track is "thickened"; alternatively, the radius of the tube @param center the center of the track @param radius the radius of the track */ hostdevice__ range2 intersect_ring (float center_dist, float inv_center_dist, float max_dist, fvec2 center, float radius) const; /** version of intersect_ring for testing against tubes with hits */ hostdevice__ range2 intersect_ring_tubes(fvec2 center, float radius) const; /** version of intersect_ring for testing against bins of skewlets */ hostdevice__ range2 intersect_ring_skewlets(fvec2 center, float radius) const; /** gets the bin for the 2d position, normally used to bin skewlets; note that the bin starts from the start of layer's range, and the number is thus "global" */ hostdevice__ int point_bin(fvec2 pos) const; /** row of the sector-layer */ //int row; /** sector of the sector-layer */ //int sector; /** position of the first (#0) tube/bin */ fvec2 p0; /** vector from the first to the second tube (line vector), normalized */ fvec2 k; /** normal vector to the line */ //fvec2 n; /** range of straws or bins */ range straws; /** whether the sector-layer is skewed; set true for layers representing skewlet bins */ bool is_skewed; }; // struct SectorLayer #endif