def get_time(self): time = plane.Time() lower = 1.0 upper = 2.0 lower1 = 1.1 upper1 = 2.1 lower2 = 1.2 upper2 = 2.2 samples = [ shape.SubInterval(lower, lower1), shape.SubInterval(lower2, upper), shape.SubInterval(upper1, upper2) ] interval = shape.Interval(lower, upper2, samples) time.bounds = interval if self.caom_version >= 24: time.resolution_bounds = shape.Interval(22.2, 33.3) time.dimension = 1 time.resolution = 2.1 time.sample_size = 3.0 time.exposure = 10.3 return time
def get_energy(self): energy = plane.Energy() lower = 1.0 upper = 2.0 lower1 = 1.1 upper1 = 2.1 lower2 = 1.2 upper2 = 2.2 samples = [ shape.SubInterval(lower, lower1), shape.SubInterval(lower2, upper), shape.SubInterval(upper1, upper2) ] interval = shape.Interval(lower, upper2, samples) energy.bounds = interval energy.dimension = 100 energy.resolving_power = 2.0 energy.sample_size = 1.1 energy.bandpass_name = "e" if self.caom_version >= 24: energy.energy_bands.add(plane.EnergyBand.GAMMARAY) energy.energy_bands.add(plane.EnergyBand.OPTICAL) energy.transition = wcs.EnergyTransition("species", "transition") return energy
def get_poly_position(self): position = plane.Position() if self.caom_version >= 23: v0 = shape.Vertex(0.0, 0.0, shape.SegmentType.MOVE) v1 = shape.Vertex(3.0, 4.0, shape.SegmentType.LINE) v2 = shape.Vertex(2.0, 3.0, shape.SegmentType.LINE) v3 = shape.Vertex(1.0, 2.0, shape.SegmentType.LINE) v4 = shape.Vertex(0.0, 0.0, shape.SegmentType.CLOSE) vl = [v0, v1, v2, v3, v4] samples = shape.MultiPolygon(vertices=vl) p1 = shape.Point(0.0, 0.0) p2 = shape.Point(3.0, 4.0) p3 = shape.Point(2.0, 3.0) p4 = shape.Point(1.0, 2.0) p = [p1, p2, p3, p4] polygon = shape.Polygon(points=p, samples=samples) position.bounds = polygon position.dimension = wcs.Dimension2D(10, 20) position.resolution = 0.5 position.sample_size = 1.1 position.time_dependent = False if self.caom_version >= 24: position.resolution_bounds = shape.Interval(1.0, 2.0) return position
def _get_num_pixels(axis, use_func): """ Count the number of pixels :param axis: A CoordAxis1D :param use_func: A boolean :return: A float """ range = axis.range bounds = axis.bounds function = axis.function if range is not None: return abs(range.end.pix - range.start.pix) if bounds is not None: # Count number of distinct bins bins = [] for cr in bounds.samples: si = shape.Interval(cr.start.pix, cr.end.pix) CustomAxisUtil._merge_into_list(si, bins, float(0.0)) ret = float(0.0) for si in bins: ret += abs(si.upper - si.lower) return ret if use_func and function is not None: return function.naxis return float(0.0)
def get_circle_position(self): position = plane.Position() position.bounds = shape.Circle(shape.Point(1.1, 2.2), 3.0) position.dimension = wcs.Dimension2D(10, 20) position.resolution = 0.5 position.sample_size = 1.1 position.time_dependent = False if self.caom_version >= 24: position.resolution_bounds = shape.Interval(1.0, 2.0) return position
def _merge_into_list(si, samples, union_scale): """Merge an Interval into a list of Intervals :param si An Interval :param samples A list of Intervals :param union_scale A float """ snew = si if len(samples) > 0: f = union_scale * (si.upper - si.lower) a = si.lower - f b = si.upper + f tmp = [] # Find intervals that overlap the new one, move from samples -> tmp for sample in samples: f = union_scale * (sample.upper - sample.lower) c = sample.lower - f d = sample.upper + f # [a,b] U [c,d] if b >= c and d >= a: # there is overlap tmp.append(sample) samples.pop(0) # Merge all overlapping sub-intervals # compute the outer bounds of the sub-intervals if len(tmp) > 0: lb = si.lower ub = si.upper for s in tmp: if lb > s.lower: lb = s.lower if ub < s.upper: ub = s.upper snew = shape.Interval(lb, ub) # Insert new sub to preserve order added = False for i in range(len(samples)): sample = samples[i] if snew.lower < sample.lower: samples.insert(i, snew) added = True break if not added: samples.append(snew)
def range1d_to_interval(wcs, r): """ range1d_to_interval calculates interval for CoordRange1D :param wcs A CustomWCS :param r A CoordRange1D :return An Interval """ CustomAxisUtil.validate_wcs(wcs) np = abs(r.start.pix - r.end.pix) a = r.start.val b = r.end.val delta = abs(b - a) if delta == 0.0 and np > 1.0: raise ValueError( "Invalid CoordRange1D: found {} + pixels and delta = 0.0 in \ [{},{}]".format(np, a, b)) return shape.Interval(min(a, b), max(a, b))
def function1d_to_interval(wcs, func): """ function1d_to_interval calculates interval for CoordFunction1D :param wcs A CustomWCS :param r A CoordFunction1D :return An Interval """ CustomAxisUtil.validate_wcs(wcs) if func.delta == 0.0 and func.naxis > 1: raise ValueError( "Invalid CoordFunction1D: found {} pixels and delta = 0.0". format(func.naxis)) p1 = 0.5 p2 = float(func.naxis) + 0.5 a = CustomAxisUtil.val2pix(wcs, func, p1) b = CustomAxisUtil.val2pix(wcs, func, p2) return shape.Interval(min(a, b), max(a, b))
def get_custom(self): custom = plane.CustomAxis('MyAxis') custom.bounds = shape.Interval(2.2, 3.3) custom.dimension = 1
def compute_bounds(artifacts, product_type, expected_ctype): """ Compute bounds. :param artifacts List of Artifacts :param product_type A Product_type :param expected_ctype Expected CTYPE :return An Interval """ union_scale = float(0.02) subs = [] for a in artifacts: for p_key in a.parts: p = a.parts[p_key] for c in p.chunks: if c is not None and c.custom is not None and \ CustomAxisUtil._use_chunk( a.product_type, p.product_type, c.product_type, product_type): current_ctype = c.custom.axis.axis.ctype if current_ctype is None or \ current_ctype != expected_ctype: raise ValueError( "CTYPE must be the same across all Artifacts. \ Found: {}. Expected: {}".format( current_ctype, expected_ctype)) else: range = c.custom.axis.range bounds = c.custom.axis.bounds function = c.custom.axis.function if range is not None: s = CustomAxisUtil.range1d_to_interval( c.custom, range) logger.debug( "[compute_bounds] range -> sub: {}".format( s)) CustomAxisUtil._merge_into_list( s, subs, union_scale) elif bounds is not None: for cr in bounds.samples: s = CustomAxisUtil.range1d_to_interval( c.custom, cr) logger.debug( "[compute_bounds] bounds -> sub: {}". format(s)) CustomAxisUtil._merge_into_list( s, subs, union_scale) elif function is not None: s = CustomAxisUtil.function1d_to_interval( c.custom, function) logger.debug( "[compute_bounds] function -> sub: {}". format(s)) CustomAxisUtil._merge_into_list( s, subs, union_scale) if len(subs) == 0: return None # Compute the outer bounds of the sub intervals lb = sys.float_info.max ub = sys.float_info.min for sub in subs: lb = min(lb, sub.lower) ub = max(ub, sub.upper) return shape.Interval(lb, ub, subs)