1 from __future__
import absolute_import, division, print_function
2 from builtins
import object
11 """Class to support bright object masks 13 N.b. I/O is done by providing a readFits method which fools the butler. 17 schema = afwTable.SimpleTable.makeMinimalSchema()
18 schema.addField(
"type", str,
"type of region (e.g. box, circle)", size=10)
19 schema.addField(
"radius",
"Angle",
"radius of mask (if type == circle")
20 schema.addField(
"height",
"Angle",
"height of mask (if type == box)")
21 schema.addField(
"width",
"Angle",
"width of mask (if type == box)")
22 schema.addField(
"angle",
"Angle",
"rotation of mask (if type == box)")
23 schema.addField(
"mag", float,
"object's magnitude")
25 self.
_catalog = afwTable.SimpleCatalog(schema)
26 self.
_catalog.table.setMetadata(dafBase.PropertyList())
45 """Read a ds9 region file, returning a ObjectMaskCatalog object 47 This method is called "readFits" to fool the butler. The corresponding mapper entry looks like 49 template: "deepCoadd/BrightObjectMasks/%(tract)d/BrightObjectMask-%(tract)d-%(patch)s-%(filter)s.reg" 50 python: "lsst.obs.subaru.objectMasks.ObjectMaskCatalog" 51 persistable: "PurePythonClass" 52 storage: "FitsCatalogStorage" 54 and this is the only way I know to get it to read a random file type, in this case a ds9 region file. 56 This method expects to find files named as BrightObjectMask-%(tract)d-%(patch)s-%(filter)s.reg 57 The files should be structured as follows: 59 # Description of catalogue as a comment 60 # CATALOG: catalog-id-string 67 circle(RA, DEC, RADIUS) # ID: 1, mag: 12.34 68 box(RA, DEC, XSIZE, YSIZE, THETA) # ID: 2, mag: 23.45 71 The ", mag: XX.YY" is optional 73 The commented lines must be present, with the relevant fields such as tract patch and filter filled 74 in. The coordinate system must be listed as above. Each patch is specified as a box or circle, with 75 RA, DEC, and dimensions specified in decimal degrees (with or without an explicit "d"). 77 Only (axis-aligned) boxes and circles are currently supported as region definitions. 80 log = Log.getLogger(
"ObjectMaskCatalog")
83 checkedWcsIsFk5 =
False 84 NaN = float(
"NaN")*afwGeom.degrees
87 with open(fileName)
as fd:
88 for lineNo, line
in enumerate(fd.readlines(), 1):
91 if re.search(
r"^\s*#", line):
100 mat = re.search(
r"^\s*#\s*([a-zA-Z][a-zA-Z0-9_]+)\s*:\s*(.*)", line)
102 key, value = mat.group(1).lower(), mat.group(2)
106 brightObjects.table.getMetadata().set(key, value)
108 line = re.sub(
r"^\s*#.*",
"", line)
112 if re.search(
r"^\s*wcs\s*;\s*fk5\s*$", line, re.IGNORECASE):
113 checkedWcsIsFk5 =
True 118 mat = re.search(
r"^\s*(box|circle)" 120 "(\d+(?:\.\d*)?([d]*))" "(?:\s+|\s*,\s*)" 121 "([+-]?\d+(?:\.\d*)?)([d]*)" "(?:\s+|\s*,\s*)" 122 "([+-]?\d+(?:\.\d*)?)([d]*)" "(?:\s+|\s*,\s*)?" 123 "(?:([+-]?\d+(?:\.\d*)?)([d]*)" 125 "([+-]?\d+(?:\.\d*)?)([d]*)" 129 "(?:\s*,\s*mag:\s*(\d+\.\d*))?" 132 _type, ra, raUnit, dec, decUnit, \
133 param1, param1Unit, param2, param2Unit, param3, param3Unit, \
134 _id, mag = mat.groups()
151 width =
convertToAngle(param1, param1Unit,
"width", fileName, lineNo)
152 height =
convertToAngle(param2, param2Unit,
"height", fileName, lineNo)
153 angle =
convertToAngle(param3, param3Unit,
"angle", fileName, lineNo)
156 log.warn(
"Rotated boxes are not supported: \"%s\" at %s:%d" % (
157 line, fileName, lineNo))
159 elif _type ==
"circle":
160 radius =
convertToAngle(param1, param1Unit,
"radius", fileName, lineNo)
162 if not (param2
is None and param3
is None):
163 log.warn(
"Extra parameters for circle: \"%s\" at %s:%d" % (
164 line, fileName, lineNo))
167 rec = brightObjects.addNew()
172 rec.setCoord(afwGeom.SpherePoint(ra, dec))
175 rec[
"height"] = height
177 rec[
"radius"] = radius
179 log.warn(
"Unexpected line \"%s\" at %s:%d" % (line, fileName, lineNo))
183 raise RuntimeError(
"Saw %d formatting errors in %s" % (nFormatError, fileName))
185 if not checkedWcsIsFk5:
186 raise RuntimeError(
"Expected to see a line specifying an fk5 wcs in %s" % fileName)
189 brightObjects._catalog = brightObjects._catalog.copy(
True)
195 """Given a variable and its units, return an afwGeom.Angle 197 what, fileName, and lineNo are used to generate helpful error messages 201 if varUnit
in (
"d",
"",
None):
208 raise RuntimeError(
"unsupported unit \"%s\" for %s at %s:%d" %
209 (varUnit, what, fileName, lineNo))
211 return var*afwGeom.degrees
def convertToAngle(var, varUnit, what, fileName, lineNo)
def readFits(fileName, hdu=0, flags=0)
def __setitem__(self, i, v)