#!/usr/bin/env python3 # -*- coding: utf-8- # # Split the strip-shaped CCD gaps regions into a series of small # square regions, which are used as the input regions of 'roi' to # determine the corresponding background regions, and finally providied # to 'dmfilth' in order to fill in the CCD gaps. # # Aaron LI # 2015/08/12 # # Changelogs: # v0.1.0, 2015/08/12 # * initial version # __version__ = "0.1.0" __date__ = "2015/08/12" import os import sys import re import math import argparse from io import TextIOWrapper ## BoxRegion {{{ class BoxRegion(object): """ CIAO/DS9 "rotbox"/"box" region class. rotbox/box format: rotbox(xc, yc, width, height, rotation) box(xc, yc, width, height, rotation) Notes: rotation: [0, 360) (degree) """ def __init__(self, xc=None, yc=None, width=None, height=None, rotation=None): self.regtype = "rotbox" self.xc = xc self.yc = yc self.width = width self.height = height self.rotation = rotation def __str__(self): return "%s(%s,%s,%s,%s,%s)" % (self.regtype, self.xc, self.yc, self.width, self.height, self.rotation) @classmethod def parse(cls, regstr): """ Parse region string. """ regex_box = re.compile(r'^\s*(box|rotbox)\(([0-9. ]+),([0-9. ]+),([0-9. ]+),([0-9. ]+),([0-9. ]+)\)\s*$', re.I) m = regex_box.match(regstr) if m: regtype = m.group(1) xc = float(m.group(2)) yc = float(m.group(3)) width = float(m.group(4)) height = float(m.group(5)) rotation = float(m.group(6)) return cls(xc, yc, width, height, rotation) else: return None def split(self, filename=None): """ Split strip-shaped box region into a series small square regions. """ angle = self.rotation * math.pi / 180.0 # to record the center coordinates of each split region centers = [] if self.width > self.height: # number of regions after split nreg = math.ceil(self.width / self.height) # width & height of the split region width = self.width / nreg height = self.height # position of the left-most region x_l = self.xc - 0.5*self.width * math.cos(angle) y_l = self.yc - 0.5*self.width * math.sin(angle) for i in range(nreg): x = x_l + (0.5 + i) * width * math.cos(angle) y = y_l + (0.5 + i) * width * math.sin(angle) centers.append((x, y)) else: # number of regions after split nreg = math.ceil(self.height / self.width) # width & height of the split region width = self.width height = self.height / nreg # position of the left-most region x_l = self.xc + 0.5*self.height * math.cos(angle + math.pi/2) y_l = self.yc + 0.5*self.height * math.sin(angle + math.pi/2) for i in range(nreg): x = x_l - (0.5 + i) * height * math.cos(angle + math.pi/2) y = y_l - (0.5 + i) * height * math.sin(angle + math.pi/2) centers.append((x, y)) # create split regions regions = [] for (x, y) in centers: regions.append(self.__class__(x, y, width+2, height+2, self.rotation)) # write split regions into file if specified if isinstance(filename, str): regout = open(filename, "w") regout.write("\n".join(map(str, regions))) regout.close() else: return regions ## BoxRegion }}} def main(): # command line arguments parser = argparse.ArgumentParser( description="Split strip-shaped rotbox region into " + \ "a series of small square regions.", epilog="Version: %s (%s)" % (__version__, __date__)) parser.add_argument("-V", "--version", action="version", version="%(prog)s " + "%s (%s)" % (__version__, __date__)) parser.add_argument("infile", help="input rotbox region file") parser.add_argument("outfile", help="output file of the split regions") args = parser.parse_args() outfile = open(args.outfile, "w") regex_box = re.compile(r'^\s*(box|rotbox)\([0-9., ]+\)\s*$', re.I) for line in open(args.infile, "r"): if regex_box.match(line): reg = BoxRegion.parse(line) split_regs = reg.split() outfile.write("\n".join(map(str, split_regs)) + "\n") else: outfile.write(line) outfile.close() if __name__ == "__main__": main()